
CSS Utility Classes and “Separation of Concerns” (2017) - aarondf
https://adamwathan.me/css-utility-classes-and-separation-of-concerns/
======
ehnto
I use a method called Context and Components. The idea being to build
components, and to modify those components if they need to change base on
context.

If I need to change the product card on my site it is at component/product-
card.scss. If I want it to be different on thr homepage I change it at
context/home-page.scss and I targetit with .home-page .product-card. Simple
stuff, no inheritance issues either.

From my experience, reusable CSS is somewhat of a red herring. Maintainable
and easily located CSS is where you get productivity gains. If you don't know
what you have because there are hundreds of utility classes then what good is
it.

Also, if you are using utility classes why not just inline CSS? "red-border
white-background pad-20" is just as bad.

I wrote an article explaining the method here:
[https://polylab.co/articles/ccm-contexts-and-components-
css....](https://polylab.co/articles/ccm-contexts-and-components-css.html)

~~~
karaterobot
I didn't know there was a name for this method, but it's what I've settled on
as well: Namespace the classes by their component's class name, and then
override them, if necessary, in another namespaced context. It's pretty
simple, as safe as can be expected, and works well for sites of all sizes.

The only bullet you have to bite is occasionally repeating yourself, but as
you say, that part of CSS never really worked well anyway.

If using a pre-processor like Stylus or Sass, you can get a lot of
composability with mixins and extensions, if that's what you want, and these
can even be cleaner and more flexible than utility classes, because they can
use parameters and basic logic.

~~~
ehnto
> I didn't know there was a name for this method

I just made that one up when I started formalizing the method!

> The only bullet you have to bite is occasionally repeating yourself, but as
> you say, that part of CSS never really worked well anyway.

I find as well that if you write clean, concise CSS that doesn't have to
override anything you get away with far less CSS anyway. So repeating yourself
isn't so bad. Similarly, in a project of any longevity, especially if clients
are involved, chances are pretty high the things you repeated will eventually
diverge. So had you made it DRY you would have to de-compose the coupled
components and write it again anyway. With the Contexts, you can make most
diverging modifications without ever touching the components, and I feel any
more levels of inheritance than that leads to CSS that is more complex than it
needs to be.

------
Andrex
The money quote for me:

"The reason I call the approach I take to CSS utility-first is because I try
to build everything I can out of utilities, and only extract repeating
patterns as they emerge."

I've been puzzling over the same "Separation of Concerns vs. Mixing Concerns"
dichotomy ever since the rise of Bootstrap. Something about using Bootstrap's
classes never felt right to me, but I was never happy with the amount of
duplication in my traditional CSS either... I eventually settled on BEM, but
that didn't 100% solve the issues either, and it seems to be getting left
behind as the ecosystem gets older.

The idea of starting with the Bootstrap-like functional CSS, and then
compositing repeated patterns into components, definitely seems to have
tremendous upsides... Looking forward to trying this methodology out in a
future project.

~~~
inopinatus
Two decades ago I was overjoyed to discover that Scheme was finally going to
have a useful application beyond illustrating SICP and writing koans to amuse
myself, because DSSSL was on the cusp of evolving into the last document
styling language anyone would ever need.

Unfortunately following an incident with a broken Lisp machine, a liquid
lunch, and an unlicensed particle accelerator, I became trapped in a parallel
universe where the HTML ERB anointed CSS by mistake during a drunken night out
in Oslo.

The fundamental concept of CSS (best revealed by H.W.Lie's thesis IMO[1]) was
to create a rich and versatile and non-Turing-complete set of structural
selectors in lieu of DSSSL's recursive logic, and to allow styles to overlay
one another; two design choices that only by the application of gallons of
irony can explain why most web pages are composed of a bunch of nested DIV
elements with hashed IDs and overloaded semantic class attributes, and
everyone compiles their assets into a static file.

I switched to Tailwind CSS months ago. Adam Wathan is the hero we deserve.

[1]
[https://www.wiumlie.no/2006/phd/css.pdf](https://www.wiumlie.no/2006/phd/css.pdf)

~~~
tannhaeuser
As an aside, XSLT 1.0, based on DSSSL and created by its author (as is groff
and SP SGML), is 20 years old to the date.

------
ken
The fundamental problem I see is that CSS is far too weak for proper
separation of concerns. You can't make a nice structure in HTML, and then
style it with CSS. You have to structure your HTML from the start in a way
that it's feasible to style it with CSS.

(That's why every CSS question on Stack Overflow has an answer that says "use
this HTML: ... and this CSS: ...". It's rarely possible to use some random
HTML and style it in an arbitrary way.)

The CSS designers decided to pick a purely declarative stylesheet language,
which is a cool idea and has some interesting properties. One of the things
you sacrifice with this decision, though, is the ability to structure the HTML
as you wish. You've got two languages you need to play with, and you've got to
tweak them in concert.

There's an alternate universe where they chose to use JavaScript as the
styling language. The style layer runs in its own sandbox completely separate
from any other JS on your page, and all it does is accept HTML trees and lay
out and style them. You can structure your HTML in any way you want, and then
write 3 lines of JS to style it any way you want. You can implement TeX-style
word wrapping or media queries as a library. Your designers don't have to talk
to your programmers when they change something, because the HTML is generic
from the start.

~~~
sonofhans
I agree with you that CSS is weak, especially from today's POV, and that HTML
& CSS can be unwieldy together. Also that "It's rarely possible to use some
random HTML and style it in an arbitrary way."

However it's not true that "can't make a nice structure in HTML, and then
style it with CSS." That is one of the design goals of CSS, and it works.

In a former life I did this for many years, with many CMS and front-end
systems. In a well-structured Drupal or Wordpress site, for instance, you can
link to one additional stylesheet and override any aspect of the design. Some
of the CSS might be ugly, and every now and then you might need the HTML
tweaked to add a class, but it works.

Check out [[http://www.csszengarden.com](http://www.csszengarden.com)]. This
is an old site, nearly 20 years old, put up by designer Dave Shea precisely to
disprove your point :) It sports hundreds of interesting designs with non-
trivial layouts, really pushing the boundaries of what was possible back in
the day. All of the designs are CSS-only, and hang off the same HTML skeleton.
If you view the source, it's pretty simple.

Doing this with JavaScript introduces all sorts of other concerns:
accessibility, security, privacy, maintainability, future-proofness, compute
necessary to render, render time, etc. jQuery did basically this, right?
Selecting markup and content with CSS syntax to munge them, or attach
triggers.

I rarely see people write vanilla CSS these days. Most folks abstract it with
SCSS or LESS. That removes a lot of the warts. It's still too easy to end up
with 5000 lines of CSS that can only be tested by manual inspection :/

~~~
ellyagg
You can re-style arbitrary (or well-designed) HTML in lots of different and
cool ways with CSS. But you can't re-style it to the new particular design
that management wants.

And even if I'm wrong, the last decade has proven that your regular above-
average developer can't typically do it, and that amounts to the same thing.

------
XCSme
> Isn't this just inline styles?

Yes it is.

I personally don't like the end result, where by "separating the concerns" you
end up hardcoding your style in the HTML markup. For me the utility classes
are just exposing the CSS rules to the HTML markup, which I think is actually
the opposite of separation of concerns because I when I think of "separate" I
think the most of writing code in two different files.

> The amazing thing about this is that before you know it, you can build
> entirely new UI components without writing any new CSS.

So, if you want a responsive/mobile version you would have to either serve a
different HTML for mobile or also have all the CSS rules for mobile in the
inline class names. Before you know, you have a list of 30 cryptic CSS classes
written inside the HTML markup for an element.

> How many times have you needed to style some HTML and thought, "this text
> needs to be a little darker," then reached for the darken() function to
> tweak some base $text-color?

Well, why not just use $text-color--darker? Define your swatches globally
beforehand and do not allow the creation of new colors anyhwere else in the
code. I guess his solution is similar, but with using another CSS class
instead of a variable.

Also, what if at some point you decide to redesign your site and change the
margin of all text? So you would have to replace all "mar-6" with "mar-12",
but only where the margin is for text. This looks like a complex update
invloving a lot of bug-prone search and replace. If it was written as ".text-
margin { margin: 6px; }" then it was just a matter of changing one number and
you know it would only affect the text-related margin. Sharing style across
components is not always a good thing, it makes changing things much harder. I
guess with this approach you should never change the initial values, as the
entire design might be affected in weird ways.

I am not saying this is completely bad, I am just saying there's no perfect
way of doing things and everyone and every project is different.

~~~
kristiandupont
In addition to meeritas point about pseudo classes and media queries, I'd add
that the fact that it narrows down the space is an important factor. The
classes mean that I need to find the best fit rather than spend hours matching
pixels by hand. It's like going from drawing charts on blank paper to grid
paper. You stay within certain boundaries. It seems like a detail but I find
that in practice (and in fairness, I've only been using Tailwind a bit so
far), this makes a significant difference to the way I think and work with UI.

~~~
bstasse
This is the equivalent of predefined variables (usable in any preprocessor and
now even in plain CSS), nothing specific about Tailwind here. Except for the
fact that in the case of Tailwind they are tied to properties, but they are
defined globally under the hood, so this doesn't change anything.

------
listenallyall
(Article is from 2017). TailwindCSS is a terrific library.

One area that wasn't covered was the ease of creating truly responsive
layouts, inline, by defining different utility classes to the same elements
based on screen size. "Responsive" is so much more than just the placement --
quite often, mobile version needs different font sizes, overflow behavior,
thinner margins (since there is less screen space), etc. Very easy to do with
the utility approach.

~~~
james_s_tayler
I find Bulma strikes the right balance in this regard. It feels like
bootstrap, only much cleaner, but then it also has these nice responsive
classes you can apply. It makes it very, very easy work with.

------
thinkloop
The real issue with css is that there is an enormous amount of code re-use
while at the same time almost no code-reuse at all. The author's example
highlights this perfectly: he has a "media-card" representing both the
"author-bio" and "article-preview" but the "author-bio", in this case, needs
to be slightly different. This, to me, is the quintessential css problem.

Almost nothing in css is identical, but almost everything is similar.

This becomes especially true as you move up the complexity spectrum. Primitive
things can be identical (fonts, colors, input boxes, etc.), but the real
higher-order actual components like pages, forms, sections rarely are. In
fact, the little differences, tweaks and custom-tailoring that are manually
applied based on context are what separate professional design from robotic
enterprise-style Frankenstein design.

I think the answer is that you need both semantic css and utility css. Utility
css is used to define the rigid primitives that make up the general design
language, while semantic css provides the hooks and separation needed to be
able to uniquely compose those primitives into custom higher-order components.

So to answer the author's question regarding how to model "author-bio" and
"article-preview", I would personally keep their separate semantic titles, but
style them using common utility primitives classes and custom css within the
css.

~~~
kian
In programming, this problem would be solved with something like higher order
functions or parametric data types, allowing us to both abstract out the
commonalities and maintain incredibly specific, easily modifiable, highly
customized functionality. Is there an analog in the CSS world?

~~~
chrisweekly
There doesn't need to be, given CSS-in-JS!

~~~
koboll
It's wild to me that most of the discourse around CSS-in-JS is about personal
preference for how separation of concerns should be when its biggest advantage
is totally orthogonal to that--it almost completely solves the issues of
scope, specificity, and mapping styles to markup that so many different
libraries and methodologies have been invented to cope with over the years.

~~~
chrisweekly
upvoted and agreed

------
beizhia
From my experience, using utility classes like this just means that you'll
have a lot of messy overriding to do when your reusable components need to
look different in different places.

Personally I think visual consistency is important and you shouldn't make
things look different in different places, but it's not always up to me.

~~~
csande17
At least React's "pass an object to the `style` prop" makes it relatively easy
to do that overriding.

With utility classes, your code has no way of knowing that "bg-red" should
override "bg-blue". (And frequently it won't, if "bg-blue" happens to come
later in the CSS file.) So people end up inner-plaforming their own clunky
solutions on top.

~~~
mxstbr
You would be surprised how many people do not know that the order of classes
in the source file, not the class="" attribute, matters.

See my (totally unscientific, yet scary) poll of my audience, which heavily
leans towards frontend with a focus on React:
[https://mobile.twitter.com/mxstbr/status/1038073603311448064...](https://mobile.twitter.com/mxstbr/status/1038073603311448064?lang=en)

Only 43% got it correct!

~~~
jeltz
If you do not know basic stuff like that how can you even write CSS at all?
Trial and error?

~~~
Izkata
From experience with co-workers: Yep, and lots of !important

------
whytaka
As a designer, the only thing that's important for me in managing CSS is
isolation of styles. I apply a reset at the top to make everything as minimal
as possible and then apply styling to each element and the naming convention
would be such that it applies pretty much only to that element (or only that
and its children if I'm being lazy).

If the markup changes, the CSS changes. The nested SCSS should closely mirror
the DOM.

I can only imagine utility classes will simply create many problems with
naming down the road. I would hate to have to deal with all that.

~~~
IggleSniggle
I can definitely see the advantages! But don't you find yourself writing the
exact same CSS hundreds or even thousands of times with this approach?

~~~
whytaka
Yes and if anything I think I spoke too strongly. I do use classes that
encompass a broader pattern, but they definitely don't go as far as "text-
right", but perhaps something like, "card" for card based layouts.

------
adamwathan
Author here — a common question I’ve seen in the comments that I didn’t cover
in the article is how you do responsive design with this approach.

Here’s a link to the responsive design guide in the Tailwind CSS docs that
covers it in detail:

[https://tailwindcss.com/docs/responsive-
design](https://tailwindcss.com/docs/responsive-design)

The TL;DR is you have breakpoint-specific versions of your utilities, so you
can define all of your responsive behaviour directly in your markup.

For example this element would be `block` by default (on mobile) and `flex`
when the browser is at or above some defined “medium” breakpoint:

<div class=“block md:flex”>

Two years after writing that article I can say CSS definitely feels “solved”
to me, and every time I have to go back to an old Tailwind project it’s very
easy to make changes.

If you’re building things with React, I’d also encourage you to explore
projects like Emotion and Theme UI which allow you to work with the same
philosophical approach (styling elements directly instead of through “hooks”
and some separate style layer) but with a bunch of neat advantages that aren’t
possible with a regular class/CSS-based API, like having better control over
how style definitions override each other when applied to the same element.

Personally I’m still very happy using Tailwind even in React projects, because
the syntax is more terse and it’s nice to have a singular styling paradigm
that I can use even outside React projects.

~~~
38932ur98u
Thanks for the fantastic library! I've really enjoyed using it and it has sped
up dev time phenomenally. However, I am curious: what is it like using
tailwind on huge projects? I can imagine with many developers working on a
codebase the "extract repeated patterns to their own new class" philosophy can
get easily ignored, or difficult to track where some series of classes is
being repeated.

------
cdirkx
I think utility classes _first_, and not utility classes _only_, is a
reasonable approach. My purist mind would prefer something like semantic
classes as a sort of 'public', 'HTML-facing' API, implemented using 'private'
utility mixins, keeping the separation of concerns. But in practice, I know I
have wasted a lot of time thinking about class hierarcies and separating
components, especially when the design is nowhere finalized and I just want a
4px padding.

------
csande17
I think the utility-based approach overlooks an important point: semantic
class names are useful for a lot of things besides writing your styles.

"Codeless tracking" systems let you put in the CSS selector for a button and
find out how many people clicked on it. UI test automation tools let you
specify the CSS selector of an element to click on. User stylesheets let
people make tweaks to your site if they have accessibility, usability, or
aesthetic concerns.

If all your elements have class names like "mt-2 bg-black font-semibold text-
white pt-2 pb-3 flex justify-left", you're making it a lot harder for you,
your users, and your co-workers to take advantage of this ecosystem. At the
very least, you might want to consider _also_ putting semantic classes on your
elements.

~~~
1_player
Nothing stops you from adding a semantic class name or ID to a tag for easy
reference.

~~~
csande17
Right, but it goes from being something you get for free to being something
you have to go out of your way to do. Which can matter, especially on projects
where you're designing a site/theme to hand off to someone less technical.

~~~
tln
I've found that using the same class name for styling and attaching behaviors
to be dangerous... refactor the styling and lose the functionality, or break
the tests, or disable the analytics.

I'm glad that backbone and jQuery apps are in my rear view mirror at this
point.

~~~
frenchy
The reason why you're finding this dangerous is because you've coupled your
class names too closely with your style. Class names should describe what the
content is about, and so if the class names change, that implies that the
content itself is different.

------
bouchardm
I never liked to do CSS, but I must admit with the library this guy released
(tailwindcss), it's really fun :)

------
contravariant
>What if we wanted to change how the author bio looked without changing how
the article preview looks?

>Before, we could just open up our stylesheet and choose new styles for either
of the two components. Now we'd need to edit the HTML! Blasphemy!

The reason you can't is because the markup declares two things to be
equivalent, obviously then CSS can't tell them apart. You're not mixing
concerns you're lamenting the fact that CSS can't be concerned with markup.

Throwing separation of concerns overboard and making HTML concerned with
styling doesn't seem the best resolution.

------
martinbooth
There are lots of positive comments in this thread in support of this approach
and I think it's great when anyone challenges the status quo.

It is more common these days than it was for websites to support multiple
styles/layouts. Whether that's because they're responsive or because they
allow you to enable dark mode or because they support rtl layouts. Class names
such as text-dark-soft or align-right will be misleading if text-dark-soft
ends up closer to white and align-right is left aligned as a website is
evolved to support these features.

Not a criticism of this approach; this is easily fixed by using names such as
text-emphasized-soft or align-start (for example), just pointing out the
examples in this article could be lead to problems

CSS variables can also be used to encourage picking colors or padding/margin
from a curated list. The approach in this article is not required to solve
that problem

------
asjw
In my opinion the problem is that CSS apply styles _and_ positioning to markup

Components have been a solved problem in desktop apps for decades

You have layout and styles applied to components positioned in the layout

What's really problematic is having a presentation layer that's split in
layout and styles in the same context (CSS) while content and structure are
both exposed in HTML

If we had layout in HTML and styling in CSS it would be easier to reason about
it

HTML was born to give the document structure, layout is in the same league if
you ask me, but then styles became the only way to lay out content, HTML lost
its purpose of being the way to structure content in a meaningful way so you
have the same HTML behaving diffentely with different layouts just because CSS
can work on both of them

If footer meant "stuck at the foot of content no matter what the content is"
we could have saved a lot of engineering hacks around making it reusable

------
chrisweekly
MODS: OP is from August, 2017; maybe add "(2017)" to the title given how long
27 months is in webdev?

------
jameslk
Maintenance of these utility class CSS codebases is such a pain. I've had the
pleasure of dealing with it. What if you want to tweak one of your utility
classes ever so slightly? If your codebase is big enough, you've just created
enormous amounts of potential regressions.

~~~
meerita
Give me an example of that.

Would you mantain .display--block? how? .color--red?

~~~
jameslk
It would be some domain-specific component. Like .product-card. I don't see
the examples you've given. Those are so literal, you might as well use inline
styles at that point.

~~~
meerita
That's the problem functional CSS solves: class naming doesn't relay on
developer intervention, it's just a translation of the utility.

Product-card is not an utility, that's why it's a problem to maintain such
classes.

------
madoublet
Adam is an awesome follow on Twitter. I still haven't come around to his way
of thinking on utility classes. It feels messy compared to a component based
approach. But, I totally respect his work and can see myself adopting
something like this in the future.

------
ChrisMarshallNY
I've been writing sites like this for years.

It can look sloppy, but I find that it's important to provide as many "hooks"
as possible to elements; especially dynamically-generated elements.

This is because I've written tools that were meant to be integrated into
sites, as opposed to the end site, itself.

It was important that the user of the tool be able to exert as much control as
possible over the rendering.

It does look messy as hell, though. Inspect Element is very helpful. Since a
lot of the dynamic code is optimized anyway, or rendered by AJAX, display page
source is kinda worthless.

It's all about keeping the specificity as weak as possible, while allowing the
CSS to focus on individual elements, or collections of elements.

~~~
ChrisMarshallNY
Also, for anyone that cares, I wrote up a series on CSS-based Web design about
ten years ago:
[https://littlegreenviper.com/series/cssdesign/](https://littlegreenviper.com/series/cssdesign/)

It's dated, but still absolutely relevant.

Here's the start of the specificity section, which goes on for some time:
[https://littlegreenviper.com/miscellany/stylist/introduction...](https://littlegreenviper.com/miscellany/stylist/introduction-
to-specificity/)

------
nailer
This very long article leads to the following point:

\---

> Utilities force you to choose:

Is this text-sm or text-xs?

Should I use py-3 or py-4?

Do I want text-dark-soft or text-dark-faint?

You can't just pick any value want; you have to choose from a curated list.

Instead of 380 text colors, you end up with 10 or 12.

------
pixelbash
This is a particular dilemma I've tried a lot of different approaches for. One
thing the article didn't touch on is what happens on responsive, where often
margins can change multiple times between desktop and mobile.

For a while now I've been effectively writing semantic css (nested or more
recently bem) composed out of non semantic sass helper functions. The benefits
of this are being able to think about namespacing in very simple terms. It can
make for fairly large css output files though, something BEM helps with a bit.

------
luord
This article is interesting, but not for anything having to do with CSS:

1\. Start with a given approach, but say you feel something "off" because it
doesn't quite fit "best practice xyz".

2\. Use another approach, which _also_ doesn't fit "best practice xyz".

3\. Argue that the best practice shouldn't be a best practice.

This of course, should mean that the very first approach is just as alright as
the second, yet here it is used to defend _only_ the second (sure, there's a
token acknowledgement of the first approach being valid too under the new
assumption, but everything afterwards is a long "but not really, second one is
the true better one").

Back to the topic at hand, the article depicts a circle: let's move away from
inline css by... moving it one attribute over, to "class". The token attempt
at contradicting this is unsuccessful one because, as much as there's no limit
in the inline css you can do, there's no limit to the amount of classes you
can add. So it all ends up feeling a bit self-defeating.

Ultimately, this article, IMO, is a good example of this:
[https://christine.website/blog/experimental-
rilkef-2018-11-3...](https://christine.website/blog/experimental-
rilkef-2018-11-30).

Then again, I'm a developer first and foremost, maybe I'd like this better
were I a designer.

------
circlingthesun
I love the analysis in this post. I think utility functions along with a set
of design tokens (Styled System [1] / ThemeUI [2]) is a better mechanism and
achieves the same end goal as utility-first CSS, at least in the React
ecosystem.

1\. [https://styled-system.com/](https://styled-system.com/) 2\.
[https://theme-ui.com/](https://theme-ui.com/)

~~~
deltron3030
Yeah, it's technically better than Tailwind CSS, but unfortunately JS/React
only.

------
sbussard
I wanted to point out some of the downfalls of utility classes, but then
realized that my main objections are with the HTML-CSS model itself. Adam was,
as we all are, trying to make the best of this weird web dev situation. It is
the discussion itself that is the most valuable imo.

Architecture is not a striving toward perfection, it's a collaborative process
of finding heuristics that give good results based on real-world constraints.

Things to consider:

Utility classes do not do well when there are multiple states involved (as a
simple case, consider :hover). Libraries that use the CSS utility classes do
not follow the "Open-closed principle" or the "Dependency Inversion Principle"
– depending on the mental model you use.

The term "functional CSS" is a misnomer, since the composition of styles
happens at the HTML layer. Calling it "mashup CSS" would be far more accurate.

One huge problem in writing any software is figuring out how to make good
decisions about where and how to compose smaller building blocks into bigger
ones. Category Theory helps with many of these questions, but is far from
sufficient to answer all of our questions. So it's quite valuable to discuss
and try new things.

------
sdnguyen90
I’ve been using utility classes for a few years now. Some thoughts I’ve come
up with:

For content heavy sites like ecommerce/marketing/blogs, I use pretty much
utility classes exclusively. There usually isn’t much reuse of UI components
on these types of sites so maintenance is much simpler compared to semantic
classes. With semantic classes you’ll have a lot of one off styles.

I actually really enjoy writing sites like these since I can code a site start
to finish without touching any CSS files. Using utility classes I probably
finish 25%-50% faster than if I were to use semantic classes.

On more web app type things like admin panels, I use a mix of mostly semantic
classes and a few utility classes. I only use utilities to make sure there
aren’t a million different padding/margin/font size values.

In the earlier days of React I tried using all utility classes and it just
felt like there was too much going on in the JSX. If you use utility classes,
you know the class attribute can get pretty long - sometimes needing to be
broken into 2 lines. The CSS tooling with Webpack has come a long way and
solves a lot of the problems that all the utility class frameworks were trying
to solve around 2015.

------
lxe
I really like how the author progressed from semantic to utility with
examples. This approach made it really easy to understand the... uh... utility
of utility classes.

The answer to anyone asking "how is this not inline styles", is in the
article. With utility CSS, you don't use 100% of everything that CSS can do,
and just pick the exact snippets you need for your theme.

------
mcgwiz
What's always missing from these perennial CSS deep dives is that HTML already
gives us a paradigm worth extending: generic constructs, used in domain
specific contexts. Generic constructs are those that are devoid of domain
specifics and can be used by HTML documents from other domains, e.g. links,
paragraphs, buttons, tabs, and modals.

A link can refer to a user profile page or a news article. Both use the
generic anchor "component", which comes from the wider universe of components
applicable to most/all HTML docs. HTML: `<A class="user">`, CSS selector:
`A.user`.

To extend this, a media card could represent a video or a book or a sidebar
item. Both use the media card component's HTML structure but can be tweaked
visually with CSS. The root element of the video media card would be `<DIV
class="MediaCard video">` and would be identified with the selector
`DIV.MediaCard.video`.

(PascalCase is arbitrary but I like that it harks to class naming conventions
from OOP languages. You'd need some other naming conventions as well. I like
`_title` for internal element class names, like private class members from OOP
languages. Internal selectors would be built using the performant child
combinator. Some of these patterns are more verbose than current alternatives,
but it's also the minimum necessary to get crystal clarity around inherited
and cascaded values. Preprocessor nesting makes this less painful. And
`-highlight` for variants, because they resemble CLI switches. What about non-
generic components? Those aren't "components" as defined here - they are
simply higher-level HTML fragments, typically organized in source as an HTML
template.)

This gives you two dimensions along which to flexibly organize things - the
generic forms and the domain-specific applications, and should keep you from
slipping down the slope to utility-dominant CSS.

------
cousin_it
The decision to make CSS libraries that are reusable across all parts of your
application is spot on. Also it helps with theming, eg dark mode. To avoid
listing tons of classes on each element, you can use something like less:

    
    
        .my-class {
          .utility-class-1;
          .utility-class-2;
        }
    

Reusable constants also help a lot.

~~~
pixelbash
On the dark mode thing, another way to do this is using css variables like
--color-foreground for example. The whole site can have dynamic colour themes
with minimal effort after that.

------
tqkxzugoaupvwqr
Question: I used CSS utility classes for building components in VueJS. The
problem I ran into was that I wanted to apply classes only when certain
conditions are met, i.e. style the component slightly differently based on its
state. This caused me to check the condition repeatedly – once per class I
want to apply. Is there a better way, e.g. applying all classes together after
checking once?

TypeScript/JavaScript:

    
    
        export default Vue.extend({
            data() {
                return {
                    isActive: false,
                };
            },
            computed: {
                componentClasses() {
                    return ["margin-4", "padding-3", {
                        "color-red": this.isActive,
                        "font-size-30": this.isActive,
                        "font-weight-700": this.isActive,
                    }];
                }
            }
        });

~~~
aliveupstairs
the docs:

[https://vuejs.org/v2/guide/class-and-style.html#Binding-
HTML...](https://vuejs.org/v2/guide/class-and-style.html#Binding-HTML-Classes)

[https://vuejs.org/v2/guide/class-and-style.html#Array-
Syntax](https://vuejs.org/v2/guide/class-and-style.html#Array-Syntax)

In your template:

a) <div :class={active: isActive} />

b) <div :class="{isActive? 'active' : 'inactive' }"/>

~~~
earthboundkid
B) is not valid. It needs to be wrapped in an Array, not an Object.

------
chrisweekly
In terms of applying styles to pages / component hierarchies, I find it useful
to think in terms of "global / baseline", "layout", and "utility classes". I
wish layout were always viewed as a first-class concern, entirely separate
from branding, colors, etc.

I think "Every-Layout" ([https://every-layout.dev](https://every-layout.dev))
makes an extremely compelling case for this approach. I'd love to see an
example of a design system leveraging these beautiful, coherent, logically
sound typography-based layouts, incorporated w/ modern component architecture,
ready to be customized and themed. IMHO that'd be as transformative now as
twitter bootstrap was when it first arrived.

------
blauwhelm
I feel like one thing that isn't addressed is the way designs are often made.
Using utility classes requires that your designer is also aware of this and
uses it. My experience is that most of the time this is not the case. You will
end up having to make a lot of utility classes for single cases.

------
gintery
Separating HTML from CSS has no basis, they are both concerned with the visual
organisation of information. I feel that the real problem is not with CSS, but
with how HTML forces you to jointly specify the semantic structure of data
with its layout.

------
meerita
Anyone interested in a framework to produce functional CSS in SCSS/Sass, this
is my project
[https://github.com/meerita/utilcss](https://github.com/meerita/utilcss)

------
z3t4
You can have many classes. So in your markup you can have an item that is both
class article and class bio. Then on another page that is the same but
different the class can be article preview. Then in the CSS you make rules for
.article and where bio and preview differs you use .article.bio or
.article.preview respectively.

In CSS specific rules overrides general rules. So .article.bio would inherit
all .article rules and also override.

I like to start out my style sheet (CSS) by only using the semantic HTML
elements like h1, button, etc. Then when the design advances and I go down to
the small details - I add more and more specific rules.

------
ehnto
I use a method called Context and Components. The idea being to build
components, and to modify those components of they need to change base on
context.

From my experience, reusable CSS is somewhat of a red herring. Maintainable
and easily locates CSS is where you get productivity gains. If you don't know
what you habe because there are hundreds of utility classes then what good is
it. Also, if you are using utility classes why not just inline CSS? "red-
border" is jusr as

------
mmckelvy
CSS felt "solved" for me when the React team introduced inline styles. I've
been using them ever since and it has made styling a breeze. I know people
balk at inline styles, but I still haven't heard a convincing argument as to
why they are a bad thing.

~~~
andrethegiant
Lots of rule duplication and no pseudo-selector support with inline styles. If
you like using inline styles, I think you'd like CSS-in-JS, because it has a
similar feel when writing components with the benefit of deduped atomic
classes as critical CSS + pseudo-selector support.

------
bluetwo
The mistake in my opinion is trying to write HTML and CSS that is a Swiss army
knife of everything you'll need. Understand the problem at hand in the project
you are working on first and write HTML and CSS to tackle that problem.

------
firefoxd
What I figured out over the years, is that CSS is not an afterthought. You
need to engineer a solution for your design as you are building the html.

~~~
saagarjha
If you treat your CSS as a value-add, I've found you can often treat it that
way. I've designed sites that work fine in text-based browsers, and then I
stick CSS on it to make it look pretty on your phone.

------
flaviojuvenal
Ended up looking a lot like Bootstrap to me.

------
vkaku
Too much work.

A-b_c is so multiplicative

------
tayleeganj
This just seems primitive to me, use a UI framework and make ur life easier...

------
0xFACEFEED
For me, CSS has been a Solved Problem™ for 5 years now.

If a website is small then I write plain HTML/CSS/JS in the old school way and
all of these abstractions/systems are YAGNI.

If a website is large enough for these abstractions to matter then I'm using
React with inline CSS. I get reusability and composition without a noticeable
performance tradeoff. You can still build your components to decouple style
from content where needed. Up to you.

Years later, no issues.

~~~
XCSme
How do you re-use this inline CSS?

~~~
csande17
Not the parent, but the approach I've seen in React is to treat inline CSS as
objects like "{ fontWeight: "bold", color: "#000" }". So to re-use it, you can
either put it in a constant or make a component that applies the styles to an
element (and maybe takes props to override them).

~~~
XCSme
I was asking because doing this just looks like normal CSS, where you define a
class and use it in multiple places, only that it's in JS instead, so you
still have all the "problems" mentioned in the article.

~~~
Izkata
The major downside of reused inline CSS is when you have to do minor tweaks
(where active manipulation in the browser devtools is by far easier to find
the right values) and those inline styles are on the page multiple times.
Editing one class's rules is significantly easier than all the repeated inline
styles.

~~~
0xFACEFEED
With the inline CSS approach, components are your reusable entities not CSS
classes.

