Jump to content
Sergio

Tailwind CSS for ProcessWire Developers

Recommended Posts

Tailwind CSS Framework, a utility-first CSS framework for rapidly building custom designs

This thread is a place for ProcessWire developers who use (or would like to use) Tailwind CSS to share their experience, tips, frustrations , solutions, code snippets and generally discuss all things tailwind.

From the creators of Tailwind CSS

Quote

Tailwind CSS is a highly customizable, low-level CSS framework that gives you all of the building blocks you need to build bespoke designs without any annoying opinionated styles you have to fight to override.

 

Moderator note: the first few posts in this topic were split from this thread.

##########################

 

Thanks, @apeisa! Yes, Tailwind is awesome! Responsive classes are a clever idea indeed, much easier to work with. The authors did an excellent job and keep improving it.

Some people may feel a little sceptical, but I fell in love with it the moment I built my first project.  Although nowadays I work alone, I believe that Tailwind makes work between a frontend and backend developers much easier because it makes the HTML more declarative and you can grasp what the classes mean in a glimpse.

  • Like 3

Share this post


Link to post
Share on other sites
10 hours ago, arjen said:

 

I'm pretty interested in Tailwind too. I'd love to hear some pointers on your set-up and workflow? How do you guys handle the filesize? I've read about Purgecss and I'm curious how integrate this with ProcessWire.

The easiest way I've found is to use Laravel Mix with two plugins, Laravel Mix Tailwind and Laravel Mix PurgeCSS to reduce file size by going through all php templates. But note, the website is not running the purged version yet, as I'm working on some configs on javascript generated classes and classes set by the user via admin (using RepeaterMatrix). 

But I also reduced manually Tailwinds output by using just a few colors and removing other pieces. 

Take a look on my webpack.mix.js file:

Spoiler

let mix = require('laravel-mix');
require('laravel-mix-tailwind');
require('laravel-mix-purgecss');

mix
    .js('./site/templates/src/js/app.js', './site/templates/js/app.js')
    .js('./site/templates/src/js/infinity-scroll.js', './site/templates/js/vendor.js')
    .sass('./site/templates/src/sass/app.scss', './site/templates/css', { outputStyle: 'compressed' })
    .tailwind("./tailwind-config.js")
    .purgeCss({
        enabled: mix.inProduction(),

        folders: ['./site/templates/css'],
        
        globs: [
            path.join(__dirname, './site/templates/**/*.php'),
        ],

        extensions: ['php'],

         // Other options are passed through to Purgecss
  		 // /^uk-/ filter for classes beginning with uk-, from uikit
         whitelistPatterns: [/^uk-/, /^md\:tw-float-/],

        extractors: [
            {
                extractor: class {
                    static extract(content) {
                        return content.match(/[A-z0-9-:\/]+/g)
                    }
                },
                extensions: ['php']
            }
        ]
    })

And here goes Tailwind Config file. Note: I'm using Tailwind earlier version (prior to 1.0). Will upgrade it when possible, but it works just fine. 

Spoiler

/*

Tailwind - The Utility-First CSS Framework

A project by Adam Wathan (@adamwathan), Jonathan Reinink (@reinink),
David Hemphill (@davidhemphill) and Steve Schoger (@steveschoger).

Welcome to the Tailwind config file. This is where you can customize
Tailwind specifically for your project. Don't be intimidated by the
length of this file. It's really just a big JavaScript object and
we've done our very best to explain each section.

View the full documentation at https://tailwindcss.com.


|-------------------------------------------------------------------------------
| The default config
|-------------------------------------------------------------------------------
|
| This variable contains the default Tailwind config. You don't have
| to use it, but it can sometimes be helpful to have available. For
| example, you may choose to merge your custom configuration
| values with some of the Tailwind defaults.
|
*/

let defaultConfig = require('tailwindcss/defaultConfig')()


/*
|-------------------------------------------------------------------------------
| Colors                                    https://tailwindcss.com/docs/colors
|-------------------------------------------------------------------------------
|
| Here you can specify the colors used in your project. To get you started,
| we've provided a generous palette of great looking colors that are perfect
| for prototyping, but don't hesitate to change them for your project. You
| own these colors, nothing will break if you change everything about them.
|
| We've used literal color names ("red", "blue", etc.) for the default
| palette, but if you'd rather use functional names like "primary" and
| "secondary", or even a numeric scale like "100" and "200", go for it.
|
*/

let colors = {
  'transparent': 'transparent',
  'black': '#22292f',
  'beige-darkest': 'hsla(30, 27%, 66%, 1)',
  'beige-darker': 'hsla(30, 27%, 46%, 1)',
  'beige-dark': 'hsla(30, 27%, 90%, 1)',
  'beige': 'hsla(30, 27%, 96%, 1)',
  'beige-light': 'hsla(30, 27%, 98%, 1)',
  // 'beige-lighter': 'hsla(30, 27%, 100%, 1)',,
  // 'beige-lightest': '#f8fafc',
  'white': '#ffffff',

  // 'orange-darkest': '#9A6948',
  'orange-darker': 'hsla(20, 85%, 25%, 1)',
  'orange-dark': 'hsla(20, 70%, 28%, 1)',
  'orange': 'hsla(20, 90%, 55%, 1)',
  'orange-light': '#faad63',
  'orange-lighter': 'hsla(20, 100%, 65%, 1)',
  // 'orange-lightest': '#fff5eb',

  // 'yellow-darkest': '#453411',
  'yellow-darker': 'hsla(44, 99%, 33%, 1)',
  'yellow-dark': 'hsla(44, 99%, 43%, 1)',
  'yellow': 'hsla(44, 99%, 53%, 1)',
  'yellow-light': 'hsla(44, 99%, 63%, 1)',
  'yellow-lighter': 'hsla(44, 99%, 83%, 1)',
  // 'yellow-lightest': '#fcfbeb',

  'purple-darker': 'hsl(238, 32%, 35%)',
  'purple-dark': 'hsl(238, 32%, 45%)',
  'purple': 'hsl(238, 32%, 55%)',
  'purple-light': '#a779e9',
  'purple-lighter': '#d6bbfc',
  // 'purple-lightest': '#f3ebff',

}

