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

🇳🇱 React Summit 2023

🇳🇱 React Summit 2023

ℹ️ It's 2023 and I Can Finally Talk About Atomic CSS

Libraries like Tailwind became quite popular and their utility-first—aka atomic classes—approach was an interesting paradigm shift in CSS. Many developers love it, and it's understandable why.

However, we tend to forget that the core of this technique isn't new. Way before Bootstrap, we all had our small CSS snippets copied from project to project with similar classes.

In this session, we'll discuss the evolution of scalable CSS, walk through the limitations and drawbacks of Atomic CSS, and also figure out where this concept can be beneficial.

Matheus Albuquerque

June 06, 2023
Tweet

More Decks by Matheus Albuquerque

Other Decks in Programming

Transcript

  1. Hello, React Summit 👋 🇳🇱 IT'S 2023 AND I CAN

    FINALLY TALK ABOUT ATOMIC CSS • THE 6TH OF JUNE, 2023.
  2. IT'S 2023 AND I CAN FINALLY TALK ABOUT ATOMIC CSS

    ↑ ALL THE LINKS! 🤓 🧑🏫 @techlabs 🐦 @ythecombinator 👨💻 @medallia ⚡ Perf GDE
  3. This talk presents… ↝ Problems of CSS at scale ↝

    The Bad (takes) ↝ The Bad ↝ The Ugly ↝ The Good (Way) ↝ Closing Thoughts
  4. Problems of CSS at scale IT'S 2023 AND I CAN

    FINALLY TALK ABOUT ATOMIC CSS
  5. Lack of Namespaces ↝ GLOBAL NAMESPACE WAS DESIGNED AS CORE

    FEATURE OF CSS TO ENABLE PORTABILITY AND CASCADING ↝ ANY PROGRAMMING LANGUAGES LACKING BUILT-IN NAMESPACES WILL HAVE PROBLEMS AT SCALE ↝ OPTIONS LIKE CSS-IN-JS FIXED THAT WITH BUILD TOOLS THAT CAN INTERCEPT AND GENERATE SCOPES AUTOMATICALLY
  6. Stuck With the Past ↝ MAINTAINING BACKWARD COMPATIBILITY IS A

    TOP PRIORITY WHEN DESIGNING NEW FEATURES ↝ IT'S NOT ALWAYS FEASIBLE TO COMPLETELY ABANDON BAD DECISIONS MADE IN THE PAST ↝ ADOPTION RATE AND BROWSER SUPPORT MUST BE TAKEN INTO ACCOUNT WHEN MAKING CHANGES TO THE LANGUAGE
  7. Unpredictable to Humans ↝ CSS MERGES STYLES FROM MULTIPLE SOURCES

    AND ORIGINS (IE. INLINE STYLES, INTERNAL AND EXTERNAL STYLESHEETS, DIFFERENT SELECTORS, ETC.) ↝ THIS INVOLVES SPECIFICITY CALCULATIONS, INHERITANCE, AND OTHERS, MAKING IT QUITE COMPLEX ↝ IT’S HARD FOR HUMANS TO PREDICT HOW STYLES WILL BE RESOLVED
  8. Static ↝ STILL PRIMARILY A SET OF STATIC LAYOUT RULES,

    WITH LIMITED SUPPORT FOR DYNAMIC AND VARIABLE STYLING ↝ STILL STRUGGLES TO KEEP UP WITH THE DEMANDS OF DYNAMIC WEB PAGES ↝ THEMING AND DYNAMIC CHANGES BASED ON INCOMING DATA FROM JAVASCRIPT CAN BE CHALLENGING
  9. “What About… Inline Styles?” ↝ SURPRISINGLY COSTLY FOR THE BROWSER

    ↝ CAN'T HANDLE MEDIA QUERIES OR PSEUDO SELECTORS ↝ YOU DON’T HAVE TO FOLLOW ANY PRE-EXISTING DEFINITION ↝ UTILITY CLASSES EXPOSE A WELL-DEFINED API AND A SINGLE SOURCE OF TRUTH
  10. “What About… the HTML Bloat?” ↝ THE DEFLATE ALGORITHM (GZIP)

    CAN HANDLE DUPLICATE STRINGS ↝ THE MORE A SELECTOR IS REPEATED IN A STYLESHEET, THE MORE WORK THE BROWSER HAS TO DO TO RESOLVE ALL STYLES
  11. “What About… SoC?” ↝ STYLE COMPOSITION IS PERFORMED IN THE

    HTML, BUT NOT USING style OR align ATTRIBUTES ↝ PIECES ARE ASSEMBLED FROM A STYLESHEET WRITTEN IN CSS AND HTML BECOMES A CONSUMER OF A CSS ↝ EXTREME VISION OF “SEPARATION OF CONCERNS” ↝ DEEPLY IMPRACTICAL (DOGMATIC LEVEL)
  12. “What About…?” ↝ "REDESIGNING/THEMING BECOMES CHALLENGING” ↝ "IT RESULTS IN

    A LOT OF UNUSED CSS" ↝ "IT’S HARD TO KNOW WHAT’S AVAILABLE TO USE” ↝ A WHOLE OTHER LANGUAGE TO LEARN ON TOP OF CSS ↝ …
  13. “What About…?” ↝ "REDESIGNING/THEMING BECOMES CHALLENGING” ↝ "IT RESULTS IN

    A LOT OF UNUSED CSS" ↝ "IT’S HARD TO KNOW WHAT’S AVAILABLE TO USE” ↝ A WHOLE OTHER LANGUAGE TO LEARN ON TOP OF CSS ↝ …
  14. Tailwind has the potential to alleviate some of the concerns

    outlined for atomic CSS and provides intriguing new benefits.
  15. I often see a popular belief that Tailwind is the

    future of web development, and that it represents the correct way to do things.
  16. Semantic HTML/CSS ⇢ Tailwind ↝ BREAK “COMPOUND” SEMANTIC CLASSES INTO

    “ATOMIC” UTILITY CLASSES WITH SINGLE RESPONSIBILITIES ↝ A FAIRLY EASY THING TO DO
  17. Tailwind ⇢ Semantic HTML/CSS ↝ IT’S HARD TO PICTURE A

    TOOL THAT DOES THE REVERSE ↝ YOU CAN’T REALLY BUILD MORE COMPLEX WITHOUT ASSEMBLING THOSE CLASSES BY HAND ↝ YOU COULD ONLY REALISTICALLY CONVERT TAILWIND INTO SOME OTHER UTILITY FRAMEWORK
  18. Utility CSS Lock-in ↝ MOVING TO ANY OTHER FRAMEWORK OR

    PREPROCESSOR REQUIRES A CONSIDERABLE AMOUNT OF REFACTORING ↝ MOST OF US AREN’T SWAPPING OUT CSS FRAMEWORKS ON PROJECTS ON A REGULAR BASIS ↝ BUT IT’S AN IMPORTANT CONSIDERATION FOR APPS THAT YOU’LL BE MAINTAINING IN THE FUTURE
  19. Missing Key CSS Features ↝ BACKGROUND GRADIENTS; ↝ ANIMATIONS; ↝

    NEW SELECTORS (:is AND :where) ↝ NEW FUNCTIONS (min(), max(), AND clamp()) ↝ OTHER BLEEDING-EDGE FEATURES
  20. Class Detection ↝ TAILWIND DOESN'T PARSE OR EXECUTE ANY OF

    THE CODE ↝ IT USES REGULAR EXPRESSIONS TO EXTRACT EVERY STRING THAT COULD POSSIBLY BE A CLASS NAME ↝ IT WILL ONLY FIND CLASSES THAT EXIST AS COMPLETE UNBROKEN STRINGS ↝ YOU CAN'T CONSTRUCT CLASS NAMES DYNAMICALLY
  21. Hard to Scan <div className="w-16 h-16 rounded text-white bg-black py-1

    px-2 m-1 text-sm md:w-32 md:h-32 md:rounded-md md:text-base lg:w-48 lg:h-48 lg:rounded-lg lg:text-lg"/>
  22. Hard to Scan .class { width: 16px; height: 16px; color:

    white; background-color: black; padding: 0.25rem 0.5rem; margin: 0.25rem; border-radius: 0.25rem; font-size: 0.875rem; line-height: 1.25rem; } @media screen and (min-width: 768px) { .class { width: 32px; height: 32px; border-radius: 0.375rem; font-size: 1rem; line-height: 1.5rem; } } @media screen and (min-width: 1024px) { .class { width: 48px; height: 48px; border-radius: 0.5rem; font-size: 1.125rem; line-height: 1.75rem; } }
  23. Hard to Scan .class { width: 16px; height: 16px; color:

    white; background-color: black; padding: 0.25rem 0.5rem; margin: 0.25rem; border-radius: 0.25rem; font-size: 0.875rem; line-height: 1.25rem; } @media screen and (min-width: 768px) { .class { width: 32px; height: 32px; border-radius: 0.375rem; font-size: 1rem; line-height: 1.5rem; } } @media screen and (min-width: 1024px) { .class { width: 48px; height: 48px; border-radius: 0.5rem; font-size: 1.125rem; line-height: 1.75rem; } }
  24. Hard to Scan ↝ IT'S SIMPLER TO SCAN IF YOU

    ONLY NEED TO READ YOUR CODE FROM TOP TO BOTTOM ↝ IT'S EASIER TO FIND SPECIFIC PROPERTY-VALUE PAIRS ↝ PROPER SYNTAX HIGHLIGHTING SEPARATES PROPERTIES FROM VALUES AND ENHANCES READABILITY
  25. Encouraged Tag Soup ↝ THE FOCUS IS ON THE CLASSES,

    NOT THE MARKUP ↝ TAILWINDCSS DOESN’T PROMOTE “UGLY HTML” AT ALL ↝ BUT YOU CAN THROW IN AS MANY <div> AS YOU WANT WITHOUT CARING ABOUT MEANING ↝ YOU CAN DO IT THE RIGHT WAY, BUT ERGONOMICS LEAN DEEP DOM
  26. #hotTake 🌶 The problem lies in thinking in CSS classes

    first, rather than starting with markup and working the CSS from there.
  27. #hotTake 🌶 Tools can make it easy to do certain

    things the wrong way. Their approach makes poor semantics the easiest path.
  28. IT'S 2023 AND I CAN FINALLY TALK ABOUT ATOMIC CSS

    #3 DEVELOPER (TOOLS) EXPERIENCE
  29. Hard To Find Components ↝ WHEN TROUBLESHOOTING IN A LARGE

    CODE BASE, NARROWING DOWN THE AFFECTED COMPONENT IS IMPORTANT ↝ HAVING A CLOSE MAPPING BETWEEN A COMPONENT’S NAME AND ITS CLASS NAMES MAKES IT EASIER TO FIND THE RELEVANT CODE QUICKLY ↝ HERE, WE HAVE TWO OPTIONS: KNOWLEDGE OF THE PARTICULAR AREA OF THE APP AND STRINGS
  30. Hard To Find Components ↝ NOT EVERYONE ON A TEAM

    MAY BE FAMILIAR WITH EVERY COMPONENT IN THE CODE BASE (ENTERPRISE-SCALE MONOREPOS, NEW HIRES, ETC.) ↝ STRINGS MAY GET REUSED ACROSS MULTIPLE COMPONENTS = SEARCHING MAY YIELD MULTIPLE RESULTS ↝ IT’S HARD TO DETERMINE WHERE A MODULE STARTS AND ENDS
  31. Hard to Tweak CSS ↝ MAKING STYLE TWEAKS THROUGH DEV

    TOOLS IN THE BROWSER IS A COMMON PRACTICE ↝ HERE, YOU NEED TO GIVE EACH COMPONENT A NEW CLASS NAME AND USE THAT AS THE SELECTOR ↝ …OR USE INLINE STYLES, BUT SOMETIMES IT'S HELPFUL TO SEE HOW CHANGES ARE REFLECTED THROUGHOUT THE UI
  32. @for $i from 1 through 10 { .m-#{$i} { margin:

    $i / 4 rem; } } On-Demand Generation [BEFORE]
  33. @for $i from 1 through 10 { .m-#{$i} { margin:

    $i / 4 rem; } } .m-1 { margin: 0.25 rem; } .m-2 { margin: 0.5 rem; } / * . . . * / .m-10 { margin: 2.5 rem; } On-Demand Generation [BEFORE]
  34. On-Demand Generation [AFTER] CSS YOU ARE USING CSS SHIPPED (PROD

    / DEV) CSS GENERATED ON DEMAND SCAN GENERATE SHIP
  35. Beware of @apply NEGATES BENEFITS GAINED OVER TRADITIONAL COMPONENT- DRIVEN

    CSS: ↝ THE EXPLICITNESS OF THE CLASS NAME ↝ THE TIME SAVED BY NOT HAVING TO WRITE YOUR OWN CSS ↝ THE SINGLE SOURCE OF TRUTH
  36. Beware of @apply ↝ EXTREMELY DESTRUCTIVE POTENTIAL ↝ E.G. USE

    FUNCTIONAL CLASSES AS AN ESCAPE HATCH TO UNDO COMPONENT RULES ↝ STRIVE TO BE EXTREMELY STRICT WITH THE APPLICATION OF BOTH SO THAT THEY DO NOT INTERSECT OR SHARE CONCERNS
  37. StyleSheet Composition [SIMPLE] import { clsx, type ClassValue } from

    "clsx" import { twMerge } from "tailwind-merge" export function classnames(…inputs: ClassValue[]) { return twMerge(clsx(inputs)) }
  38. const Input = ({ className, . . . props })

    = > { return <input className={classnames(' . . . ', className)} { . . . props} />; }; import { clsx, type ClassValue } from "clsx" import { twMerge } from "tailwind-merge" export function classnames(…inputs: ClassValue[]) { return twMerge(clsx(inputs)) } StyleSheet Composition [SIMPLE]
  39. const buttonVariants = cva( ' . . . ', {

    variants: { intent: { primary: 'bg-green-500 hover:bg-green-600', secondary: 'bg-red-500 hover:bg-red-600', default: 'bg-gray-500 hover:bg-gray-600', }, size: { small: ['text-sm', 'py-1', 'px-2'], medium: ['text-base', 'py-2', 'px-4'], large: ['text-lg', 'py-4', 'px-8'], }, roundness: { square: 'rounded-none', round: 'rounded-md', pill: 'rounded-full', }, }, defaultVariants: { intent: 'default', size: 'medium', roundness: 'round', }, } ); StyleSheet Composition [COMPLEX]
  40. intent: { primary: 'bg-green-500 hover:bg-green-600', secondary: 'bg-red-500 hover:bg-red-600', default: 'bg-gray-500

    hover:bg-gray-600', } size: { small: ['text-sm', 'py-1', 'px-2'], medium: ['text-base', 'py-2', 'px-4'], large: ['text-lg', 'py-4', 'px-8'], } roundness: { square: 'rounded-none', round: 'rounded-md', pill: 'rounded-full', } StyleSheet Composition [COMPLEX]
  41. StyleSheet Composition [COMPLEX] export default function Button({ intent, size, roundness,

    children }) { return ( <button className={buttonVariants({ intent, size, roundness })}>{children}</button> ) }
  42. Accessibility ↝ BUILD PROCESS: CATCH ERRORS AS YOU BUILD OUT

    THE APP (AXE-CORE, JSX-A11Y, LIGHTHOUSE AUDITS, ACCESSLINT.JS) ↝ CONTINUOUS INTEGRATION: FIND ISSUES IN YOUR PULL REQUESTS (AXE-LINTER OR ACCESSLINT) ↝ SIMULATE IMPAIRMENTS: USE TOOLS TO SIMULATE COLOR BLINDNESS, LOW VISION, ZOOM, LOW CONTRAST…
  43. #hotTake 🌶 It allows us to write our styles in

    a familiar “monolithic” way, but get Atomic CSS out. — THE SHORTHAND-LONGHAND PROBLEM IN ATOMIC CSS, BY ROBIN WESER
  44. Atomic CSS-in-JS ↝ NO NEED FOR A SPECIFIC CLASS NAMING

    CONVENTION ↝ TREATS COMMON AND ONE-OFF STYLES ON AN EQUAL BASIS ↝ EXTRACTS CRITICAL CSS FROM A PAGE AND ENABLES CODE-SPLITTING ↝ RESOLVES CSS RULES INSERTION ORDER ISSUES IN JAVASCRIPT
  45. IT'S 2023 AND I CAN FINALLY TALK ABOUT ATOMIC CSS

    #1 IT’S JUST A TOOL BUT THE RIGHT TOOL™ CAN MAKE A HUGE DIFFERENCE
  46. IT'S 2023 AND I CAN FINALLY TALK ABOUT ATOMIC CSS

    #2 THE SOLUTION TO THE PROBLEM ONLY CHANGES THE PROBLEM
  47. IT'S 2023 AND I CAN FINALLY TALK ABOUT ATOMIC CSS

    #2 THE SOLUTION TO THE PROBLEM ONLY CHANGES THE PROBLEM TRADE-OFFS TRADE-OFFS TRADE-OFFS
  48. IT'S 2023 AND I CAN FINALLY TALK ABOUT ATOMIC CSS

    #3 UTILITY CLASSES CAN COEXIST WITH OTHER APPROACHES THE SWEET SPOT FOR YOU MIGHT BE A HYBRID OF DIFFERENT CONVENTIONS
  49. IT'S 2023 AND I CAN FINALLY TALK ABOUT ATOMIC CSS

    #4 TAILWIND SUFFERS FROM THINKING IT APPLIES TO ALL PROJECTS
  50. IT'S 2023 AND I CAN FINALLY TALK ABOUT ATOMIC CSS

    #5 JSX CREATED A SIMILAR FEELING AMONG DEVELOPERS WORLDWIDE …IT WAS GOING AGAINST SO MANY BEST PRACTICES THAT IT COULDN'T BE CONSIDERED A GOOD IDEA
  51. IT'S 2023 AND I CAN FINALLY TALK ABOUT ATOMIC CSS

    #6 THERE’S AN EMOTIONAL FACET TO DEVELOPERS’ TECH CHOICES THIS SCORCHING PASSION IS USUALLY WHAT’S CALLED TEAM IDENTIFICATION IN PSYCHOLOGY
  52. THAT’S ALL, FOLKS! THANKS! 👋 🇳🇱 QUESTIONS? MATHEUS ALBUQUERQUE •

    @ythecombinator ↑ ALL THE LINKS! 🤓 IT'S 2023 AND I CAN FINALLY TALK ABOUT ATOMIC CSS