Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Soaring with utility-first CSS and Tailwind

Soaring with utility-first CSS and Tailwind

Workshop for Florida DrupalCamp.

71c9ebde850996d2533c5df4df2c93c6?s=128

Oliver Davies

February 18, 2021
Tweet

Transcript

  1. Soaring with utility-first CSS and Tailwind Oliver Davies (@opdavies)

  2. Prerequisites • Git • PHP • Composer • npm/yarn @opdavies

  3. Before we start git clone https://github.com/opdavies/workshop-tailwind-css.git cd workshop-tailwind-css composer install

    php -S 127.0.0.1:8000 -t public @opdavies
  4. @opdavies

  5. What is Tailwind CSS? @opdavies

  6. A utility-first CSS framework for rapidly building custom designs @opdavies

  7. Tailwind CSS is a highly customisable, low-level CSS framework @opdavies

  8. Tailwind is more than a CSS framework, it's an engine

    for creating design systems @opdavies
  9. • Text/border/background colours • Font size/family/weight • Alignment • Padding/margin/negative

    margin • Flexbox • Positioning • Lists • z-index • Opacity @opdavies
  10. • Screenreader visibility • Placeholder colour • first-child, last-child, nth-child

    • CSS Grid • Transition • Transform • Spacing / Divide • Focus ring • Text clamping @opdavies
  11. @opdavies

  12. @opdavies

  13. @opdavies

  14. Task 1: Adding Tailwind CSS @opdavies

  15. # Add Tailwind, PostCSS, Autoprefixer, PostCSS CLI yarn add cross-env

    \ tailwindcss@latest \ postcss@latest \ autoprefixer@latest \ postcss-cli # Generate Tailwind and PostCSS configuration files npx tailwindcss init -p @opdavies
  16. Create the source file: /* assets/css/tailwind.pcss */ @tailwind base; @tailwind

    components; @tailwind utilities; @opdavies
  17. Add to package.json: "scripts": { "dev": "cross-env NODE_ENV=development postcss assets/css/tailwind.pcss

    -o public/build/tailwind.css", "prod": "cross-env NODE_ENV=production postcss assets/css/tailwind.pcss -o public/build/tailwind.css", "watch": "cross-env NODE_ENV=development postcss assets/css/tailwind.pcss -o public/build/tailwind.css --watch" } Add to templates/html.html.twig: <link rel="stylesheet" href="/build/tailwind.css"/> @opdavies
  18. @opdavies

  19. Task 2: Add text styling @opdavies

  20. Before we start git add -A git commit -m 'Save

    progress' git checkout -b local/2-text-styling origin/task/1-add-tailwind-css @opdavies
  21. Adding intro text <!-- templates/pages/home.html.twig --> <div> <p>Florida DrupalCamp is

    an annual conference that brings together web developers from all over the world to learn, network and discuss web development and the Drupal content management system.</p> <a>Learn more</a> </div> @opdavies
  22. @opdavies

  23. <!-- templates/pages/home.html.twig --> <div class="max-w-2xl px-4 py-8 mx-auto text-center"> <p>Florida

    DrupalCamp is an annual conference that brings together web developers from all over the world to learn, network and discuss web development and the Drupal content management system.</p> <a>Learn more</a> </div> @opdavies
  24. @opdavies

  25. <!-- templates/pages/home.html.twig --> <div class="max-w-2xl px-4 py-8 mx-auto text-center"> <p

    class="text-2xl leading-loose text-blue-700"> Florida DrupalCamp is an annual conference that brings together web developers from all over the world to learn, network and discuss web development and the Drupal content management system.</p> <a>Learn more</a> </div> @opdavies
  26. <!-- templates/pages/home.html.twig --> <div class="max-w-2xl px-4 py-8 mx-auto text-center"> <p

    class="text-2xl leading-loose text-blue-700"> Florida DrupalCamp is an annual conference that brings together web developers from all over the world to learn, network and discuss web development and the Drupal content management system.</p> <a class="inline-block px-5 py-4 mt-8 text-2xl text-blue-700 transition-colors duration-200 ease-in-out border-2 border-blue-700 hover:bg-blue-700 focus:bg-blue-700 hover:text-white focus:text-white" href="#0">Learn more</a> </div> @opdavies
  27. @opdavies

  28. Task 3: Add a navbar component @opdavies

  29. Before we start git add -A git commit -m 'Save

    progress' git checkout -b local/3-navbar origin/task/2-intro-text @opdavies
  30. <!-- templates/pages/home.html.twig --> <div> <div> <div> <a href="#0"> <img src="https://www.fldrupal.camp/sites/all/themes/fldc17/images/header-logo-general.svg">

    </a> </div> <div> <ul> <li><a href="#0">Conference</a></li> <li><a href="#0">Sponsors</a></li> <li><a href="#0">Community</a></li> <li><a href="#0">FAQ</a></li> <li><a href="#0">Register</a></li> </ul> </div> </div> </div> @opdavies
  31. @opdavies

  32. <!-- templates/pages/home.html.twig --> <div class="sticky top-0 z-30 px-4 mx-auto bg-white

    max-w-screen-2xl"> <div class="grid grid-cols-2 gap-4"> <div> <a href="#0"> <img src="https://www.fldrupal.camp/sites/all/themes/fldc17/images/header-logo-general.svg"> </a> </div> <div> <ul> <li><a href="#0">Conference</a></li> <li><a href="#0">Sponsors</a></li> <li><a href="#0">Community</a></li> <li><a href="#0">FAQ</a></li> <li><a href="#0">Register</a></li> </ul> </div> </div> </div> @opdavies
  33. @opdavies

  34. <!-- templates/pages/home.html.twig --> <div class="sticky top-0 z-30 px-4 mx-auto bg-white

    max-w-screen-2xl"> <div class="grid grid-cols-2 gap-4"> <div> <a href="#0"> <img src="https://www.fldrupal.camp/sites/all/themes/fldc17/images/header-logo-general.svg"> </a> </div> <div> <ul class="flex justify-end h-full"> <li><a class="block px-2 py-4 text-lg font-bold text-blue-700 uppercase" href="#0">Conference</a></li> <li><a class="block px-2 py-4 text-lg font-bold text-blue-700 uppercase" href="#0">Sponsors</a></li> <li><a class="block px-2 py-4 text-lg font-bold text-blue-700 uppercase" href="#0">Community</a></li> <li><a class="block px-2 py-4 text-lg font-bold text-blue-700 uppercase" href="#0">FAQ</a></li> <li><a class="block px-2 py-4 text-lg font-bold text-white uppercase bg-blue-500" href="#0">Register</a> </li> </ul> </div> </div> </div> @opdavies
  35. @opdavies

  36. Task 4: Change the default configuration @opdavies

  37. Before we start git add -A git commit -m 'Save

    progress' git checkout -b local/4-config origin/task/3-navbar @opdavies
  38. tailwind.config.js 1 module.exports = { 2 // ... 3 4

    theme: { 5 fontFamily: { 6 display: ['Bebas Neue', 'Arial Narrow', 'Arial', 'sans-serif'], 7 sans: ['Helvetica', 'Arial', 'sans-serif'], 8 }, 9 colors: { 10 blue: { 11 DEFAULT: '#56a9db', 12 dark: '#1772ae', 13 }, 14 gray: { @opdavies
  39. 15 dark: '#333333', 16 }, 17 orange: '#fcb040', 18 white:

    '#ffffff', 19 }, 20 extend: { 21 fontSize: { 22 '2xl': '1.5625rem', // 25px 23 '3xl': '1.6875rem', // 27px 24 }, 25 }, 26 }, 27 } @opdavies
  40. Adding the Bebas font {# templates/html.html.twig #} <title>{% block title

    %}Tailwind CSS workshop{% endblock %}</title> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"> <link rel="preconnect" href="https://fonts.gstatic.com"> <link href="https://fonts.googleapis.com/css2?family=Bebas+Neue&display=swap" rel="stylesheet"> <link rel="stylesheet" href="/build/tailwind.css"/> {% block stylesheets %}{% endblock %} @opdavies
  41. Updating existing classes - <div class="max-w-2xl px-4 py-8 mx-auto text-center">

    + <div class="max-w-3xl px-4 py-8 mx-auto text-center"> - <p class="text-2xl leading-loose text-blue-700"> + <p class="text-3xl leading-loose text-blue-dark"> - <a class="inline-block px-5 py-4 mt-8 text-2xl text-blue-700 - transition-colors duration-200 ease-in-out border-2 border-blue-700 - hover:bg-blue-700 focus:bg-blue-700 hover:text-white focus:text-white" + <a class="inline-block px-5 py-4 mt-8 text-3xl transition-colors + duration-200 ease-in-out border-2 text-blue-dark border-blue-dark + hover:bg-blue-dark focus:bg-blue-dark hover:text-white focus:text-white" href="#0"> @opdavies
  42. Updating existing classes {# templates/includes/navbar.html.twig #} - <a class="block px-2

    py-4 text-lg font-bold text-blue-700 uppercase" + <a class="block px-2 py-3 text-2xl uppercase duration-200 ease-out + transition-color font-display text-blue-dark hover:bg-orange + focus:bg-orange hover:text-gray-dark focus:text-gray-dark" @opdavies
  43. @opdavies

  44. Task 5: Refactor - avoid duplication using loops @opdavies

  45. Before we start git add -A git commit -m 'Save

    progress' git checkout -b local/5-loops origin/task/4-configuration @opdavies
  46. Using a loop <a class="block px-2 py-3 text-2xl uppercase duration-200

    ease-out transition-color font-display text-blue-dark hover:bg-orange focus:bg-orange hover:text-gray-dark focus:text-gray-dark" href="#0">Community</a> <a class="block px-2 py-3 text-2xl uppercase duration-200 ease-out transition-color font-display text-blue-dark hover:bg-orange focus:bg-orange hover:text-gray-dark focus:text-gray-dark" href="#0">FAQ</a> <a class="block px-2 py-3 text-2xl text-white uppercase duration-200 ease-out transition-color font-display bg-blue hover:text-gray-dark focus:text-gray-dark" href="#0">Register</a> @opdavies
  47. Using a loop {% for menu_item in menu_items.findAll() %} {%

    set linkClasses = [ 'block px-2 py-3 text-2xl uppercase duration-200 ease-out transition-color font-display text-blue-dark hover:bg-orange focus:bg-orange hover:text-gray-dark focus:text-gray-dark', menu_item.is_active ? 'text-white bg-blue' ] %} <li> <a class="{{ linkClasses|join(' ')|trim }}" href="#0"> {{ menu_item.title }} </a> </li> {% endfor %} @opdavies
  48. Task 6: Add the video component @opdavies

  49. Before we start git add -A git commit -m 'Save

    progress' git checkout -b local/6-video origin/task/5-refactor-menu-item-loop @opdavies
  50. <div> <video poster="https://www.fldrupal.camp/sites/all/themes/fldc17/images/video-poster.jpg" preload="auto" > <source src="https://www.fldrupal.camp/sites/default/files/FLDC17%20Promo-high.mp4" type="video/mp4" > </video>

    </div> @opdavies
  51. @opdavies

  52. - <div> + <div class="px-4 mx-auto max-w-screen-2xl"> <video poster="https://www.fldrupal.camp/sites/all/themes/fldc17/images/video-poster.jpg" preload="auto"

    + class="w-full opacity-60" > <source src="https://www.fldrupal.camp/sites/default/files/FLDC17%20Promo-high.mp4" type="video/mp4" > </video> </div> @opdavies
  53. @opdavies

  54. Adding the logo <div class="px-4 mx-auto max-w-screen-2xl"> <video poster="https://www.fldrupal.camp/sites/all/themes/fldc17/images/video-poster.jpg" preload="auto"

    class="w-full opacity-60" > <source src="https://www.fldrupal.camp/sites/default/files/FLDC17%20Promo-high.mp4" type="video/mp4" > </video> <img src="https://www.fldrupal.camp/sites/all/themes/fldc17/images/logo-general.svg" alt="Florida Drupalcamp Logo"> </div> @opdavies
  55. @opdavies

  56. Positioning the logo - <div class="px-4 mx-auto max-w-screen-2xl"> + <div

    class="flex items-center justify-center px-4 mx-auto max-w-screen-2xl"> - <img src="https://www.fldrupal.camp/sites/all/themes/fldc17/images/logo-general.svg" ... + <img class="absolute w-96" src="..." @opdavies
  57. @opdavies

  58. Adding stars <img class="absolute w-96" src="https://www.fldrupal.camp/sites/all/themes/fldc17/images/logo-general.svg" alt="Florida Drupalcamp Logo"> <img

    src="https://www.fldrupal.camp/sites/all/themes/fldc17/images/stars-1.svg" alt=""> <img src="https://www.fldrupal.camp/sites/all/themes/fldc17/images/stars-2.svg" alt=""> <img src="https://www.fldrupal.camp/sites/all/themes/fldc17/images/stars-3.svg" alt=""> @opdavies
  59. Positioning the stars - <div class="flex items-center justify-center px-4 mx-auto

    max-w-screen-2xl"> + <div class="relative flex items-center justify-center px-4 mx-auto max-w-screen-2xl"> - <img src="https://www.fldrupal.camp/sites/all/themes/fldc17/images/stars-1.svg" alt=""> - <img src="https://www.fldrupal.camp/sites/all/themes/fldc17/images/stars-2.svg" alt=""> - <img src="https://www.fldrupal.camp/sites/all/themes/fldc17/images/stars-3.svg" alt=""> + <img class="absolute w-24 h-auto left-32 top-48" + src="https://www.fldrupal.camp/sites/all/themes/fldc17/images/stars-1.svg" alt=""> + <img class="absolute w-24 h-auto top-32 right-48" + src="https://www.fldrupal.camp/sites/all/themes/fldc17/images/stars-2.svg" alt=""> + <img class="absolute w-20 h-auto right-80 bottom-32" + src="https://www.fldrupal.camp/sites/all/themes/fldc17/images/stars-3.svg" alt=""> @opdavies
  60. @opdavies

  61. Task 7: Add the sponsors component @opdavies

  62. git add -A git commit -m 'Save progress' git checkout

    -b local/7-sponsors origin/task/6-video composer install yarn dev @opdavies
  63. <div> <h2>Sponsors</h2> <div> {% include 'includes/sponsor-list.html.twig' with { title: 'Platinum

    Sponsors', type: 'platinum', } only %} {% include 'includes/sponsor-list.html.twig' with { title: 'Gold Sponsors', type: 'gold', } only %} </div> </div> @opdavies
  64. <div> <h2>{{ title }}</h2> <ul> {% for sponsor in sponsors.findByType(type)

    %} <li> <a href="#0"> <img src="{{ sponsor.logo_url }}" alt=""> <p>{{ sponsor.name }}</p> </a> </li> {% endfor %} </ul> </div> @opdavies
  65. @opdavies

  66. {% set titleClasses = [ 'text-5xl font-display', type == 'bronze'

    ? 'text-bronze', type == 'gold' ? 'text-gold', type == 'in_kind' ? 'text-blue-dark', type == 'platinum' ? 'text-platinum', type == 'silver' ? 'text-silver', ] %} <div class="mt-10 text-center"> <h2 class="{{ titleClasses|join(' ')|trim }}">{{ title }}</h2> <div class="mt-6"> <ul class="flex flex-wrap justify-center mx-auto -mt-2 -ml-2"> {# ... #} </ul> @opdavies
  67. {% for sponsor in sponsors.findByType(type) %} <li class="mt-2 ml-2"> <a

    class="flex flex-col items-center justify-center w-64 h-48 p-4 bg-gray-light" href="#0" > <span class="flex items-center h-full"> <img class="block w-4/5 max-h-full mx-auto" src="{{ sponsor.logo_url }}" alt="" > </span> <p class="sr-only">{{ sponsor.name }}</p> </a> </li> {% endfor %} @opdavies
  68. @opdavies

  69. Task 8: Make it responsive @opdavies

  70. Before we start git add -A git commit -m 'Save

    progress' git checkout -b local/8-responsive origin/task/7-sponsors yarn dev @opdavies
  71. {# templates/includes/home/intro-text.html.twig #} - <p class="text-3xl leading-loose text-blue-dark"> + <p

    class="text-xl leading-loose lg:text-3xl text-blue-dark"> - <a class="inline-block px-5 py-4 mt-8 text-3xl transition-colors duration-200 ease-in-out - border-2 text-blue-dark border-blue-dark hover:bg-blue-dark focus:bg-blue-dark - hover:text-white focus:text-white" + <a class="inline-block px-4 py-3 mt-8 text-xl transition-colors duration-200 ease-in-out + border-2 lg:px-5 lg:py-4 lg:text-3xl text-blue-dark border-blue-dark hover:bg-blue-dark + focus:bg-blue-dark hover:text-white focus:text-white" href="#0">Learn more</a> @opdavies
  72. {# templates/includes/navbar.html.twig #} - <img class="relative z-20" ... + <img

    class="relative z-20 w-auto h-20 md:h-24" ... - <div> + <div class="flex items-center justify-end h-full"> + <button class="my-4 lg:hidden" type="button" aria-label="Toggle menu"> + <svg class="w-10 h-10" fill="none" stroke="currentColor" + viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> + <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" + d="M4 6h16M4 12h16M4 18h16"></path> + </svg> + </button> + - <ul class="flex justify-end h-full"> + <ul class="justify-end hidden h-full md:flex"> @opdavies
  73. {# templates/includes/home/sponsor-list.html.twig #} - <li class="mt-2 ml-2"> - <a class="flex

    flex-col items-center justify-center w-64 h-48 p-4 bg-gray-light" - href="#0"> + <li class="w-full mt-2 ml-2 sm:w-auto"> + <a class="flex flex-col items-center justify-center p-4 sm:w-64 sm:h-48 + sm:bg-gray-light" href="#0"> @opdavies
  74. Task 9: Configure PurgeCSS @opdavies

  75. # yarn dev yarn run v1.22.5 $ cross-env NODE_ENV=development postcss

    assets/css/tailwind.pcss -o public/build/tailwind.css Done in 2.77s. # ls -lh public/build total 1.8M -rw-r--r-- 1 root root 3.8M Feb 11 12:00 tailwind.css @opdavies
  76. # yarn prod yarn run v1.22.5 $ cross-env NODE_ENV=production postcss

    assets/css/tailwind.pcss -o public/build/tailwind.css warn - Tailwind is not purging unused styles because no template paths have been provided. warn - If you have manually configured PurgeCSS outside of Tailwind or are deliberately not removing unused styles, set `purge: false` in your Tailwind config file to silence this warning. warn - https://tailwindcss.com/docs/controlling-file-size/#removing-unused-css Done in 2.75s. @opdavies
  77. Configuring PurgeCSS // tailwind.config.js { - purge: [], + purge:

    { + content: ["templates/**/*.twig"] + }, // ... } @opdavies
  78. # yarn prod yarn run v1.22.5 $ cross-env NODE_ENV=production postcss

    assets/css/tailwind.pcss -o public/build/tailwind.css Done in 2.52s. # ls -lh public/build total 16K -rw-r--r-- 1 root root 12K Feb 11 17:31 tailwind.css @opdavies
  79. Thanks! References: • https://tailwindcss.com • https://tailwindui.com • https://www.youtube.com/c/TailwindLabs • https://drupal.org/project/tailwindcss

    Me: • https://www.oliverdavies.uk @opdavies