module.exports = {

  /*
  |-----------------------------------------------------------------------------
  | Colors                                  https://tailwindcss.com/docs/colors
  |-----------------------------------------------------------------------------
  |
  | The color palette defined above is also assigned to the "colors" key of
  | your Tailwind config. This makes it easy to access them in your CSS
  | using Tailwind's config helper. For example:
  |
  | .error { color: config('colors.red') }
  |
  */

  colors: colors,


  /*
  |-----------------------------------------------------------------------------
  | Screens                      https://tailwindcss.com/docs/responsive-design
  |-----------------------------------------------------------------------------
  |
  | Screens in Tailwind are translated to CSS media queries. They define the
  | responsive breakpoints for your project. By default Tailwind takes a
  | "mobile first" approach, where each screen size represents a minimum
  | viewport width. Feel free to have as few or as many screens as you
  | want, naming them in whatever way you'd prefer for your project.
  |
  | Tailwind also allows for more complex screen definitions, which can be
  | useful in certain situations. Be sure to see the full responsive
  | documentation for a complete list of options.
  |
  | Class name: .{screen}:{utility}
  |
  */

  screens: {
    // 'mobile': {'max': '767px'},
    // 'sm': '576px',
    'md': '768px',
    'lg': '992px',
    'xl': '1400px',
    'widescreen': '1800px'
  },


  /*
  |-----------------------------------------------------------------------------
  | Fonts                                    https://tailwindcss.com/docs/fonts
  |-----------------------------------------------------------------------------
  |
  | Here is where you define your project's font stack, or font families.
  | Keep in mind that Tailwind doesn't actually load any fonts for you.
  | If you're using custom fonts you'll need to import them prior to
  | defining them here.
  |
  | By default we provide a native font stack that works remarkably well on
  | any device or OS you're using, since it just uses the default fonts
  | provided by the platform.
  |
  | Class name: .font-{name}
  | CSS property: font-family
  |
  */

  fonts: {
    'sans': [
      'Lato',
      'system-ui',
      'BlinkMacSystemFont',
      '-apple-system',
      'Segoe UI',
      'Roboto',
      'Oxygen',
      'Ubuntu',
      'Cantarell',
      'Fira Sans',
      'Droid Sans',
      'Helvetica Neue',
      'sans-serif',
    ],
    'serif': [
      'Constantia',
      'Lucida Bright',
      'Lucidabright',
      'Lucida Serif',
      'Lucida',
      'DejaVu Serif',
      'Bitstream Vera Serif',
      'Liberation Serif',
      'Georgia',
      'serif',
    ],
    'mono': [
      'Menlo',
      'Monaco',
      'Consolas',
      'Liberation Mono',
      'Courier New',
      'monospace',
    ],
  },


  /*
  |-----------------------------------------------------------------------------
  | Text sizes                         https://tailwindcss.com/docs/text-sizing
  |-----------------------------------------------------------------------------
  |
  | Here is where you define your text sizes. Name these in whatever way
  | makes the most sense to you. We use size names by default, but
  | you're welcome to use a numeric scale or even something else
  | entirely.
  |
  | By default Tailwind uses the "rem" unit type for most measurements.
  | This allows you to set a root font size which all other sizes are
  | then based on. That said, you are free to use whatever units you
  | prefer, be it rems, ems, pixels or other.
  |
  | Class name: .text-{size}
  | CSS property: font-size
  |
  */

  textSizes: {
    'xs': '.625rem',     // 10px
    'sm': '.875rem',    // 14px
    'base': '1rem',     // 16px
    'lg': '1.125rem',   // 18px
    'xl': '1.25rem',    // 20px
    '2xl': '1.5rem',    // 24px
    '3xl': '1.875rem',  // 30px
    '4xl': '2.25rem',   // 36px
    '5xl': '3rem',      // 48px
    '6xl': '4rem',      // 64px
    '7xl': '5rem',      // 80px
  },


  /*
  |-----------------------------------------------------------------------------
  | Font weights                       https://tailwindcss.com/docs/font-weight
  |-----------------------------------------------------------------------------
  |
  | Here is where you define your font weights. We've provided a list of
  | common font weight names with their respective numeric scale values
  | to get you started. It's unlikely that your project will require
  | all of these, so we recommend removing those you don't need.
  |
  | Class name: .font-{weight}
  | CSS property: font-weight
  |
  */

  fontWeights: {
    // 'hairline': 100,
    // 'thin': 200,
    'light': 300,
    'normal': 400,
    // 'medium': 500,
    'semibold': 600,
    'bold': 700,
    // 'extrabold': 800,
    'black': 900,
  },


  /*
  |-----------------------------------------------------------------------------
  | Leading (line height)              https://tailwindcss.com/docs/line-height
  |-----------------------------------------------------------------------------
  |
  | Here is where you define your line height values, or as we call
  | them in Tailwind, leadings.
  |
  | Class name: .leading-{size}
  | CSS property: line-height
  |
  */

  leading: {
    'negative': 0.8,
    'none': 1,
    'tight': 1.25,
    'normal': 1.6,
    'loose': 2,
  },


  /*
  |-----------------------------------------------------------------------------
  | Tracking (letter spacing)       https://tailwindcss.com/docs/letter-spacing
  |-----------------------------------------------------------------------------
  |
  | Here is where you define your letter spacing values, or as we call
  | them in Tailwind, tracking.
  |
  | Class name: .tracking-{size}
  | CSS property: letter-spacing
  |
  */

  tracking: {
    'tight': '-0.1em',
    'normal': '.1em',
    'wide': '0.15em',
  },


  /*
  |-----------------------------------------------------------------------------
  | Text colors                         https://tailwindcss.com/docs/text-color
  |-----------------------------------------------------------------------------
  |
  | Here is where you define your text colors. By default these use the
  | color palette we defined above, however you're welcome to set these
  | independently if that makes sense for your project.
  |
  | Class name: .text-{color}
  | CSS property: color
  |
  */

  textColors: colors,


  /*
  |-----------------------------------------------------------------------------
  | Background colors             https://tailwindcss.com/docs/background-color
  |-----------------------------------------------------------------------------
  |
  | Here is where you define your background colors. By default these use
  | the color palette we defined above, however you're welcome to set
  | these independently if that makes sense for your project.
  |
  | Class name: .bg-{color}
  | CSS property: background-color
  |
  */

  backgroundColors: colors,


  /*
  |-----------------------------------------------------------------------------
  | Background sizes               https://tailwindcss.com/docs/background-size
  |-----------------------------------------------------------------------------
  |
  | Here is where you define your background sizes. We provide some common
  | values that are useful in most projects, but feel free to add other sizes
  | that are specific to your project here as well.
  |
  | Class name: .bg-{size}
  | CSS property: background-size
  |
  */

  backgroundSize: {
    'auto': 'auto',
    'cover': 'cover',
    'contain': 'contain',
  },


  /*
  |-----------------------------------------------------------------------------
  | Border widths                     https://tailwindcss.com/docs/border-width
  |-----------------------------------------------------------------------------
  |
  | Here is where you define your border widths. Take note that border
  | widths require a special "default" value set as well. This is the
  | width that will be used when you do not specify a border width.
  |
  | Class name: .border{-side?}{-width?}
  | CSS property: border-width
  |
  */

  borderWidths: {
    default: '1px',
    '0': '0',
    '2': '2px',
    '4': '4px',
    '8': '8px',
  },


  /*
  |-----------------------------------------------------------------------------
  | Border colors                     https://tailwindcss.com/docs/border-color
  |-----------------------------------------------------------------------------
  |
  | Here is where you define your border colors. By default these use the
  | color palette we defined above, however you're welcome to set these
  | independently if that makes sense for your project.
  |
  | Take note that border colors require a special "default" value set
  | as well. This is the color that will be used when you do not
  | specify a border color.
  |
  | Class name: .border-{color}
  | CSS property: border-color
  |
  */

  borderColors: global.Object.assign({ default: colors['beige-light'] }, colors),


  /*
  |-----------------------------------------------------------------------------
  | Border radius                    https://tailwindcss.com/docs/border-radius
  |-----------------------------------------------------------------------------
  |
  | Here is where you define your border radius values. If a `default` radius
  | is provided, it will be made available as the non-suffixed `.rounded`
  | utility.
  |
  | If your scale includes a `0` value to reset already rounded corners, it's
  | a good idea to put it first so other values are able to override it.
  |
  | Class name: .rounded{-side?}{-size?}
  | CSS property: border-radius
  |
  */

  borderRadius: {
    // 'none': '0',
    // 'sm': '.125rem',
    default: '.25rem',
    'lg': '.5rem',
    'full': '9999px',
  },


  /*
  |-----------------------------------------------------------------------------
  | Width                                    https://tailwindcss.com/docs/width
  |-----------------------------------------------------------------------------
  |
  | Here is where you define your width utility sizes. These can be
  | percentage based, pixels, rems, or any other units. By default
  | we provide a sensible rem based numeric scale, a percentage
  | based fraction scale, plus some other common use-cases. You
  | can, of course, modify these values as needed.
  |
  |
  | It's also worth mentioning that Tailwind automatically escapes
  | invalid CSS class name characters, which allows you to have
  | awesome classes like .w-2/3.
  |
  | Class name: .w-{size}
  | CSS property: width
  |
  */

  width: {
    'auto': 'auto',
    'px': '1px',
    '1': '0.25rem',
    '2': '0.5rem',
    '3': '0.75rem',
    '4': '1rem',
    '5': '1.25rem',
    '6': '1.5rem',
    '8': '2rem',
    '10': '2.5rem',
    '12': '3rem',
    '16': '4rem',
    '24': '6rem',
    '32': '8rem',
    '48': '12rem',
    '64': '16rem',
    '1/2': '50%',
    '1/3': '33.33333%',
    '2/3': '66.66667%',
    '1/4': '25%',
    '3/4': '75%',
    '1/5': '20%',
    '2/5': '40%',
    '3/5': '60%',
    '4/5': '80%',
    '1/6': '16.66667%',
    '5/6': '83.33333%',
    'full': '100%',
    'screen': '100vw',
  },


  /*
  |-----------------------------------------------------------------------------
  | Height                                  https://tailwindcss.com/docs/height
  |-----------------------------------------------------------------------------
  |
  | Here is where you define your height utility sizes. These can be
  | percentage based, pixels, rems, or any other units. By default
  | we provide a sensible rem based numeric scale plus some other
  | common use-cases. You can, of course, modify these values as
  | needed.
  |
  | Class name: .h-{size}
  | CSS property: height
  |
  */

  height: {
    'auto': 'auto',
    'px': '1px',
    '1': '0.25rem',
    '2': '0.5rem',
    '3': '0.75rem',
    '4': '1rem',
    '5': '1.25rem',
    '6': '1.5rem',
    '8': '2rem',
    '10': '2.5rem',
    '12': '3rem',
    '16': '4rem',
    '24': '6rem',
    '32': '8rem',
    '48': '12rem',
    '64': '16rem',
    'full': '100%',
    'screen': '100vh',
  },


  /*
  |-----------------------------------------------------------------------------
  | Minimum width                        https://tailwindcss.com/docs/min-width
  |-----------------------------------------------------------------------------
  |
  | Here is where you define your minimum width utility sizes. These can
  | be percentage based, pixels, rems, or any other units. We provide a
  | couple common use-cases by default. You can, of course, modify
  | these values as needed.
  |
  | Class name: .min-w-{size}
  | CSS property: min-width
  |
  */

  minWidth: {
    '0': '0',
    'full': '100%',
  },


  /*
  |-----------------------------------------------------------------------------
  | Minimum height                      https://tailwindcss.com/docs/min-height
  |-----------------------------------------------------------------------------
  |
  | Here is where you define your minimum height utility sizes. These can
  | be percentage based, pixels, rems, or any other units. We provide a
  | few common use-cases by default. You can, of course, modify these
  | values as needed.
  |
  | Class name: .min-h-{size}
  | CSS property: min-height
  |
  */

  minHeight: {
    '0': '0',
    'full': '100%',
    'screen': '100vh',
  },


  /*
  |-----------------------------------------------------------------------------
  | Maximum width                        https://tailwindcss.com/docs/max-width
  |-----------------------------------------------------------------------------
  |
  | Here is where you define your maximum width utility sizes. These can
  | be percentage based, pixels, rems, or any other units. By default
  | we provide a sensible rem based scale and a "full width" size,
  | which is basically a reset utility. You can, of course,
  | modify these values as needed.
  |
  | Class name: .max-w-{size}
  | CSS property: max-width
  |
  */

  maxWidth: {
    'xs': '20rem',
    'sm': '30rem',
    'md': '40rem',
    'lg': '50rem',
    'xl': '60rem',
    '2xl': '70rem',
    '3xl': '80rem',
    '4xl': '90rem',
    '5xl': '100rem',
    '6xl': '120rem',
    'full': '100%',
  },


  /*
  |-----------------------------------------------------------------------------
  | Maximum height                      https://tailwindcss.com/docs/max-height
  |-----------------------------------------------------------------------------
  |
  | Here is where you define your maximum height utility sizes. These can
  | be percentage based, pixels, rems, or any other units. We provide a
  | couple common use-cases by default. You can, of course, modify
  | these values as needed.
  |
  | Class name: .max-h-{size}
  | CSS property: max-height
  |
  */

  maxHeight: {
    'full': '100%',
    'screen': '100vh',
  },


  /*
  |-----------------------------------------------------------------------------
  | Padding                                https://tailwindcss.com/docs/padding
  |-----------------------------------------------------------------------------
  |
  | Here is where you define your padding utility sizes. These can be
  | percentage based, pixels, rems, or any other units. By default we
  | provide a sensible rem based numeric scale plus a couple other
  | common use-cases like "1px". You can, of course, modify these
  | values as needed.
  |
  | Class name: .p{side?}-{size}
  | CSS property: padding
  |
  */

  padding: {
    'px': '1px',
    '0': '0',
    '1': '0.25rem',
    '2': '0.5rem',
    '3': '0.75rem',
    '4': '1rem',
    '5': '1.25rem',
    '6': '1.5rem',
    '8': '2rem',
    '10': '2.5rem',
    '12': '3rem',
    '16': '4rem',
    '20': '5rem',
    '24': '6rem',
    '32': '8rem',
  },


  /*
  |-----------------------------------------------------------------------------
  | Margin                                  https://tailwindcss.com/docs/margin
  |-----------------------------------------------------------------------------
  |
  | Here is where you define your margin utility sizes. These can be
  | percentage based, pixels, rems, or any other units. By default we
  | provide a sensible rem based numeric scale plus a couple other
  | common use-cases like "1px". You can, of course, modify these
  | values as needed.
  |
  | Class name: .m{side?}-{size}
  | CSS property: margin
  |
  */

  margin: {
    'auto': 'auto',
    'px': '1px',
    '0': '0',
    '1': '0.25rem',
    '2': '0.5rem',
    '3': '0.75rem',
    '4': '1rem',
    '5': '1.25rem',
    '6': '1.5rem',
    '8': '2rem',
    '10': '2.5rem',
    '12': '3rem',
    '16': '4rem',
    '20': '5rem',
    '24': '6rem',
    '32': '8rem',
  },


  /*
  |-----------------------------------------------------------------------------
  | Negative margin                https://tailwindcss.com/docs/negative-margin
  |-----------------------------------------------------------------------------
  |
  | Here is where you define your negative margin utility sizes. These can
  | be percentage based, pixels, rems, or any other units. By default we
  | provide matching values to the padding scale since these utilities
  | generally get used together. You can, of course, modify these
  | values as needed.
  |
  | Class name: .-m{side?}-{size}
  | CSS property: margin
  |
  */

  negativeMargin: {
    // 'px': '1px',
    // '0': '0',
    // '1': '0.25rem',
    '2': '0.5rem',
    '3': '0.75rem',
    '4': '1rem',
    '5': '1.25rem',
    '6': '1.5rem',
    '8': '2rem',
    // '10': '2.5rem',
    '12': '3rem',
    // '16': '4rem',
    // '20': '5rem',
    '24': '6rem',
    '32': '8rem',
  },


  /*
  |-----------------------------------------------------------------------------
  | Shadows                                https://tailwindcss.com/docs/shadows
  |-----------------------------------------------------------------------------
  |
  | Here is where you define your shadow utilities. As you can see from
  | the defaults we provide, it's possible to apply multiple shadows
  | per utility using comma separation.
  |
  | If a `default` shadow is provided, it will be made available as the non-
  | suffixed `.shadow` utility.
  |
  | Class name: .shadow-{size?}
  | CSS property: box-shadow
  |
  */

  shadows: {
    default: '0 2px 4px 0 rgba(0,0,0,0.10), 0 1px 2px 0 rgba(0,0,0,0.06)',
    'md': '0 4px 8px 0 rgba(0,0,0,0.12), 0 2px 4px 0 rgba(0,0,0,0.08)',
    'lg': '0 15px 30px 0 rgba(0,0,0,0.11), 0 5px 15px 0 rgba(0,0,0,0.08)',
    'inner': 'inset 0 2px 4px 0 rgba(0,0,0,0.06)',
    'outline': '0 0 0 3px rgba(52,144,220,0.5)',
    'none': 'none',
  },
  


  /*
  |-----------------------------------------------------------------------------
  | Z-index                                https://tailwindcss.com/docs/z-index
  |-----------------------------------------------------------------------------
  |
  | Here is where you define your z-index utility values. By default we
  | provide a sensible numeric scale. You can, of course, modify these
  | values as needed.
  |
  | Class name: .z-{index}
  | CSS property: z-index
  |
  */

  zIndex: {
    // 'auto': 'auto',
    // '0': 0,
    '10': 10,
    '20': 20,
    '30': 30,
    // '40': 40,
    // '50': 50,
  },


  /*
  |-----------------------------------------------------------------------------
  | Opacity                                https://tailwindcss.com/docs/opacity
  |-----------------------------------------------------------------------------
  |
  | Here is where you define your opacity utility values. By default we
  | provide a sensible numeric scale. You can, of course, modify these
  | values as needed.
  |
  | Class name: .opacity-{name}
  | CSS property: opacity
  |
  */

  opacity: {
    '0': '0',
    '25': '.25',
    '50': '.5',
    '75': '.75',
    '100': '1',
  },


  /*
  |-----------------------------------------------------------------------------
  | SVG fill                                   https://tailwindcss.com/docs/svg
  |-----------------------------------------------------------------------------
  |
  | Here is where you define your SVG fill colors. By default we just provide
  | `fill-current` which sets the fill to the current text color. This lets you
  | specify a fill color using existing text color utilities and helps keep the
  | generated CSS file size down.
  |
  | Class name: .fill-{name}
  | CSS property: fill
  |
  */

  svgFill: {
    'current': 'currentColor',
  },


  /*
  |-----------------------------------------------------------------------------
  | SVG stroke                                 https://tailwindcss.com/docs/svg
  |-----------------------------------------------------------------------------
  |
  | Here is where you define your SVG stroke colors. By default we just provide
  | `stroke-current` which sets the stroke to the current text color. This lets
  | you specify a stroke color using existing text color utilities and helps
  | keep the generated CSS file size down.
  |
  | Class name: .stroke-{name}
  | CSS property: stroke
  |
  */

  svgStroke: {
    'current': 'currentColor',
  },


  /*
  |-----------------------------------------------------------------------------
  | Modules                  https://tailwindcss.com/docs/configuration#modules
  |-----------------------------------------------------------------------------
  |
  | Here is where you control which modules are generated and what variants are
  | generated for each of those modules.
  |
  | Currently supported variants:
  |   - responsive
  |   - hover
  |   - focus
  |   - focus-within
  |   - active
  |   - group-hover
  |
  | To disable a module completely, use `false` instead of an array.
  |
  */

  modules: {
    appearance: ['responsive'],
    backgroundAttachment: ['responsive'],
    backgroundColors: ['hover', 'focus'],
    backgroundPosition: ['responsive'],
    backgroundRepeat: ['responsive'],
    backgroundSize: ['responsive'],
    borderCollapse: [],
    borderColors: ['focus'],
    borderRadius: ['responsive'],
    borderStyle: [],
    borderWidths: [],
    // cursor: ['responsive'],
    display: ['responsive'],
    flexbox: ['responsive'],
    float: ['responsive'],
    // fonts: ['responsive'],
    // fontWeights: ['responsive', 'hover', 'focus'],
    height: ['responsive'],
    leading: ['responsive'],
    lists: ['responsive'],
    margin: ['responsive'],
    maxHeight: ['responsive'],
    maxWidth: ['responsive'],
    minHeight: ['responsive'],
    minWidth: ['responsive'],
    negativeMargin: ['responsive'],
    objectFit: false,
    objectPosition: false,
    opacity: ['hover'],
    outline: ['focus'],
    overflow: ['responsive, hover'],
    padding: ['responsive'],
    pointerEvents: ['responsive'],
    position: ['responsive'],
    resize: ['responsive'],
    shadows: ['responsive', 'hover'],
    svgFill: [],
    svgStroke: [],
    tableLayout: ['responsive'],
    textAlign: ['responsive'],
    textColors: ['responsive', 'hover', 'focus'],
    textSizes: ['responsive'],
    textStyle: ['responsive', 'hover', 'focus'],
    tracking: ['responsive'],
    userSelect: ['responsive'],
    verticalAlign: ['responsive'],
    visibility: ['responsive'],
    whitespace: ['responsive'],
    width: ['responsive'],
    zIndex: ['responsive'],
  },


  /*
  |-----------------------------------------------------------------------------
  | Plugins                                https://tailwindcss.com/docs/plugins
  |-----------------------------------------------------------------------------
  |
  | Here is where you can register any plugins you'd like to use in your
  | project. Tailwind's built-in `container` plugin is enabled by default to
  | give you a Bootstrap-style responsive container component out of the box.
  |
  | Be sure to view the complete plugin documentation to learn more about how
  | the plugin system works.
  |
  */

  plugins: [
    // require('tailwindcss/plugins/container')({
      // center: true,
      // padding: '1rem',
    // }),
    require('tailwindcss-transition')({
      // standard: 'all .3s ease',
      transitions: {
        'normal': 'all .1s cubic-bezier(0.455, 0.03, 0.515, 0.955)',
        'slow': 'all .2s cubic-bezier(.17,.67,.83,.67)',
      },
      // variants: ['hover'],  
    }),
  ],


  /*
  |-----------------------------------------------------------------------------
  | Advanced Options         https://tailwindcss.com/docs/configuration#options
  |-----------------------------------------------------------------------------
  |
  | Here is where you can tweak advanced configuration options. We recommend
  | leaving these options alone unless you absolutely need to change them.
  |
  */

  options: {
    prefix: 'tw-',
    important: false,
    separator: ':',
  },

}

 

  • Like 2

