autoscale: true theme: Plain Jane, 1 # **Taking Flight with
Tailwind CSS** ![40%](images/tailwind.svg) ^ Tailwind CSS is a framework that I've been using for the last year and a half Going to be using Tailwind 1.0 which was released recently (May 13th) --- - PHP and Front End Developer - System Administrator - Senior Engineer at Inviqa - Part-time freelancer - Open sourcer - @opdavies - oliverdavies.uk ![right](../images/me-phpnw.png) ^ Co-organiser of PHP South Wales and DrupalCamp Bristol --- ![125%](images/techs.png) --- # **What is Tailwind CSS?** --- [.footer: tailwindcss.com] # A **utility-first** CSS framework for rapidly building **custom designs**. ^ CSS utility class generator PostCSS Make different looking sites using the same class names No "Tailwind looking site" like there is with Bootstrap --- [.footer: tailwindcss.com] # Tailwind CSS is a **highly customizable**, **low-level** CSS framework ^ No components like Bootstrap or Bulma Configure it per project Extendable if needed via additional plugins Avoids the need to name things prematurely Can extract components if needed (reusability) --- [.footer: tailwindcss.com/docs/what-is-tailwind/#designed-to-be-customized] # Tailwind is more than a CSS framework, it's an engine for
**creating design systems**. ^ Good default values provided - colours, fonts, padding, widths Designing with constraints. Using inline styles, every value is a magic number. With utilities, you're choosing styles from a predefined design system, which makes it much easier to build visually consistent UIs. --- - Text/border/background colours - Font size/family/weight - Alignment - Padding/margin/negative margin - Flexbox - Positioning - Lists - z-index - Opacity ^ Some of the 'original' things that Tailwind would generate classes for. --- - Screenreader visibility - Placeholder colour - first-child, last-child, nth-child - CSS Grid - Transition - Transform - Spacing / Divide ^ All generated from a single, customisable configuration file. --- ![](images/screenshot-laravel-nova.png) --- ![](images/screenshot-send-firefox.png) --- ![](images/screenshot-rebuilding-bartik.png) --- # **How do I use Tailwind?** ^ From the new tailwindcss.com website --- # With Tailwind, you style elements
by **applying pre-existing classes** directly in your HTML. --- # Using **utility classes** to build custom designs **without writing CSS** --- ## **Benefits** - You aren't wasting time and energy inventing class names - Your CSS stops growing - Making changes feels safer ^ No more adding silly class names like sidebar-inner-wrapper just to be able to style something, and no more agonizing over the perfect abstract name for something that's really just a flex container. ^ Using a traditional approach, your CSS files get bigger every time you add a new feature. With utilities, everything is reusable so you rarely need to write new CSS. ^ CSS is global and you never know what you're breaking when you make a change. Classes in your HTML are local, so you can change them without worrying about something else breaking. --- ![500%](images/example/0.png) --- ![500%](images/example/1.png) ^ Add padding with p-6 --- ![500%](images/example/2.png) ^ Rounded image - rounded-full --- ![500%](images/example/3.png) ^ Centre image using mx-auto --- ![500%](images/example/4.png) ^ Larger text - text-lg --- ![500%](images/example/5.png) ^ Purple text - text-purple-500 --- ![500%](images/example/6.png) ^ Grey text - text-gray-600 --- ![500%](images/example/7.png) ^ Centre text - text-center --- ![500%](images/example/8.png) ^ Responsive: enable flexbox on medium screens - md:flex --- ![500%](images/example/9.png) ^ Remove margin around image - md:mx-0 --- ![500%](images/example/10.png) ^ Re-align text on medium screens - md:text-left --- ![500%](images/example/11.png) ^ md:mr-6 - add margin to the side of the image on medium screens --- ![500%](images/example/12.png) ^ Increase image size - md:h-24 md:w-24 --- ![500%](images/example/13.png) ^ Smaller view --- # **How do I install Tailwind?** --- # **1. Use the CDN** --- [.footer: https://next.tailwindcss.com/docs/installation] ## **https://unpkg.com/tailwindcss/dist/tailwind.min.css** --- [.footer: https://next.tailwindcss.com/docs/installation] ## **To get the most out of Tailwind,
you really should install it via npm.** ^ - You can't customize Tailwind's default theme - You can't use any directives like _@apply_, _@variants_, etc. - You can't enable features like _group-hover_ - You can't install third-party plugins --- ## **2. Installing Tailwind via NPM** --- ## `npm install --save-dev`
`tailwindcss` ## `yarn add -D tailwindcss` ^ Adds it as a dependency to your package.json file --- ## **Adding Tailwind to your CSS** --- [.code-highlight: 2-7] ```css /* src/css/app.pcss */ @tailwind base; @tailwind components; @tailwind utilities; ``` --- [.code-highlight: 5,9,13] ``` /* src/css/app.pcss */ @tailwind base; /* Custom base styles go here */ @tailwind components; /* Custom components go here */ @tailwind utilities; /* Custom utilities go here */ ``` --- ## **Processing your CSS with Tailwind
with the build command** ^ Compile the generated CSS Pass through PostCSS and Tailwind --- # `npx tailwind build`
`src/css/app.pcss`
`-o dist/css/app.css` --- ```css .text-left { text-align: left; } .text-center { text-align: center; } .text-right { text-align: right; } .text-justify { text-align: justify; } ``` --- ## **Processing your CSS with Tailwind
with Laravel Mix** --- # `npm install --save-dev laravel-mix` --- ```js // webpack.mix.js const mix = require('laravel-mix') mix.postCss( 'src/css/app.pcss', 'dist/css', [ require('tailwindcss')() ] ) ``` ^ PostCSS - useful if you're including other PostCSS plugins like PostCSS Nested --- ```js // webpack.mix.js const mix = require('laravel-mix') require('laravel-mix-tailwind') mix.postCss('src/css/app.pcss', 'dist/css') .tailwind() ``` --- ```html My new website ``` --- # `npm run dev` # `npm run watch` # `npm run prod` --- # **Interaction states** ## hover, focus, active, disabled, visited,
group-hover, focus-within,
first-child, last-child... ^ Start to differ from inline styles --- # `[state][separator][class]` ^ State = hover, focus, group focus, focus within Separator = configurable, colon by default Class = the same utility class that you would have used normally --- # `hover:text-red-500` --- ```css .text-red-500 { color: #f56565; } .hover\:text-red-500:hover { color: #f56565; } .focus\:text-red-500:focus { color: #f56565; } ``` --- ```html Read more ``` --- ```js // defaultConfig.stub.js variants: { alignContent: ['responsive'], alignItems: ['responsive'], alignSelf: ['responsive'], appearance: ['responsive'], backgroundAttachment: ['responsive'], backgroundColor: ['responsive', 'hover', 'focus'], backgroundPosition: ['responsive'], backgroundRepeat: ['responsive'], ... ``` --- # **Responsive** ^ Mobile first --- # [fit] `.[screen][separator][class]` --- ```js // defaultConfig.stub.js screens: { sm: '640px', md: '768px', lg: '1024px', xl: '1280px', }, ``` --- # `md:flex` --- # `md:hover:bg-red-500` --- ```css .block { display: block; } @media (min-width: 640px) { .sm\:block { display: block; } } @media (min-width: 768px) { .md\:block { display: block; } } ``` --- ```html
Column 1
Column 2
``` --- # **Keeping Things Small:
Controlling the File Size** --- # Disabling unused variants
and core plugins --- ```js // tailwind.config.js variants: { alignContent: ['responsive'], alignItems: ['responsive'], alignSelf: ['responsive'], appearance: ['responsive'], backgroundAttachment: ['responsive'], backgroundColor: ['responsive', 'hover', 'focus'], ``` --- ```diff // tailwind.config.js variants: { alignContent: ['responsive'], alignItems: ['responsive'], - alignSelf: ['responsive'], + alignSelf: false, appearance: ['responsive'], backgroundAttachment: ['responsive'], - backgroundColor: ['responsive', 'hover', 'focus'], + backgroundColor: ['responsive'], ``` --- # **Manually removing** unused or unwanted classes --- ```js screens: { sm: '640px', md: '768px', lg: '1024px', xl: '1280px', }, colors: { transparent: 'transparent', black: '#000', white: '#fff', gray: { 100: '#f7fafc', 200: '#edf2f7', 300: '#e2e8f0', 400: '#cbd5e0', 500: '#a0aec0', 600: '#718096', 700: '#4a5568', 800: '#2d3748', 900: '#1a202c', }, ``` --- ```diff screens: { sm: '640px', md: '768px', lg: '1024px', - xl: '1280px', }, colors: { transparent: 'transparent', black: '#000', white: '#fff', gray: { 100: '#f7fafc', - 200: '#edf2f7', 300: '#e2e8f0', - 400: '#cbd5e0', - 500: '#a0aec0', 600: '#718096', 700: '#4a5568', - 800: '#2d3748', 900: '#1a202c', }, ``` ^ Needs to be done manually --- # **Automatically removing**
unused classes --- # `npm install --save-dev laravel-mix-purgecss` --- ```js const mix = require('laravel-mix') mix.postCss('src/css/site.css', 'dist/css').purgeCss({ folders: ['templates'], extensions: ['html', 'php', 'twig'], }) ``` --- [.code-highlight: 1,3,6-9] ```js const mix = require('laravel-mix') require('laravel-mix-purgecss') mix.postCss('src/css/site.css', 'dist/css').purgeCss({ folders: ['templates'], extensions: ['html', 'php', 'twig'], }) ``` ^ Can be tricky using Drupal/WordPress as you don't know where the classes could be coming from, no generated output directory --- # PurgeCSS is now **included by default** with Tailwind 1.4 --- [.code-highlight: 2-6] ```js module.exports = { purge: [ './src/**/*.html', './src/**/*.vue', './src/**/*.jsx', ], theme: {}, variants: {}, plugins: [], } ``` --- # Avoid repetition by **extracting components** --- # Does something **justify**
becoming a component? --- # Could the duplication
**be moved elsewhere**? ^ Twig partials Vue components WordPress template parts --- ```twig {# base.html.twig #} {% for item in navItems %} {{ item.title }} {% endfor %} ``` ^ Using a loop --- ```twig {# classes.html.twig #}

Adults

{% include 'class-list' with { classes: page.classes, type: 'adults', } %}

Kids

{% include 'class-list' with { classes: page.classes, type: 'kids', } %} ``` ^ Move the duplicate markup into a partial, so there's only one version Pass data in. --- ```css a.btn { @apply text-sm no-underline font-bold; @apply rounded-full inline-block px-5 py-2; @apply text-white bg-blue-600; } a.btn:hover { @apply bg-blue-700; } ``` ^ Use utilities as mixins Copy classes from markup Still re-using the same design system and constraints as before --- ```css a.btn { font-size: 0.875rem; text-decoration: none; font-weight: 700; border-radius: 9999px; display: inline-block; padding-left: 1.25rem; padding-right: 1.25rem; padding-top: 0.5rem; padding-bottom: 0.5rem; color: #fff; background-color: #3182ce; } a.btn:hover { background-color: #2b6cb0; } ``` --- # **Customising Tailwind** --- # `npx tailwind init` --- ```js // tailwind.config.js module.exports = { theme: { extend: {}, }, plugins: [], variants: {}, } ``` --- [.code-highlight: 5-7] ```js // tailwind.config.js module.exports = { theme: { colors: { inherit: 'inherit', }, extend: {}, }, plugins: [], variants: {}, } ``` ^ Overrides all colours. --- [.code-highlight: 5-9] ```js // tailwind.config.js module.exports = { theme: { extend: { colors: { inherit: 'inherit', }, }, }, plugins: [], variants: {}, } ``` ^ Extends Tailwind's default colours --- [.code-highlight: 1,4-5] ```js // tailwind.config.js module.exports = { prefix: '', important: false, theme: { extend: {}, }, plugins: [], variants: {}, } ``` --- # `npx tailwind init --full` --- # **Extending Tailwind CSS
with Plugins** --- # `npm install --save-dev tailwindcss-list-reset` --- [.code-highlight: 7-9] ```js // tailwind.config.js module.exports = { theme: { extend: {}, }, plugins: [require('tailwindcss-list-reset')()], variants: {}, } ``` --- ```css .list-reset { list-style: none; padding: 0; } ``` --- ```js // index.js module.exports = variants => ({addUtilities}) => { addUtilities( { '.list-reset': { listStyle: 'none', padding: 0, }, }, variants, ) } ``` --- # **Demo** --- ## **Useful links** - tailwindcss.com - tailwindui.com - builtwithtailwind.com - youtube.com/adamwathan - drupal.org/project/tailwindcss - oliverdavies.uk/tags/tailwind-css - oliverdavies.uk/tailwind-repos --- # **Questions?** ### oliverdavies.uk/tailwind-talk
@opdavies