Slide 1

Slide 1 text

Taking Flight with Tailwind CSS Oliver Davies (@opdavies) https://opdavi.es/dcg

Slide 2

Slide 2 text

What is utility-first CSS? • A different way to write CSS. • Instead of writing CSS in separate files, you work primarily in HTML. • Small CSS classes with a single responsibility. • Classes are named by what they do, not where they are used. @opdavies

Slide 3

Slide 3 text

The traditional CSS approach @opdavies

Slide 4

Slide 4 text

1 h1 { 2 font-size: 3rem; 3 font-weight: bold; 4 color: #020617; /* Dark grey */ 5 padding: .5rem 0 2rem; 6 } @opdavies

Slide 5

Slide 5 text

1 h1 { 2 font-size: 3rem; 3 font-weight: bold; 4 color: #020617; /* Dark grey */ 5 padding: .5rem 0 2rem; 6 } 7 8 .card { 9 padding: 2rem; 10 } 11 12 .card p { 13 color: #020617; /* Dark grey */ 14 font-size: 3rem; 15 font-weight: bold; 16 } @opdavies

Slide 6

Slide 6 text

1 h1 { 2 font-size: 3rem; 3 font-weight: bold; 4 color: #020617; /* Dark grey */ 5 padding: .5rem 0 2rem; 6 } 7 8 .card { 9 padding: 2rem; 10 } 11 12 .card p { 13 color: #020617; /* Dark grey */ 14 font-size: 3rem; 15 font-weight: bold; 16 } @opdavies

Slide 7

Slide 7 text

1 h1 { 2 font-size: 3rem; 3 font-weight: bold; 4 color: #020617; /* Dark grey */ 5 padding: .5rem 0 2rem; 6 } 7 8 .card { 9 padding: 2rem; 10 } 11 12 .card p { 13 color: #020617; /* Dark grey */ 14 font-size: 3rem; 15 font-weight: bold; 16 } @opdavies

Slide 8

Slide 8 text

1 h1 { 2 font-size: 3rem; 3 font-weight: bold; 4 color: #020617; /* Dark grey */ 5 padding: .5rem 0 2rem; 6 } 7 8 .card { 9 padding: 2rem; 10 } 11 12 .card p { 13 color: #020617; /* Dark grey */ 14 font-size: 3rem; 15 font-weight: bold; 16 } @opdavies

Slide 9

Slide 9 text

1 h1 { 2 font-size: 3rem; 3 font-weight: bold; 4 color: #020617; /* Dark grey */ 5 padding: .5rem 0 2rem; 6 } 7 8 .card { 9 padding: 2rem; 10 } 11 12 .card p { 13 color: #020617; /* Dark grey */ 14 font-size: 3rem; 15 font-weight: bold; 16 } @opdavies

Slide 10

Slide 10 text

The utility-first CSS approach @opdavies

Slide 11

Slide 11 text

1 .font-bold { 2 font-weight: bold; 3 } 4 5 .text-slate-900 { 6 color: #020617; 7 } 8 9 .text-5xl { 10 text-size: 3rem; 11 } 12 13 .flex { 14 display: flex; 15 } @opdavies

Slide 12

Slide 12 text

1 .font-bold { 2 font-weight: bold; 3 } 4 5 .text-slate-900 { 6 color: #020617; 7 } 8 9 .text-5xl { 10 text-size: 3rem; 11 } 12 13 .flex { 14 display: flex; 15 } @opdavies

Slide 13

Slide 13 text

1 .font-bold { 2 font-weight: bold; 3 } 4 5 .text-slate-900 { 6 color: #020617; 7 } 8 9 .text-5xl { 10 text-size: 3rem; 11 } 12 13 .flex { 14 display: flex; 15 } @opdavies

Slide 14

Slide 14 text

1 .font-bold { 2 font-weight: bold; 3 } 4 5 .text-slate-900 { 6 color: #020617; 7 } 8 9 .text-5xl { 10 text-size: 3rem; 11 } 12 13 .flex { 14 display: flex; 15 } @opdavies

Slide 15

Slide 15 text

1 .font-bold { 2 font-weight: bold; 3 } 4 5 .text-slate-900 { 6 color: #020617; 7 } 8 9 .text-5xl { 10 text-size: 3rem; 11 } 12 13 .flex { 14 display: flex; 15 } @opdavies

Slide 16

Slide 16 text

What problems does this solve? • 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

Slide 17

Slide 17 text

Examples @opdavies

Slide 18

Slide 18 text

@opdavies

Slide 19

Slide 19 text

@opdavies

Slide 20

Slide 20 text

@opdavies

Slide 21

Slide 21 text

What is Tailwind CSS? @opdavies

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

CSS utility class generator @opdavies

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

block inline flex grid @opdavies

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

Installation and Usage @opdavies

Slide 30

Slide 30 text

npm install --save-dev tailwindcss @opdavies

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

Interaction states @opdavies

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

[state][separator][class] @opdavies

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

Interaction states in HTML 1 5 Read more 6 @opdavies

Slide 41

Slide 41 text

Interaction states in HTML 1 5 Read more 6 @opdavies

Slide 42

Slide 42 text

Responsive @opdavies

Slide 43

Slide 43 text

[screen][separator][class] @opdavies

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

Arbitrary values @opdavies

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

How I deal with repetition? @opdavies

Slide 57

Slide 57 text

Avoid repetition by extracting components @opdavies

Slide 58

Slide 58 text

Loops 1 {% for item in navItems %} 2 6 {{ item.title }} 7 8 {% endfor %} @opdavies

Slide 59

Slide 59 text

Loops 1 {% for item in navItems %} 2 6 {{ item.title }} 7 8 {% endfor %} @opdavies

Slide 60

Slide 60 text

Loops 1 {% for item in navItems %} 2 6 {{ item.title }} 7 8 {% endfor %} @opdavies

Slide 61

Slide 61 text

Loops 1 {navItems.map(item => ( 2 6 {item.title} 7 8 ))} @opdavies

Slide 62

Slide 62 text

Loops 1 {navItems.map(item => ( 2 6 {item.title} 7 8 ))} @opdavies

Slide 63

Slide 63 text

Loops 1 {navItems.map(item => ( 2 6 {item.title} 7 8 ))} @opdavies

Slide 64

Slide 64 text

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

Slide 65

Slide 65 text

Includes 1

Adults

2 3 4 5

Kids

6 7 @opdavies

Slide 66

Slide 66 text

Keeping Things Small: Controlling the file size @opdavies

Slide 67

Slide 67 text

Just in Time (JIT mode) @opdavies

Slide 68

Slide 68 text

Content Tell Tailwind where it should look for utility classes. 1 // tailwind.config.js 2 3 module.exports = { 4 content: ['./templates/**/*.twig'], 5 // ... 6 } @opdavies

Slide 69

Slide 69 text

Customising Tailwind @opdavies

Slide 70

Slide 70 text

npx tailwind init @opdavies

Slide 71

Slide 71 text

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

Slide 72

Slide 72 text

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

Slide 73

Slide 73 text

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

Slide 74

Slide 74 text

npx tailwind init --full @opdavies

Slide 75

Slide 75 text

Adding Tailwind to your CSS @opdavies

Slide 76

Slide 76 text

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

Slide 77

Slide 77 text

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

Slide 78

Slide 78 text

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

Slide 79

Slide 79 text

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

Slide 80

Slide 80 text

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

Slide 81

Slide 81 text

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

Slide 82

Slide 82 text

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

Slide 83

Slide 83 text

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

Slide 84

Slide 84 text

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

Slide 85

Slide 85 text

Extending Tailwind CSS with Plugins @opdavies

Slide 86

Slide 86 text

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

Slide 87

Slide 87 text

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

Slide 88

Slide 88 text

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

Slide 89

Slide 89 text

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

Slide 90

Slide 90 text

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

Slide 91

Slide 91 text

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

Slide 92

Slide 92 text

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

Slide 93

Slide 93 text

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

Slide 94

Slide 94 text

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

Slide 95

Slide 95 text

Adding Tailwind CSS to an existing project @opdavies

Slide 96

Slide 96 text

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

Slide 97

Slide 97 text

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

Slide 98

Slide 98 text

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

Slide 99

Slide 99 text

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

Slide 100

Slide 100 text

!important !flex @opdavies

Slide 101

Slide 101 text

Tailwind CSS in Drupal @opdavies

Slide 102

Slide 102 text

@opdavies

Slide 103

Slide 103 text

@opdavies

Slide 104

Slide 104 text

composer require drupal/tailwindcss:^5 @opdavies

Slide 105

Slide 105 text

php web/core/scripts/drupal generate-theme my_theme --starterkit tailwindcss @opdavies

Slide 106

Slide 106 text

@opdavies

Slide 107

Slide 107 text

@opdavies

Slide 108

Slide 108 text

@opdavies

Slide 109

Slide 109 text

@opdavies

Slide 110

Slide 110 text

@opdavies

Slide 111

Slide 111 text

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