Share this post


Link to post
Share on other sites

@Sergio Could you put your long code sample into a "spoiler" please? Anyway, thanks for sharing 🙂

Share this post


Link to post
Share on other sites
2 hours ago, szabesz said:

@Sergio Could you put your long code sample into a "spoiler" please? Anyway, thanks for sharing 🙂

Sorry! Just did :)

  • Like 1

Share this post


Link to post
Share on other sites
16 hours ago, Sergio said:

The easiest way I've found is to use Laravel Mix with two plugins, Laravel Mix Tailwind and Laravel Mix PurgeCSS to reduce file size by going through all php templates. But note, the website is not running the purged version yet, as I'm working on some configs on javascript generated classes and classes set by the user via admin (using RepeaterMatrix). 

Thanks! 

This is what got me thinking as well since I use a lot of generated classes (also in PHP and JS). How well a job does purgecss do with those? I know you can whitelist classes, but it feels cumbersome to maintain it.

Share this post


Link to post
Share on other sites
4 hours ago, arjen said:

Thanks! 

This is what got me thinking as well since I use a lot of generated classes (also in PHP and JS). How well a job does purgecss do with those? I know you can whitelist classes, but it feels cumbersome to maintain it.

That's a good question, I still need to figure out all the details. PurgeCSS lets you whitelist patterns, not just classes, so I usually use js- on my classes that will be handled only by javascript. Also, you can extract from .js files as well, or any other extension if you create your own extractor, and also set `/* purgecss ignore */` on a css file to ignore all classes bellow it. 

