Style Board Game Cards with Tailwind CSS

In the previous lessons, we created the Board Games section and then imported our favorite board games using the FeedMe plugin. So far we’ve only worked in the Craft admin panel, that changes today when we update the homepage Twig template to display our board games & style it with Tailwind CSS.

Mockup of Board Games row #

Here’s a screenshot of a board game row displaying 3 cards.

💡 Check it out on the Tailwind Play playground.

Update Homepage to list board game titles #

Before setting up Tailwind, let’s get familiar with updating the homepage. We’ll modify the default index.twig template to list our board game titles.

  1. Open templates/index.twig in your favorite code editor.1
  2. Scroll down until you find the H2 with “Popular Resources” and replace it with “Favorite Board Games”.
  3. We’re going to grab ALL or our board game data and put into a variable boardgames. Copy & paste the snippet below, put it right above the H2.
{% set boardgames = craft.entries.section('boardGames').all() %}
  1. Replace all the <li> rows with the following.
{% for boardgame in boardgames %}
      {% set image = boardgame.boardGameImage.one() %}
      
  • {{boardgame.title }}
    {{ boardgame.boardGameCategory.one()}}
  • {% endfor %}
    💡 You can look up the field handles in Settings> Fields.

    Visit the homepage and you’ll see a list of board games like this:

    https://cdn.eaglepeakweb.com/img/projects/blog/First-board-game-created.jpg

    So we’re looping through each individual boardgame and

    • Displaying the Title
    • Linking the Title to the board game’s cover image
    • Displaying the Category below the Title

    Notice that Twig has 2 types of curly braces.

    1. {{ }} print this

    2. {% %} do this like set a variable, start a loop or check a condition

    Also notice the .one() method for the image & category. Since a board game could have multiple images or categories, we only want the first value.

    Simple Tailwind CSS Setup #

    You could easily spend half a day setting up a front-end build chain with Gulp, webpack, etc. So our setup is deliberately “simple” 🤔 to get us going.2

    Node.js #

    You’ll need to have Node.js installed locally. So go to the Node.js homepage & download the LTS version for your OS.

    Lando - con­fig­ure fron­t-end tool­ing #

    If you’re using Lando for local development, then you can add front-end tooling by updating .lando.yml

    name: boardgames
    recipe: lamp
    config:
      webroot: web
      php: '7.4'
      database: mariadb:10.3
    services:
      database:
        type: mariadb:10.3
        portforward: 3310
        creds:
          user: homestead
          password: secret
          database: boardgames
      node:
        type: node
        build:
          - npm install tailwindcss
          - npm install laravel-mix
    tooling:
      npm:
        service: node
      npx:
        service: node
      node:
        service: node
    

    We’ve added Node.js in a new container to our project. And we’re also installing the tailwindcss & laravel-mix packages.

    You’ll then rebuild your Lando containers. lando rebuild

    alexagui@alexMBP ~/Code/craft/boardgames (develop/tailwind-homepage) $ lando rebuild
    ? Are you sure you want to rebuild? (y/N)Yes
    Rising anew like a fire phoenix from the ashes! Rebuilding app...
    Killing boardgames_appserver_1 ... done
    Killing boardgames_database_1  ... done
    Going to remove boardgames_appserver_1, boardgames_database_1
    Removing boardgames_appserver_1 ... done
    Removing boardgames_database_1  ... done
    Pulling appserver ... extracting (0.3%)
    Pulling node      ... downloading (55.6%)
    Pulling database  ... done
    

    Install Tailwind #

    💡 If you’re not using Lando then just omit lando from the commands below .
    1. lando npm init -y
      This will create a package.json file in your project root.
    2. lando npx tailwindcss init
      alexagui@alexMBP ~/Code/craft/boardgames (develop/tailwind-homepage) $ lando npx tailwindcss init
      tailwindcss 1.9.5
      :white_check_mark: Created Tailwind config file: tailwind.config.js
      
    3. We’re going to use Laravel Mix to compile our CSS. If you’re using Lando then it should already be installed when we updated .lando.yml above & rebuilt the containers. If you’re not using Lando then you need to install Laravel Mix npm install laravel-mix

    4. Next we setup our source CSS file. Let’s create it under a new folder source/css/app.css
      mkdir -p source/css && touch $_/app.css

    5. Put the following inside app.css

      @tailwind base;
      @tailwind components;
      @tailwind utilities;
      
    6. Next, in the project root, we create a webpack.mix.js and put the following in it.

      const mix = require('laravel-mix');
      const tailwindcss = require('tailwindcss');
      mix.postCss('source/css/app.css', 'web/css/app.css', [ tailwindcss('tailwind.config.js') ]);```
      
      
    7. Modify package.json by replacing the “scripts” section with this:

      "scripts": {
       "dev": "npm run development",
       "development": "NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
       "watch": "npm run development -- --watch",
       "watch-poll": "npm run watch -- --watch-poll",
       "hot": "NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
       "prod": "npm run production",
       "production": "NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
      },
      
    8. Build the CSS by running lando npm run dev

    $ lando npm run dev
    > [email protected] dev /app  
    npm run development
    > [email protected] development /app
    > NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js
    ...
    🛫 lots of stuff flying by 🛬
    ...
    DONE  Compiled successfully in 11408ms          9:03:32 PM
    
    Asse                Size        Chunks              Chunk Names
    web/css/app.css     2.31 MiB    mix  [emitted]      mix
    

    Notice that our CSS file has been built at web/css/app.css

    Update Homepage to display styled cards #

    Replace default styling #

    1. Open templates/index.twig.
    2. Between the last <meta> tag and before the <style> tag add:

      <link rel="stylesheet" href="/css/app.css"/>
      
    3. Remove all of the <style> section.

    4. Replace the contents of the <body> tags with:

    Eek! That’s a lot of code and verbosity is a complaint about Tailwind CSS. But I’ve found that its utility-first approach makes it fairly easy for a front-end challenged developer like myself to build decent looking pages.

    If you refresh the page you’ll see just one card being displayed on the homepage.

    We just hard-coded a sample card to ensure Tailwind CSS is configured correctly. Now let’s update so the cards are served dynamically.

    Dynamically display board game cards #

    1. Once again let’s grab all the board game data. Put the following snippet at very top of the templates/index.twig template.
    2. Next we’ll start our loop. Look for this DIV
      <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
      

      and right below it add:

      {% for boardgame in boardgames %}
        {% set image = boardgame.boardGameImage.one() %}
        {% set category = boardgame.boardGameCategory.one() %}
      

      Don’t forget to close the loop.

       {% endfor %}
      </div>
      

      Take a quick peek at the homepage and it should look like this:

    3. Let’s update the template with the appropriate board game Craft field handles. Below is the fully updated code.

    ☝️ Note that we check if the playOnline field is present before displaying a Play online link.

    Refresh the homepage and it should look similar to:

    Wrapping Up #

    In this lesson, we updated the homepage to display board games cards & styled them with Tailwind CSS. But the approach we took of 1 HUGE template isn’t best practice. Ideally, we should have a layout template and the cards should be an include file. You want to keep code in smaller more manageable pieces instead of huge blobs.

    It also bugs me that there’s no margin between the cards and edge of browser window. And that the category & difficulty all have the same color. I’d like the difficulties to display in appropriate colors ex: Easy and Hard.

    In the next lesson, we’ll refactor our template & polish up these styling issues.

    This series is in development. Sign up or follow me @AlexAguilar18 to learn when new lessons are released.

    1. Like the excellent Visual Studio Code, a free cross-platform editor by Microsoft of all people.

    2. Thanks to @ademers gist on setting up Tailwind CSS in Craft CMS 3.


    Alex Aguilar

    Partner, Software Engineer