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

Taking Flight with Tailwind CSS

Oliver Davies
February 23, 2023

Taking Flight with Tailwind CSS

Oliver Davies

February 23, 2023
Tweet

More Decks by Oliver Davies

Other Decks in Technology

Transcript

  1. Taking Flight with
    Tailwind CSS
    Oliver Davies (@opdavies)

    View Slide

  2. @opdavies

    View Slide

  3. What is Tailwind CSS?
    @opdavies

    View Slide

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

    View Slide

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

    View Slide

  6. Tailwind is more than a CSS
    framework, it's an engine for
    creating design systems
    @opdavies

    View Slide

  7. • Text/border/background colours
    • Font size/family/weight
    • Alignment
    • Padding/margin/negative margin
    • Flexbox
    • Positioning
    • Lists
    • z-index
    • Opacity
    @opdavies

    View Slide

  8. • Screenreader visibility
    • Placeholder colour
    • first-child, last-child, nth-child
    • CSS Grid
    • Transition
    • Transform
    • Spacing / Divide
    • Focus ring
    • Text clamping
    @opdavies

    View Slide

  9. block inline flex grid
    @opdavies

    View Slide

  10. text-sm text-base text-lg
    text-xl text-2xl
    @opdavies

    View Slide

  11. text-blue-50 text-blue-100
    text-blue-200 text-blue-300
    text-blue-400 text-blue-500
    @opdavies

    View Slide

  12. @opdavies

    View Slide

  13. @opdavies

    View Slide

  14. @opdavies

    View Slide

  15. How to use Tailwind
    @opdavies

    View Slide

  16. Style elements by applying
    pre-existing classes directly in
    your HTML
    @opdavies

    View Slide

  17. Using utility classes to build
    custom designs without writing
    CSS
    @opdavies

    View Slide

  18. Benefits
    • You don't waste time and energy inventing class names.
    • No switching between CSS and HTML files.
    • Your CSS stops growing.
    • Reusability.
    • Making changes feels (and is) safer.
    @opdavies

    View Slide

  19. @opdavies

    View Slide

  20. @opdavies

    View Slide

  21. @opdavies

    View Slide

  22. @opdavies

    View Slide

  23. @opdavies

    View Slide

  24. @opdavies

    View Slide

  25. @opdavies

    View Slide

  26. @opdavies

    View Slide

  27. Installation and Usage
    @opdavies

    View Slide

  28. npm install --save-dev
    tailwindcss
    @opdavies

    View Slide

  29. npx tailwind
    --content index.html
    --output build/tailwind.css
    @opdavies

    View Slide

  30. Interaction states
    @opdavies

    View Slide

  31. hover, focus, active, disabled,
    visited, focus-within,
    first-child, last-child
    @opdavies

    View Slide

  32. [state][separator][class]
    @opdavies

    View Slide

  33. hover:text-red-500
    focus:text-red-500
    @opdavies

    View Slide

  34. Interaction states in CSS
    1 .text-red-500 {
    2 color: #f56565;
    3 }
    4
    5 .hover\:text-red-500:hover {
    6 color: #f56565;
    7 }
    8
    9 .focus\:text-red-500:focus {
    10 color: #f56565;
    11 }
    @opdavies

    View Slide

  35. Interaction states in HTML
    1 2 href="#"
    3 class="text-red-500 hover:text-red-800"
    4 >
    5 Read more
    6
    @opdavies

    View Slide

  36. Responsive
    @opdavies

    View Slide

  37. [screen][separator][class]
    @opdavies

    View Slide

  38. Screens (aka breakpoints)
    1 // defaultConfig.stub.js
    2
    3 screens: {
    4 sm: '640px',
    5 md: '768px',
    6 lg: '1024px',
    7 xl: '1280px',
    8 },
    @opdavies

    View Slide

  39. md:flex
    md:hover:bg-red-500
    @opdavies

    View Slide

  40. Responsive classes in CSS
    1 .block {
    2 display: block;
    3 }
    4
    5 @media (min-width: 640px) {
    6 .sm\:block {
    7 display: block;
    8 }
    9 }
    @opdavies

    View Slide

  41. Responsive classes in HTML
    1
    2
    3 Column 1
    4
    5
    6
    7 Column 2
    8
    9
    @opdavies

    View Slide

  42. Arbitrary values
    @opdavies

    View Slide

  43. w-[23px] md:w-[250px]
    text-[#abc123]
    @opdavies

    View Slide

  44. grid-cols-[fit-content(theme(sp
    acing.32))]
    @opdavies

    View Slide

  45. lg:[&:nth-child(3)]:hover
    :underline
    @opdavies

    View Slide

  46. How I deal with repetition?
    @opdavies

    View Slide

  47. Avoid repetition by extracting
    components
    @opdavies

    View Slide

  48. Loops
    1 {% for item in navItems %}
    2 3 class="block py-3 px-4 text-sm text-gray-800"
    4 href="{{ item.url }}"
    5 >
    6 {{ item.title }}
    7
    8 {% endfor %}
    @opdavies

    View Slide

  49. Loops
    1 {navItems.map(item => (
    2 3 class="block py-3 px-4 text-sm text-gray-800"
    4 href={item.url}
    5 >
    6 {item.title}
    7
    8 ))}
    @opdavies

    View Slide

  50. Includes
    1 Adults
    2
    3 {% include 'class-list' with {
    4 classes: page.classes,
    5 type: 'adults',
    6 } %}
    7
    8 Kids
    9
    10 {% include 'class-list' with {
    11 classes: page.classes,
    12 type: 'kids',
    13 } %}
    @opdavies

    View Slide

  51. Includes
    1 Adults
    2
    3
    4
    5 Kids
    6
    7
    @opdavies

    View Slide

  52. Extracting CSS components
    1 a.btn {
    2 @apply text-sm no-underline font-bold;
    3 @apply rounded-full inline-block px-5 py-2;
    4 @apply text-white bg-blue-600;
    5
    6 @apply hover:bg-blue-700;
    7 }
    @opdavies

    View Slide

  53. Extracting CSS components
    1 a.btn {
    2 font-size: 0.875rem;
    3 text-decoration: none;
    4 font-weight: 700;
    5 border-radius: 9999px;
    6 display: inline-block;
    7 padding-left: 1.25rem;
    8 padding-right: 1.25rem;
    9 padding-top: 0.5rem;
    10 padding-bottom: 0.5rem;
    11 color: #fff;
    12 background-color: #3182ce;
    13 }
    @opdavies

    View Slide

  54. 14
    15 a.btn:hover {
    16 background-color: #2b6cb0;
    17 }
    @opdavies

    View Slide

  55. Keeping Things Small:
    Controlling the file size
    @opdavies

    View Slide

  56. Just in Time (JIT mode)
    @opdavies

    View Slide

  57. Content
    Tell Tailwind where it should look for utility classes.
    1 // tailwind.config.js
    2
    3 module.exports = {
    4 mode: "jit",
    5 content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],
    6 // ...
    7 }
    @opdavies

    View Slide

  58. Customising Tailwind
    @opdavies

    View Slide

  59. npx tailwind init
    @opdavies

    View Slide

  60. tailwind.config.js
    1 /** @type {import('tailwindcss').Config} */
    2 module.exports = {
    3 content: [],
    4 theme: {
    5 extend: {},
    6 },
    7 plugins: [],
    8 }
    @opdavies

    View Slide

  61. Overriding configuration
    1 /** @type {import('tailwindcss').Config} */
    2 module.exports = {
    3 content: [],
    4 theme: {
    5 colors: {
    6 inherit: 'inherit'
    7 },
    8 extend: {},
    9 },
    10 plugins: [],
    11 }
    @opdavies

    View Slide

  62. Extending configuration
    1 /** @type {import('tailwindcss').Config} */
    2 module.exports = {
    3 content: [],
    4 theme: {
    5 extend: {
    6 colors: {
    7 inherit: 'inherit'
    8 }
    9 },
    10 },
    11 plugins: [],
    12 }
    @opdavies

    View Slide

  63. npx tailwind init --full
    @opdavies

    View Slide

  64. Adding Tailwind to your CSS
    @opdavies

    View Slide

  65. Including Tailwind
    1 /* src/css/tailwind.pcss */
    2
    3 @tailwind base;
    4
    5 @tailwind components;
    6
    7 @tailwind utilities;
    @opdavies

    View Slide

  66. Adding your own classes
    1 /* src/css/tailwind.pcss */
    2
    3 @tailwind base;
    4 /* Custom base styles */
    5
    6 @tailwind components;
    7 /* Custom components */
    8
    9 @tailwind utilities;
    10 /* Custom utilities */
    @opdavies

    View Slide

  67. Adding your own classes (with layers)
    1 /* src/css/tailwind.pcss */
    2
    3 @tailwind base;
    4 @tailwind components;
    5 @tailwind utilities;
    6
    7 @layer components {
    8 /* Custom components */
    9 }
    @opdavies

    View Slide

  68. npx tailwind
    --input src/css/tailwind.pcss
    --output dist/tailwind.css
    @opdavies

    View Slide

  69. Extending Tailwind CSS with
    Plugins
    @opdavies

    View Slide

  70. npm install --save-dev
    tailwindcss-list-reset
    @opdavies

    View Slide

  71. Adding a plugin
    1 // tailwind.config.js
    2
    3 module.exports = {
    4 theme: {
    5 extend: {},
    6 },
    7 plugins: [
    8 require('tailwindcss-list-reset')()
    9 ],
    10 variants: {},
    11 }
    @opdavies

    View Slide

  72. Generated CSS
    1 .list-reset {
    2 list-style: none;
    3 padding: 0;
    4 }
    @opdavies

    View Slide

  73. Writing plugins
    1 const plugin = require("tailwindcss/plugin");
    2
    @opdavies

    View Slide

  74. Writing plugins
    1 const plugin = require("tailwindcss/plugin");
    2
    3 module.exports = plugin(function({ addUtilities }) {
    4
    5 })
    6
    @opdavies

    View Slide

  75. Writing plugins
    1 const plugin = require("tailwindcss/plugin");
    2
    3 module.exports = plugin(function({ addUtilities }) {
    4 addUtilities({
    5 '.list-reset': {
    6 listStyle: 'none',
    7 padding: 0,
    8 },
    9 })
    10 })
    11
    @opdavies

    View Slide

  76. Writing plugins
    Adding child and child-hover variants:
    1 const plugin = require('tailwindcss/plugin');
    2
    3 module.exports = plugin(({ addVariant }) => {
    4 addVariant('child', '& > *');
    5 addVariant('child-hover', '& > *:hover');
    6 });
    @opdavies

    View Slide

  77. Writing plugins
    Adding a hocus variant:
    1 const plugin = require('tailwindcss/plugin');
    2
    3 module.exports = plugin(({ addVariant }) => {
    4 addVariant('hocus', ['&:hover', '&:focus']);
    5 });
    @opdavies

    View Slide

  78. Writing plugins
    Creating a button component:
    1 const plugin = require("tailwindcss/plugin");
    2
    3 module.exports = plugin(({ addComponents, theme }) {
    4
    5 });
    6
    @opdavies

    View Slide

  79. Writing plugins
    1 const plugin = require("tailwindcss/plugin");
    2
    3 module.exports = plugin(({ addComponents, theme }) {
    4 let styles = {
    5 primary: {
    6 default: {
    7 backgroundColor: theme("colors.primary.DEFAULT"),
    8 border: `2px solid ${theme("colors.primary.dark")}`,
    9 borderRadius: "10px",
    10 color: theme("colors.white"),
    11 cursor: "pointer",
    12 padding: `${theme("padding.3")} ${theme("padding.12")}`,
    13 },
    @opdavies

    View Slide

  80. 14
    15 hover: {
    16 backgroundColor: theme("colors.white"),
    17 color: theme("colors.primary.DEFAULT"),
    18 },
    19 },
    20 }
    21 });
    22
    @opdavies

    View Slide

  81. Writing plugins
    1 const plugin = require("tailwindcss/plugin");
    2
    3 module.exports = plugin(({ addComponents, theme }) {
    4
    5 // ...
    6
    7 addComponents({
    8 "#edit-checkout.button": styles.primary.default,
    9 "#edit-checkout.button:hover, #edit-checkout.button:focus":
    10 styles.primary.hover,
    11 });
    12 });
    13
    @opdavies

    View Slide

  82. Adding Tailwind CSS to an
    existing project
    @opdavies

    View Slide

  83. Disabling the reset styles
    1 /** @type {import('tailwindcss').Config} */
    2 module.exports = {
    3 content: [],
    4 theme: {
    5 extend: {},
    6 },
    7 corePlugins: {
    8 preflight: false,
    9 },
    10 plugins: [],
    11 }
    @opdavies

    View Slide

  84. Prefixing class names
    Turn classes like flex into tw-flex.
    1 /** @type {import('tailwindcss').Config} */
    2 module.exports = {
    3 prefix: "tw-",
    4 content: [],
    5 theme: {
    6 extend: {},
    7 },
    8 plugins: [],
    9 }
    @opdavies

    View Slide

  85. !important
    1 /** @type {import('tailwindcss').Config} */
    2 module.exports = {
    3 important: true,
    4 content: [],
    5 theme: {
    6 extend: {},
    7 },
    8 plugins: [],
    9 }
    @opdavies

    View Slide

  86. !important
    1 /** @type {import('tailwindcss').Config} */
    2 module.exports = {
    3 important: "#app",
    4 content: [],
    5 theme: {
    6 extend: {},
    7 },
    8 plugins: [],
    9 }
    @opdavies

    View Slide

  87. !important
    !flex
    @opdavies

    View Slide

  88. @opdavies

    View Slide

  89. Demo
    @opdavies

    View Slide

  90. Thanks!
    References:
    • https://tailwindcss.com
    • https://tailwindui.com
    • https://www.youtube.com/c/TailwindLabs
    • https://www.protailwind.com
    • https://drupal.org/project/tailwindcss
    Me:
    • https://www.oliverdavies.uk
    @opdavies

    View Slide