Share this post


Link to post
Share on other sites

Thanks for getting back on this. I'll try some stuff out. 

Share this post


Link to post
Share on other sites
5 hours ago, arjen said:

Thanks for getting back on this. I'll try some stuff out. 

No problem!

When I have some time here I'm planning to build a site profile using Tailwind CSS so more people can see how it can be integrated with PW. Using both the CDN version, which gzipped is around 60kb and using brotli compression goes down to less than 20kb and the webpack installation I mentioned. :)

  • Like 5

Share this post


Link to post
Share on other sites

Two sites I have build with tailwind and purge css. Other site css file was 3.4kb and other 2.5kb... I also skip purge from my own css, just tailwind goes through it. 

It is actually very simple. It does "scan" all the files you need. But in case of ProcessWire custom classes can come from many places, so I felt it easiest to purge only tailwind css. And I am pretty happy with the file size results... 

  • Like 1

Share this post


Link to post
Share on other sites

Thanks @Sergio, @apeisa and @Tom. for bringing Tailwind CSS to our attention. Incidentally, I checked out the Tailwind screencasts and ended up picking up Vue.js as well :-). Anyway, to my first question.

16 hours ago, apeisa said:

Two sites I have build with tailwind and purge css. Other site css file was 3.4kb and other 2.5kb... I also skip purge from my own css, just tailwind goes through it. 

