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

Rapid designing with Tailwind CSS

Rapid designing with Tailwind CSS

Component-focused CSS frameworks such as Bootstrap get you up and running quickly, but often lack the tools necessary for designing custom interfaces. For this people usually just use plain (S)CSS, which gets the job done but can become difficult to maintain in the long run.

Enter Tailwind, a utility-first CSS framework that approaches building complex components from a constrained set of primitive utilities. What sets Tailwind apart is the vast range of CSS properties it covers, a powerful PostCSS-backed configuration API and excellent documentation that explains CSS along the way. This talk will show Tailwind's unique approach to various aspects of design (spacing, colors, pseudo-classes, responsive design and more) and compare it with existing solutions.

Janko Marohnić

May 29, 2020
Tweet

More Decks by Janko Marohnić

Other Decks in Programming

Transcript

  1. Tailwind CSS
    Rapid designing with utility-first approach

    View Slide

  2. Janko Marohnić
    • Ruby developer
    • open source contributor
    • inexperienced in CSS
    • mainly used Bootstrap

    View Slide

  3. Tailwind CSS
    • utility-first CSS framework
    • maps closely to CSS properties
    • PostCSS plugin
    • created by Adam Wathan in 2017

    View Slide

  4. Bootstrap
    1 CSS
    2
    Tailwind
    3

    View Slide

  5. Utility-First

    View Slide

  6. View Slide

  7. CSS

    View Slide





  8. Private Villa



    Relaxing All-Inclusive Resort in Cancun



    $299 USD per night



    View Slide

  9. .vacation-card {
    width: 16rem;
    margin: 0 auto;
    }
    .vacation-card-info {
    margin-top: .5rem;
    }
    .vacation-card-image {
    border-radius: .25rem;
    }
    .vacation-card-title {
    font-weight: 700;
    color: #4a5568;
    line-height: 1.375;
    }
    .vacation-card-eyebrow {
    font-size: .75rem;
    color: #718096;
    text-transform: uppercase;
    font-weight: 700;
    }
    .vacation-card-link:hover {
    text-decoration: underline;
    }
    .vacation-card-price {
    margin-top: .5rem;
    font-size: .875rem;
    color: #718096;
    }

    View Slide

  10. Bootstrap

    View Slide





  11. Private Villa



    Relaxing All-Inclusive Resort in Cancun



    $299 USD per night



    View Slide

  12. .vacation-card {
    width: 16rem;
    }
    .vacation-card-eyebrow {
    font-size: .75rem;
    color: #718096;
    }
    .vacation-card-title {
    color: #4a5568;
    line-height: 1.375;
    }
    .vacation-card-link:hover {
    text-decoration: underline;
    }
    .vacation-card-price {
    font-size: .875rem;
    color: #718096;
    }

    View Slide





  13. Private Villa



    Relaxing All-Inclusive Resort in Cancun



    $299 USD per night



    View Slide

  14. Why?

    View Slide

  15. Embraces connection between
    HTML and CSS
    1

    View Slide

  16. No need to keep inventing
    new class names
    2
    .card-inner-outer-wrapper
    .container-wrapper-container
    .box-control-outer-container

    View Slide

  17. Localized styling
    makes changes safer
    3

    View Slide

  18. Your CSS stops growing
    4

    View Slide

  19. You’re designing with constraints
    5
    font-size: .875rem .text-sm
    color: #feb2b2 .text-red-300
    height: 100vh .h-screen

    View Slide

  20. Documentation teaches CSS

    View Slide

  21. Bootstrap Tailwind
    .d-block .d-inline-block .d-flex ... .block .inline-block .flex ...
    .justify-content-start
    .align-items-center
    .align-self-center ...
    .justify-start
    .items-center
    .self-center ...
    .text-uppercase
    .font-italic
    .font-weight-bold ...
    .uppercase
    .italic
    .font-bold ...
    .position-absolute
    .position-relative ...
    .absolute
    .relative ...

    View Slide

  22. DRY

    View Slide




  23. Apple
    Apple
    ...





    Kiwi
    Kiwi
    ...


    page1.html
    page2.html

    View Slide




  24. {title}
    {text}
    ...



    Card.jsx
    Card.vue
    card.erb
    card.php
    ...
    page1.html

    page2.html

    View Slide




  25. {title}
    {text}
    ...



    Card.jsx
    Card.vue
    card.erb
    card.php
    ...
    page1.html

    page2.html

    View Slide

  26. .btn-blue {
    background-color: #4299e1;
    color: white;
    font-weight: 700;
    padding: 0.5rem 1rem;
    border-radius: 0.25rem;
    }
    Some Link

    ...
    Save

    View Slide

  27. .btn-blue {
    @apply bg-blue-500 text-white font-bold py-2 px-4 rounded;
    }
    Some Link

    ...
    Save

    PostCSS directive

    View Slide

  28. Spacing
    &
    Sizing

    View Slide

  29. .vacation-card {
    margin: 15px;
    padding: 18em;
    width: 77%;
    height: 16rem;
    }

    View Slide

  30. .m-*
    .mt-*
    .mb-*
    .ml-*
    .mr-*
    .mx-*
    .my-*
    Margin Padding
    .p-*
    .pt-*
    .pb-*
    .pl-*
    .pr-*
    .px-*
    .py-*
    Suffix Amount
    *-0
    *-1
    *-2
    *-3
    *-4
    *-5
    0
    0.25rem
    0.5rem
    1rem
    1.5rem
    3rem

    View Slide

  31. .m-*
    .mt-*
    .mb-*
    .ml-*
    .mr-*
    .mx-*
    .my-*
    Margin Padding
    .p-*
    .pt-*
    .pb-*
    .pl-*
    .pr-*
    .px-*
    .py-*
    Suffix Amount
    *-0
    *-1
    *-2
    *-3
    *-4
    *-5
    *-6
    *-8
    *-10
    *-12
    *-16
    *-20
    ...
    *-64
    0
    0.25rem
    0.5rem
    1.75rem
    1rem
    1.25rem
    1.5rem
    2rem
    2.5rem
    3rem
    4rem
    5rem
    ...
    16rem
    Width
    .w-*
    Height
    .h-*

    View Slide

  32. Class Property
    .w-25
    .w-50
    .w-75
    .w-100
    width: 25%
    width: 50%
    width: 75%
    width: 100%

    View Slide

  33. Class Property
    .w-1/2
    .w-1/3
    .w-2/3
    .w-1/4
    .w-2/4
    .w-3/4
    .w-1/5
    .w-2/5
    .w-3/5
    ...
    .w-11/12
    .w-full
    width: 50%
    width: 33.333333%
    width: 66.666667%
    width: 25%
    width: 50%
    width: 75%
    width: 20%
    width: 40%
    width: 60%
    ...
    width: 91.66667%
    width: 100%

    View Slide


  34. ...
    ...
    ...

    View Slide


  35. ...
    ...
    ...

    View Slide


  36. ...
    ...
    ...

    View Slide

  37. Phone Number




    View Slide

  38. Phone Number




    View Slide

  39. module.exports = {
    theme: {
    extend: {
    spacing: {
    '18': '4.5rem',
    }
    }
    }
    }
    ...
    .m-16
    .m-18
    .m-20
    ...
    ...
    .p-16
    .p-18
    .p-20
    ...
    ...
    .w-16
    .w-18
    .w-20
    ...
    ...
    .h-16
    .h-18
    .h-20
    ...
    ...
    4rem
    4.5rem
    5rem
    ...
    tailwind.config.js

    View Slide

  40. module.exports = {
    theme: {
    spacing: {
    'sm': '8px',
    'md': '12px',
    'lg': '16px',
    'xl': '24px',
    }
    }
    }
    tailwind.config.js
    m-sm
    m-md
    m-lg
    m-xl
    p-sm
    p-md
    p-lg
    m-xl
    w-sm
    w-md
    w-lg
    w-xl
    h-sm
    h-md
    h-lg
    h-xl

    View Slide

  41. Colors

    View Slide

  42. #4b0082
    indigo
    rgb(76, 0, 130)
    rgba(76, 0, 130, 1.0)
    hsl(275, 100%, 25%)
    darken(#4b0082, 10%)
    lighten(#4b0082, 15%)
    tint(#4b0082, 20%)
    shade(#4b0082, 30%)
    ...
    ...

    View Slide

  43. *-primary
    *-secondary
    *-success
    *-danger
    *-warning
    *-info
    *-light
    *-dark
    ...
    .text-*
    .bg-*
    .border-*

    View Slide

  44. Taken from Refactoring UI

    View Slide

  45. Taken from Refactoring UI

    View Slide

  46. View Slide

  47. .text-red-300
    .bg-blue-500
    .border-green-700
    .btn-indigo {
    background-color: theme('colors.indigo.500');
    }
    PostCSS function

    View Slide

  48. module.exports = {
    theme: {
    colors: {
    indigo: {
    lighter: '#b3bcf5',
    default: '#5c6ac4',
    dark: '#202e78',
    }
    }
    }
    }
    tailwind.config.js
    .text-indigo-lighter
    .text-indigo-default
    .text-indigo-dark
    .bg-indigo-lighter
    .bg-indigo-default
    .bg-indigo-dark
    .border-indigo-lighter
    .border-indigo-default
    .border-indigo-dark

    View Slide

  49. const { colors } = require('tailwindcss/defaultTheme')
    module.exports = {
    theme: {
    colors: {
    indigo: {
    lighter: colors.indigo['300'],
    default: colors.indigo['500'],
    dark: colors.indigo['700'],
    },
    blue: {
    ...colors.blue,
    '900': '#1e3656',
    }
    }
    }
    }
    tailwind.config.js

    View Slide

  50. Pseudo-Classes

    View Slide

  51. Save
    .btn-blue { ... }
    .btn-blue:hover {
    background-color: #2B6CB0;
    }
    .btn-blue:focus {
    background-color: #2B6CB0;
    box-shadow: 0 0 0 3px rgba(66, 153, 225, 0.5);
    }

    View Slide


  52. Save


    Some Link


    Tab

    View Slide

  53. .hover\:bg-blue-500:hover {
    background-color: #4299e1;
    }
    .focus\:shadow-outline:focus {
    box-shadow: 0 0 0 3px rgba(66, 153, 225, 0.5);
    }
    .active\:text-indigo-300:active {
    color: #a3bffa;
    }

    View Slide

  54. @variants hover, focus {
    .hyphens-none {
    hyphens: none;
    }
    .hyphens-manual {
    hyphens: manual;
    }
    .hyphens-auto {
    hyphens: auto;
    }
    }
    PostCSS directive

    View Slide

  55. .hyphens-none { hyphens: none; }
    .hover\:hyphens-none:hover { hyphens: none; }
    .focus\:hyphens-none:focus { hyphens: none; }
    .hyphens-manual { hyphens: manual; }
    .hover\:hyphens-manual:hover { hyphens: manual; }
    .focus\:hyphens-manual:focus { hyphens: manual; }
    .hyphens-auto { hyphens: auto; }
    .hover\:hyphens-auto:hover { hyphens: auto; }
    .focus\:hyphens-auto:focus { hyphens: auto; }

    View Slide


  56. View Slide

  57. Responsive Design

    View Slide

  58. @media (min-width: 640px) { ... }
    @media (min-width: 768px) { ... }
    @media (min-width: 1024px) { ... }
    @media (min-width: 1280px) { ... }

    View Slide

  59. .col-sm-8
    .col-md-6
    .col-lg-4
    .col-xl-2
    .d-sm-block
    .d-md-inline-block
    .d-lg-flex
    .d-xl-none
    .flex-sm-row
    .justify-content-md-center
    .align-items-lg-baseline
    .align-self-xl-end
    .row-cols-sm-8
    .row-cols-md-6
    .row-cols-lg-4
    .row-cols-xl-2

    View Slide

  60. .d-sm-block
    .d-md-inline-block
    .d-lg-flex
    .d-xl-none

    View Slide

  61. .sm:block
    .md:inline-block
    .lg:flex
    .xl:hidden

    View Slide

  62. .sm:text-red-500
    .md:text-center
    .lg:text-lg
    .xl:font-bold
    .sm:mt-0
    .md:px-4
    .lg:w-40
    .xl:h-24
    .sm:self-start
    .md:justify-center
    .lg:items-baseline
    .xl:content-around
    .sm:border-2
    .md:border-blue-500
    .lg:border-dashed
    .xl:rounded-full
    .sm:grid-cols-2
    .md:grid-cols-4
    .lg:grid-cols-6
    .xl:grid-cols-8
    .sm:flex-grow
    .md:flex-shrink
    .lg:flex-initial
    .xl:flex-auto
    .sm:bg-gray-100
    .md:bg-fixed
    .lg:bg-opacity-50
    .xl:bg-left
    .sm:transition
    .md:duration-100
    .lg:scale-50
    .xl:translate-100
    .sm:block
    .md:inline-block
    .lg:flex
    .xl:hidden

    View Slide


  63. Foo
    Bar
    Baz

    View Slide

  64. @responsive {
    .hyphens-none {
    hyphens: none;
    }
    .hyphens-manual {
    hyphens: manual;
    }
    .hyphens-auto {
    hyphens: auto;
    }
    }
    PostCSS directive

    View Slide

  65. @media (min-width: 640px) {
    .sm\:hyphens-none { hyphens: none; }
    .sm\:hyphens-manual { hyphens: manual; }
    .sm\:hyphens-auto { hyphens: auto; }
    }
    @media (min-width: 768px) {
    .md\:hyphens-none { hyphens: none; }
    .md\:hyphens-manual { hyphens: manual; }
    .md\:hyphens-auto { hyphens: auto; }
    }
    @media (min-width: 1024px) {
    .lg\:hyphens-none { hyphens: none; }
    .lg\:hyphens-manual { hyphens: manual; }
    .lg\:hyphens-auto { hyphens: auto; }
    }
    @media (min-width: 1280px) {
    .xl\:hyphens-none { hyphens: none; }
    .xl\:hyphens-manual { hyphens: manual; }
    .xl\:hyphens-auto { hyphens: auto; }
    }

    View Slide


  66. View Slide

  67. Bundle Size

    View Slide

  68. ~1.8MB
    uncompressed
    ~148KB
    minified and compressed with Gzip
    ~44KB
    compressed with Brotli

    View Slide

  69. PurgeCSS
    1

    View Slide

  70. module.exports = {
    purge: [
    'src/**/*.html',
    'src/**/*.vue',
    'src/**/*.jsx',
    ],
    theme: {},
    variants: {},
    plugins: [],
    }
    tailwind.config.js

    View Slide

  71. You must list all files in your project that reference
    any of Tailwind class names
    !
    You must not use string concatenation
    to create class names
    !



    View Slide

  72. Reducing features
    2

    View Slide

  73. module.exports = {
    theme: {
    borderColor: theme => ({ 'green': theme('colors.green.300') }),
    divideColor: theme => ({ 'green': theme('colors.green.300') }),
    translate: { '1': '0.25rem' },
    },
    corePlugins: [
    'placeholderColor', 'placeholderOpacity', 'textOpacity',
    'skew', 'scale', 'rotate', 'gap',
    'gridColumn', 'gridColumnStart', 'gridColumnEnd',
    'gridRow', 'gridRowStart', 'gridRowEnd',
    ].reduce((list, plugin) => ({ [plugin]: false, ...list }), {}),
    variants: {
    textColor: ['hover', 'focus'],
    backgroundColor: ['hover', 'focus'],
    borderRadius: [], borderOpacity: ['hover', 'focus'],
    transitionDuration: [], transitionDelay: [],
    },
    }
    tailwind.config.js

    View Slide

  74. 0
    450
    900
    1350
    1800
    Uncompressed Gzip
    Original Reduced
    1800K
    400K
    148KB
    56K

    View Slide

  75. Recap
    • maps closely to CSS
    • naming optimized for writing
    • generous defaults (colors, spacing)
    • pseudo-class & responsive variants (for each class)
    • PostCSS directives & functions
    • advanced JavaScript-based configuration

    View Slide

  76. Resources
    • https://tailwindcss.com/docs
    • https://tailwindcss.com/screencasts
    • https://tailwindcss-custom-forms.netlify.app/
    • https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-
    tailwindcss
    • https://github.com/aniftyco/awesome-tailwindcss
    • https://adamwathan.me/css-utility-classes-and-separation-of-concerns/
    • Adam Wathan’s YouTube channel
    • Steve Schoger's design tips

    View Slide