Puzzle Tech Kafi #Frontend
26.08.2020, Mathis Hofer
Vanilla
CSS
Utility CSS Frameworks
Component CSS Frameworks
Full control
From scratch
Quick results
Customize
Write custom styles and classes
Own conventions
No framework
Optional: Preprocessor (LESS, SASS)
Predefined component and utility classes
Use library and add new styles reactively
Quick results
"Everything looks the same"
Heavy theme customizing/CSS overriding
User downloads huge library
No prestyled component classes
Low-level utility classes
Build own components
Create a well thought-out library proactively
Write less (or no) CSS code
Atomic CSS/Functional CSS
TACHYONS
Atomic CSS is the approach to CSS architecture that favors small, single-purpose classes with names based on visual function.
Challenging CSS Best Practices,
Thierry Koblentz (Smashing Magazine, 2013)
Styling via markup
Avoid CSS redundancy
Stop CSS growing
No contextual or descendant selectors
Styles “sandboxed” to attached nodes
Move modules around without losing styles
No dead styles
CSS Bloat ➡️ HTML Bloat
Not about banning “semantic” class names
https://github.com/tailwindlabs/tailwindcss
MIT License
First alpha in 2017
First stable in 2019
Implemented as PostCSS plugin
Directives to be used in CSS files
Breakpoints
Fonts
Color palette
Spacings
Variants
Plugins
Purging
# Create minimal tailwind.config.js
npx tailwindcss init
# Include all defaults
npx tailwindcss init --fullGenerate with CLI:
/* Injects tailwind base styles
& normalize.css */
@tailwind base;
/* Injects tailwind component classes */
@tailwind components;
/* Add custom component classes here */
/* Injects tailwind utility classes */
@tailwind utilities;
/* Add custom utility classes here */npx tailwindcss build styles.css -o output.css*only necessary after CSS changes or configuration modifications
// postcss.config.js
module.exports = {
plugins: [
// ...
require('tailwindcss'),
require('autoprefixer'),
// ...
]
}*
PostCSS plugins:
Autoprefixer
Build-time imports: postcss-import
Nesting: postcss-nested, postcss-nesting
Variables: postcss-custom-properties
Future CSS features: postcss-preset-env
<div class="chat-notification">
<div class="chat-notification-logo-wrapper">
<img class="chat-notification-logo" src="/img/logo.svg" alt="ChitChat Logo">
</div>
<div class="chat-notification-content">
<h4 class="chat-notification-title">ChitChat</h4>
<p class="chat-notification-message">You have a new message!</p>
</div>
</div>.chat-notification {
display: flex;
max-width: 24rem;
margin: 0 auto;
padding: 1.5rem;
border-radius: 0.5rem;
background-color: #fff;
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
}
.chat-notification-logo-wrapper {
flex-shrink: 0;
}
.chat-notification-logo {
height: 3rem;
width: 3rem;
}
.chat-notification-content {
margin-left: 1.5rem;
padding-top: 0.25rem;
}
.chat-notification-title {
color: #1a202c;
font-size: 1.25rem;
line-height: 1.25;
}
.chat-notification-message {
color: #718096;
font-size: 1rem;
line-height: 1.5;
}<div class="max-w-sm mx-auto flex p-6 bg-white rounded-lg shadow-xl">
<div class="flex-shrink-0">
<img class="h-12 w-12" src="/img/logo.svg" alt="ChitChat Logo">
</div>
<div class="ml-6 pt-1">
<h4 class="text-xl text-gray-900 leading-tight">ChitChat</h4>
<p class="text-base text-gray-600 leading-normal">You have a new message!</p>
</div>
</div>Source:
https://github.com/gojutin/tailwindcss-cheatsheet
Pseudo-class variants:
Responsive variants:
hover: focus: active: group-hover: group-focus: focus-within: focus-visible: motion-safe: motion-reduce: disabled: visited: checked: first: last: odd: even:
sm: md: lg: xl:
➡️ Prefix utility classes with variant(s)
➡️ Some combinations are not generated per default!
<button class="bg-blue-400 hover:bg-blue-300">
Pseudo-class
</button>
<button class="md:text-lg xl:text-xl">
Responsive: Font size
</button>
<button class="hidden lg:inline-block">
Responsive: Only visible on large screens
</button>
<button class="lg:hover:bg-red-300">
Combined
</button>Mobile-first breakpoints (min-width)
Customizable in tailwind.config.js
sm
640px
md
768px
lg
1024px
xl
1280px
<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
Button
</button>Problem:
Utility-first != Utility-only
Primary choice:
Don't (avoid premature abstraction)
Secondary choice:
Template partial (backend)
or JavaScript component (frontend)
Tertiary choice:
Component class with @apply directive
<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
Button
</button><button class="btn-blue">
Button
</button>@tailwind base;
@tailwind components;
/* Custom components */
.btn-blue {
@apply bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded;
}
@tailwind utilities;Extracted:
Per default the generated CSS is > 1MB
PurgeCSS strips out unused utility classes
(simple Regex based approach)
// tailwind.config.js
module.exports = {
purge: ['src/**/*.html'],
...
}
# Build without unused classes
NODE_ENV=production tailwindcss \
build styles.css \
-o output.cssFocus: markup/style in one place
Super high quality documentation and screencasts
Lot of traction
How about more complex components (e.g. datepicker)?
Custom component's accessibility
Choose abstractions wisely
Work with JavaScript components/partials
Work with predefined (gradual) spaces/sizes/colors
Background images ➡️ <img>
Design while you write (ideal for prototyping)
Slides:
References:
Challenging CSS Best Practices (Thierry Koblentz, Smashing Magazine)
Let’s Define Exactly What Atomic CSS is (John Polacek, CSS-Tricks)
In Defense of Utility-First CSS (Sarah Dayan, dotCSS 2019)
Why I Don't Like Tailwind CSS (Chris Hawkes)
This work is licensed under a
Creative Commons Attribution 4.0 International License.