It is actually very simple. It does "scan" all the files you need. But in case of ProcessWire custom classes can come from many places, so I felt it easiest to purge only tailwind css. And I am pretty happy with the file size results... 

@apeisa, could you please clarify this statement about ProcessWire custom classes. Does it mean you use Tailwind in the backend/admin/modules or does it mean you use ProcessWire inputfields in the frontend? 

Thanks.

Cross-posting Tom's Tailwind + UIKit + Grid resource:

 

  • Like 3

Share this post


Link to post
Share on other sites

Ah, that meant just for purge css. Things like pagination markup (and css classes it uses by default) comes from core module, so if you want to use those and just style using css, you need to disable purge for that part of css. 

  • Like 1

Share this post


Link to post
Share on other sites
12 minutes ago, apeisa said:

Ah, that meant just for purge css. Things like pagination markup (and css classes it uses by default) comes from core module, so if you want to use those and just style using css, you need to disable purge for that part of css. 

I prefer to change the pagination style on _init.php, or _func.php, for instance, to use Tailwind classes, using Ryan's modified example:

 
 
 
 
Spoiler

//Render pagination nav using custom classes
//If page has URL segment, append it to pagination link
function renderPagination(PageArray $items, $segment = '') {

	if(!$items->getLimit() || $items->getTotal() <= $items->getLimit()) return '';

	$next = isset($options['next']) ? $options['next'] : __('Next');
	$previous = isset($options['previous']) ? $options['previous'] : __('Previous'); 

	$page = page();
	if(!$page->template->allowPageNum) {
		return "Pagination is not enabled for this template";
	}

	// customize the MarkupPagerNav to output
    //using Tailwind CSS classes prefixed with tw-
	$options = array(
		'numPageLinks' => 4, //4 is a good size for mobile as we're using next and prev items
		'nextItemLabel' => $next,
		//'nextItemClass' => '',
		// 'previousItemLabel' => '<span><i></i></span>',
		// 'previousItemClass' => '',
		// 'lastItemClass' => '',
		'currentItemClass' => 'tw-bg-orange tw-font-black',
		'separatorItemLabel' => '<span>&hellip;</span>',
		'listMarkup' => "<ul id='js-pagination' class='tw-my-8 tw-justify-center tw-text-lg tw-list-reset tw-flex'>{out}</ul>",
		'itemMarkup' => "<li class='{class} tw-mr-3'>{out}</li>",
		'linkMarkup' => "<a href='{url}' class='tw-rounded tw-bg-white tw-px-3 tw-py-2 hover:tw-bg-orange hover:tw-text-white'>{out}</a>",
		'currentLinkMarkup' => "<span class='tw-px-2 tw-py-2'>{out}</span>"
	);

	
	$pager = modules('MarkupPagerNav');
	$pager->setBaseUrl($page->url.$segment);

	return $pager->render($items, $options);
}

 

 

  • Like 3

Share this post


Link to post
Share on other sites

Yes, that works great too in that case and others similar cases if there is possibility to tweak markup. 

I also found that purge failed on rather complex navbar css so I found it easiest to skip purge on my own css. Not a problem since with tailwind I write very little css anyways. 

  • Like 1

Share this post


Link to post
Share on other sites
14 hours ago, apeisa said:

Yes, that works great too in that case and others similar cases if there is possibility to tweak markup.

Just to add to this a bit: I've found it a bit problematic if you're, for an example, working with nested structures where the nesting level should affect things. That's one example where, to my best knowledge so far, it's usually easier to rely on custom classes. You can still make use of @apply and similar features behind the scenes to make use of Tailwind's features as much as possible, but the point is that you can't always rely on directly applied Tailwind classes alone – at least not without creating solutions that are either inflexible, or unnecessarily complex 🙂

As a disclaimer I'm currently building my first site with Tailwind. It's been a bit of an emotional rollercoaster: at times I find Tailwind utterly awesome, while the very next moment I can be really frustrated with it as I'm once again struggling to figure out what's the Tailwind version of some CSS rule I already have in mind. (For the record, https://nerdcave.com/tailwind-cheat-sheet has been a big help in this regard.)

I've been constantly tweaking my approach, going back and forth with things like components and custom utility classes, trying to figure out how to best combine those with native Tailwind features, when to add a new "spacing" or color (or something similar) to Tailwind's config vs. just applying a one-off custom value instead, etc. That being said, I've already got a list of do's and don'ts for my next Tailwind project, so it should go a lot smoother.

For the past year or so I've been deeply invested in a BEM type approach, and in some ways Tailwind is the opposite of that. That shift in mental models has definitely been holding me back a bit. After my next project with Tailwind I hope to have a more informed opinion, but currently if someone asked me if they should use Tailwind for their next project, I'd have to reply with "it's complicated" 😅

  • Like 3

Share this post


Link to post
Share on other sites

This looks very interesting! Thx for sharing @Sergio and thx for linking to the screencasts @kongondo - they really give a quick introduction and many times it felt as he was reading all the questions that where coming up in my mind. They did an awesome job here.

I'm not very experienced in frontend stuff, that's why I like using uikit and all its predefined components. It's quite easy to customize with LESS and you can even use hooks (https://getuikit.com/docs/less). Shouldn't it also work with purgecss (this was also new to me)? So far it seems to me that uikit and tailwind are not that different?! Uikit also has lots of utility classes (like uk-padding-large, uk-margin-small-left, uk-text-bold etc). Only difference seems to be that tailwind is even more unopinionated / low level?

So using tailwind you'd get more customized components and less bloat whereas using uikit you'd get all the existing components from start but also get more bloat, is that correct?

Share this post


Link to post
Share on other sites
29 minutes ago, bernhard said:

So using tailwind you'd get more customized components and less bloat whereas using uikit you'd get all the existing components from start but also get more bloat, is that correct?

define "bloat". In your CSS or HTML? Because this surely looks ugly to me:

<a href="#" class="no-underline text-black flex items-center cursor-pointer font-mono bg-blue-grey-50 block p-1 pl-2 rounded-tl rounded-tr border border-blue-100 border-b"><span class="inline-block text-lg font-bold mr-1 text-grey-800">

^ straight from the Tailwind cheatsheet source code. If this isn't bloat, I don't know what is.

  • Like 2

Share this post


Link to post
Share on other sites
21 hours ago, bernhard said:

So using tailwind you'd get more customized components and less bloat whereas using uikit you'd get all the existing components from start but also get more bloat, is that correct?

Tailwind is utility-first framework. The key difference between something like Uikit and Tailwind is that latter has none of the typical CSS framework components built-in. For an example, here's an example from the docs for creating a "button component":

<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
  Button
</button>

Colors and sizes (such as the "2" in "py-2" etc.) are configurable, so you can have as many or as few of them as you want, and the names can pretty much be whatever you want them to be (py-thon). Either way you're always building your UI using really simple (the word "atomic" comes to mind) rules. While Uikit has some similar utility classes (and so does Bootstrap), Tailwind has a massive number of them, even without counting the pseudo states (bg-blue hover:bg-blue-dark), responsive classes (p-6 md:p-8 lg:p-10), etc.

You can still create your own "custom" components, so that when you add some class – such as "btn" – to an element, you actually get the same thing you would with the rules in the example above. Typically this is done by defining the class in SCSS:

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

.btn:hover {
    @apply bg-blue-700;
}

Technically that this is something you should only do if you really have to repeat the same string of classes multiple times, though 🙂

Personally one thing I've always struggled with "traditional" CSS frameworks are the components they come with. While they often look quite nice, I've almost never had the chance to actually use them as-is (either there's a predefined PSD layout or something like that, or the client demands changes, or the component is just plain bad) and thus I've basically ended up designing my own component library on top of the one provided by the framework. In most of my projects I've only used a framework like Foundation for the grid implementation.

That's where Tailwind comes in:

  • you can build exactly the components you need, BUT 
  • you still get certain benefits of a framework, such as globally defined fonts, colours, spacings, etc.
20 hours ago, dragan said:

^ straight from the Tailwind cheatsheet source code. If this isn't bloat, I don't know what is.

I've struggled with this a bit, and I have to agree that to me personally the utility class approach often looks really ugly, and the shortcut class names etc. are hard to decipher. I'm not yet at the point where I can just glance over an element and instantly see what it is or how it's styled. That being said, I don't really think that this is a major issue for most projects: the size of your HTML is unlikely to become a real bottleneck.

... and if it does, you can always use the extracting components approach mentioned above. Use Tailwind for prototyping, and then convert the combinations you use often to custom components (or custom utility classes) 🙂

  • Like 4

Share this post


Link to post
Share on other sites
On 8/24/2019 at 4:13 PM, dragan said:

define "bloat". In your CSS or HTML? Because this surely looks ugly to me:

I meant bloat in the CSS of all those components that might never get used:

Quote

No more premature abstraction

Taking a component-first approach to CSS means you create components for things even if they will never get reused. This premature abstraction is the source of a lot of bloat and complexity in stylesheets.

---

On 8/24/2019 at 6:56 PM, teppo said:

Tailwind is utility-first framework. The key difference between something like Uikit and Tailwind is that latter has none of the typical CSS framework components built-in. For an example, here's an example from the docs for creating a "button component":

Yeah, thx for the explanation. That's exactly how I understood everything. I like the concept, just need to see which approach fits better to my workflow or project. Maybe I'll use both in the future. I have to try tailwind and report back 🙂 I have two ideas.......

---

4 hours ago, Sergio said:

Good read, thx! 🙂 

Share this post


Link to post
Share on other sites

Just tried tailwindcss as base stylesheet for mpdf 🙂 

<?php
require_once __DIR__ . '/vendor/autoload.php';

$mpdf = new \Mpdf\Mpdf([
  'defaultCssFile' => 'css/prod.css',
  'format' => [190, 236],
  'orientation' => 'L',
  'default_font' => 'arial',
]);
$mpdf->WriteHTML('<h1 class="text-center bg-blue-700 text-yellow-200 mx-64 py-2 font-extrabold text-3xl rounded-full">Hello world!</h1>');
$mpdf->WriteHTML('<svg class="stroke-current text-purple-500 inline-block h-12 w-12" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="8" cy="21" r="2"></circle>
<circle cx="20" cy="21" r="2"></circle>
<path d="M5.67 6H23l-1.68 8.39a2 2 0 0 1-2 1.61H8.75a2 2 0 0 1-2-1.74L5.23 2.74A2 2 0 0 0 3.25 1H1"></path>
</svg>');
$mpdf->WriteHTML('<div class="my-10 bg-red-100 border border-8 border-red-400 text-red-700 px-12 py-3 rounded relative" role="alert" style="border: 1px solid red">
<strong class="font-bold">Holy smokes!</strong>
<span class="block sm:inline">Something seriously bad happened.</span>
<span class="absolute top-0 bottom-0 right-0 px-4 py-3">
  <svg class="fill-current h-6 w-6 text-red-500" role="button" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><title>Close</title><path d="M14.348 14.849a1.2 1.2 0 0 1-1.697 0L10 11.819l-2.651 3.029a1.2 1.2 0 1 1-1.697-1.697l2.758-3.15-2.759-3.152a1.2 1.2 0 1 1 1.697-1.697L10 8.183l2.651-3.031a1.2 1.2 0 1 1 1.697 1.697l-2.758 3.152 2.758 3.15a1.2 1.2 0 0 1 0 1.698z"/></svg>
</span>
</div>');
$mpdf->WriteHTML('<hr class="my-2">');
$mpdf->WriteHTML('<div class="bg-indigo-900 text-center py-4 lg:px-4">
<div class="p-2 bg-indigo-800 items-center text-indigo-100 leading-none lg:rounded-full flex lg:inline-flex" role="alert">
  <span class="flex rounded-full bg-indigo-500 uppercase px-2 py-1 text-xs font-bold mr-3">New</span>
  <span class="font-semibold mr-2 text-left flex-auto">Get the coolest t-shirts from our brand new store</span>
  <svg class="fill-current opacity-75 h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M12.95 10.707l.707-.707L8 4.343 6.586 5.757 10.828 10l-4.242 4.243L8 15.657l4.95-4.95z"/></svg>
</div>
</div>');
$mpdf->WriteHTML('<div class="bg-orange-100 border-l-4 border-orange-500 text-orange-700 p-4" role="alert">
<p class="font-bold">Be Warned</p>
<p>Something not ideal might be happening.</p>
</div>');
$mpdf->WriteHTML('<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-full">
Button
</button>');
$mpdf->WriteHTML('<div class="max-w-sm rounded overflow-hidden shadow-lg">
<img class="w-full" src="/img/card-top.jpg" alt="Sunset in the mountains">
<div class="px-6 py-4">
  <div class="font-bold text-xl mb-2">The Coldest Sunset</div>
  <p class="text-gray-700 text-base">
    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptatibus quia, nulla! Maiores et perferendis eaque, exercitationem praesentium nihil.
  </p>
</div>
<div class="px-6 py-4">
  <span class="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2">#photography</span>
  <span class="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2">#travel</span>
  <span class="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700">#winter</span>
</div>
</div>');
$mpdf->Output();

4vynTyl.png

At least for paddings, margins, text-alignments and colors this could also be helpful. It seems borders do not work - the red border is done manually via "1px solid red" style rule.

Share this post


Link to post
Share on other sites
On 8/24/2019 at 11:23 AM, teppo said:

...I find Tailwind utterly awesome, while the very next moment I can be really frustrated with it...

https://adamwathan.me/css-utility-classes-and-separation-of-concerns/

After reading this article highlighting the utility-first approach, a couple of things popped into my mind:

  • This utility-first approach is mainly for large frameworks and/or for pre-made high-level component libraries where spending the time on all the extra work this approach introduces is worth it.
  • For the frontend of brochure sites and even for classic retail webshops strictly sticking to this approach can be overkill and limiting in terms of "custom design", even though it is supposed to be able to deliver some sort of freedom in customization.
  • If there is only one or two developers working on a not so big website, the advantages of this atomic utility-first approach fade away.

My issues with this atomic style utility-first approach:

- Memorizing the classes takes a lot of time as one has to learn a brand new language, translating a lot, eg:  

  • .flex-no-wrap means flex-wrap: nowrap;
  • .flex-wrap-reverse means flex-wrap: wrap-reverse;
  • .min-h-full means min-height: 100%;
  • .min-h-screen means min-height: 100vh;
  • And the list goes on... One has to spend quite a lot of time using the library in order to learn all this mapping.

- Even though the CSS library is there, one has to start from scratch in terms of implementing "building blocks"/"components" for the site. Not having pre-made high-level components means that there is no help in this regard, it's very much like building the frontend based on SASS/LESS only (except for the utilities out-of-the-box, of course, but still...) 

- The approach of limiting text sizes, colors and similar to a few can be limiting for custom frontend design.

By only using statistics to judge a particular design is short-sighted, I think. The Author lists some stats on popular massive sites out there, listing data like:
Stripe: 189 text colors, 90 background colors, 35 font sizes
purely based on some simple counting of the number of property values being used.

By not knowing why those colors are used, stats do not mean too much, see for example: https://stripe.com/blog/connect-front-end-experience

Being armed with some experience in working with colors one knows that – for example – bright text on dark background looks thinner than dark text on bright background and for this reason the trick of making bright text on dark background just a tiny bit brighter than its counterpart on bright background can be used to make text more readable.

Also, properly matching colors is not always possible by picking colors form a small color palette, as our brain can observe them differently depending on the context. I understand that using hundreds of colors is most probably unnecessary, but relying on a fixed number of a few dozen can be limiting at times.

The Author also states: "I don't think you should build things out of utilities only." and I agree 🙂

For small and mid-range frontend projects I think UIkit 3 is a better choice as it provides high-level components based on low-level ones which can be mixed in lots of clever ways. I usually add the BEM-like approach to my code too, so that any deviation from the otherwise LESS customized UIkit can be applied in a maintainable manner.

  • Like 3

Share this post


Link to post
Share on other sites

Interesting thoughts.

I wonder if anybody has ever tried using purgeCss with uikit and if the results are similarly impressive as when using tailwindcss?

@Tom. any numbers to share?

Quote

The perfect thing would be to combine UIKit and TailwindCSS, but the best way to achieve this is up for grabs. I personally use TailwindCSS base and implement components from UIKit. I then use PurgeCSS on the CSS file to make sure anything unused by either UIKit or Tailwind isn't making it to production. I do this using Parcel JS. I have used Webpack and Gulp previously, but I find Parcel is a simple and easy way to get a project started (and it's fast!).

Parcel.js looks interesting!

Share this post


Link to post
Share on other sites
3 hours ago, szabesz said:

- Memorizing the classes takes a lot of time as one has to learn a brand new language, translating a lot, eg:  

Memorizing classes will always be needed. If you take a pre-build framework or your own classes. The big productivity improvement is not in writing CSS using @apply and tailwind classes, but in writing just html and adding tailwind classes directly to the markup. So you need the backing css to already exist. Once you have to switch to a css file you're already loosing on the productivity gains. If you're using properly separated templates there might even be no need to later move the utilities to custom classes and `@apply` as everything's already in one place - the template of a component.

3 hours ago, szabesz said:

- Even though the CSS library is there, one has to start from scratch in terms of implementing "building blocks"/"components" for the site. Not having pre-made high-level components means that there is no help in this regard, it's very much like building the frontend based on SASS/LESS only (except for the utilities out-of-the-box, of course, but still...) 

Having the utilities out of the box is exactly the selling point of tailwind. Sass/less don't give you classes you can put in your markup - they're pre-processors. It also doesn't want to be a contender to e.g. uikit or bootstrap because they require so much work to be bent to custom design. Building your own components is expected, as custom design most often does require that anyways. There's however some work on a component library being done, which is build on top of tailwinds utility classes; and which will probably be easier to customize than e.g. bootstrap.

If you have your own custom utilities library tailwind probably won't be of much benefit. If not however it' a great way to get started quickly on a existing, well documented, well adopted framework.

3 hours ago, szabesz said:

- The approach of limiting text sizes, colors and similar to a few can be limiting for custom frontend design.
By only using statistics to judge a particular design is short-sighted, I think. 

3 hours ago, szabesz said:

Also, properly matching colors is not always possible by picking colors form a small color palette, as our brain can observe them differently depending on the context. I understand that using hundreds of colors is most probably unnecessary, but relying on a fixed number of a few dozen can be limiting at times.

Tailwind by default comes with 9 shades of each color, where afaik 4 are accessable colors on black and 5 are accessable on white background. And you can still edit them, those are just defaults. The message is not "you should not use more than (those) x colors/shades". The message is that a well managed design system must use a fixed set of colors, which is different to each person on the team just adding a new shade each and every time they add something to their codebase. The latter most often being the reason for the exploding number in color or text-size variations. It's about consistency and less about absolute numbers.

3 hours ago, szabesz said:

For small and mid-range frontend projects I think UIkit 3 is a better choice as it provides high-level components based on low-level ones which can be mixed in lots of clever ways. I usually add the BEM-like approach to my code too, so that any deviation from the otherwise LESS customized UIkit can be applied in a maintainable manner.

Imho the need for all those customization variables of frameworks like uikit/bootstrap and the lock-in to a certain preprocessor already show how "inflexible" those solutions really are. I've not yet used any of those frameworks, where I didn't hit a brick wall at some point trying to skin a component to a custom design, because some aspect of a component wasn't customizable (either markup expectations or missing a "configuration variable"). 

To me tailwind css is neither an alternative to writing css, as the building blocks are way more cohesive and well rounded as well as "higher level" than css 1 – but also not for frameworks, which often impose quite an amount of markup constraints and understandably a certain kind of style, which can be problematic when implementing a custom design.

[1] Take for example .truncate. There's no single css rule for truncating text properly. It's

overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap

Same for e.g. .rounded-t. It applied rounded borders to both top edges, instead of css, which requires you to set it for each edge explicitly.

This is more in line in how a designer would think about a design than how css needs it to be implemented. Nobody will say "make the top left and top right edge rounded". People say "make the top edges round" or "truncate that line". 

  • Like 5
  • Thanks 1

Share this post


Link to post
Share on other sites
3 hours ago, bernhard said:

Interesting thoughts.

I wonder if anybody has ever tried using purgeCss with uikit and if the results are similarly impressive as when using tailwindcss?

@Tom. any numbers to share?

Parcel.js looks interesting!

You can get UIKit purged down to ~25 - 40KB.

  • Like 2

Share this post


Link to post
Share on other sites

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By stanoliver
      My aim is to output a very basic xml document which should be styled with a few css-styles.
      <?xml version = "1.0"?> <contact-info> <name>Donal Duck</name> <company>Superducks</company> <phone>(011) 123-4567</phone> </contact-info> How do I implement it with processwire?
    • By Chris Bennett
      Not sure where I originally saw it while lurking around the forums, but someone, somewhere at some time was asking about styling Uikit checkboxes as toggle-style switches, much like the ones at the bottom of this post asking me if I want to be notified of replies.
      So here is my humble offering, rough and ready,  which can be thrown in at the bottom of your Uikit css as a starting point.
      Everything is based on ems and rems, so you can increase size as you desire by altering the single instance of font-size.
      It only targets single instances of labels within a specific field to a) try to limit unintended consequences and b) because in those cases it often seems more user-friendly to have an on/off binary switch rather than a checkbox. It's still totally a checkbox, just styled differently.
       
      .uk-form-controls-text label:only-of-type input.uk-checkbox { font-size:.8rem; margin-top:0; position:relative; -webkit-appearance:none; outline:none; width:4em; height:2.4em; border:2px solid #D6D6D6; border-radius: 3em; box-shadow:inset 5em 0 0 0 #DDD; flex-shrink: 0; } .uk-form-controls-text label:only-of-type input.uk-checkbox:after { content:""; position:absolute; top:.25em; left:.25em; background:#FFF; width:1.6em; height:1.6em; border-radius:50%; transition:all 250ms ease 20ms; box-shadow:.05em .25em .5em rgba(0,0,0,0.2); } .uk-form-controls-text label:only-of-type input.uk-checkbox:checked { background-color: transparent; box-shadow:inset 5em 0 0 0 #4ed164; border-color:#67bba5; } .uk-form-controls-text label:only-of-type input.uk-checkbox:checked:after { left:1.85em; box-shadow:0 0 1em rgba(0,0,0,0.2); } label:only-of-type input.uk-checkbox:checked + span { color:#008a00; transition:all 250ms ease 20ms; } .InputfieldCheckbox .InputfieldContent label:only-of-type {display:flex;} label:only-of-type input.uk-checkbox + span { color:#c3c3c3; display:flex; align-items:center; line-height:1.1; } /* Below is only necessary if you want the optional "tick" after items when selected */ label:only-of-type input.uk-checkbox + span:after { flex-shrink:0; margin-left:.5em;width:2em; opacity:0; content:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 250 250'%3E%3Ccircle cx='125' cy='125' r='125' fill='%23231F20' opacity='.1'/%3E%3Cpath fill='%230B8B44' d='M95.823 139.432l-32.492-32.56-31.872 31.883-.008-.008 63.72 63.732L218.549 79.116 187.494 47.52z'/%3E%3C/svg%3E"); } label:only-of-type input.uk-checkbox:checked + span:after { opacity:1; transition: opacity 250ms ease 150ms; }  

    • By mjut
      Hello!
      I am trying to get some extra css-file into my admin templates. I managed to modify my admin.php to this:
      <?php namespace ProcessWire; require($config->paths->adminTemplates . 'controller.php'); echo "<link rel='stylesheet' type='text/css' href='" . $config->urls->templates . "css/admin.css'>"; By doing so, the css <link> is added to the very end of each parsed admin-html. (right AFTER the closing </body> tag.)
      That causes some trouble. e.g. the page tree is not displaying any more. Although, other pages are working - like the edit form of a page.
      My question: is there a correct way of adding my extra css to the admin area?
      Thanks for you help!
      Stephan
       
    • By rafaoski
      This profile can be used as a business card or very simple blog.
      Requires the latest version processwire 3.0.101 !!!
      Milligram Site Profile For Processwire 3x with include functions like:
      MarkupRegions
      FunctionsAPI
      wireIncludeFile | wireRenderFile
      Essentially, this structure uses minimalist CSS framework Milligram and the Flexbox Grid System Gridlex
       
      Live Example
      CAN DOWNLOAD FROM THIS LINK ( Basic Version and simple Blog Version )
      https://github.com/rafaoski/site-milligram
      https://github.com/rafaoski/site-milligram-blog
      Screenshot:

      If you want to use Laravel Mix you must first ensure that Node.js and NPM are installed on your machine.
      Basic example to Debian and Ubuntu based Linux distributions:
      Node.js
      curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash - sudo apt-get install -y nodejs
      See more installation options LINK
      npm is installed with Node.js just check in linux terminal like below:
      node -v
      npm -v
      Set BrowserSync inside folder /templates/webpack.mix.js and change your dev url
      proxy: 'http://localhost/mix/', to your installation processwire folder like:
      proxy: 'http://localhost/your-processwire-installation-folder/',
      Next install npm packages in your templates folder with command npm install
      Now, boot up the dev server npm run watch, and you're all set go!
      On completion, use the command npm run production to build styles and scripts in the dist folder
      Simple Usage ( Basic Command )
      Run npm install Watch npm run watch Build npm run production All files to Webpack build steps is inside file ( webpack.mix.js )
      Folder With all SCSS files is inside templates/src/scss
      All build styles and scripts is inside the ( dist ) folder
      References:
      Milligram
      Gridlex
      Laravel Mix
      Feather Icons
      Web Font Loader
      Verlok Lazy Load
      Cookie Consent
      Particles.js
       
       
       
       
    • By matsn0w
      Hey all,
      I am working on a website and I want to style the login page, but I'm a bit confused. 
      I want either the existing login page styled in my own way using some CSS (I guess I prefer that) or I want to create a custom page with a form to login. (Which I could style too).
      I used the code from Ryan and Renobird posted here - which works great - but that doesn't replace the original login page. 
      Is there a way to some sort of 'disable' the original login?
      I hope my question is clear and thanks in advance,
      matsn0w
×
×
  • Create New...