
In defense of functional CSS - sebst
https://www.mikecr.it/ramblings/functional-css/
======
crazygringo
How is this any different from saying "don't write functions, just repeat the
same 10 lines the function would have in each place you'd use the function"?

The real kicker:

> _" I don't want to have to repeat the same 20 classes on every single
> button." That's understandable. I will say that there's a chance that
> repeating those 20 classes can actually be somewhat valuable, because when
> you get into a situation where one of the buttons needs to have slightly
> more margin-top than the others, then it's easy to fix._

That's just... bizarre, sorry.

It's infinitely better programming practice to use a "button" CSS class,
because then every time you want to tweak all buttons on the site, you tweak
it in one place. With 100 buttons in different places, can you imagine the
maintenance nightmare?

The author suggests creating button HTML templates instead... but _why_?
That's what CSS already _does_. And when one button needs more margin or
whatever other unique tweak... you just add an additional class so it becomes
e.g. class="button button-extra-spaced".

For the life of me I can't see _any_ advantages to the "functional CSS"
described here at all -- it looks like a nightmare programming practice.

~~~
batmansmk
Disclaimer: we have been using functional css for about 2 years.

Let's review the main use case you present "I want to tweak all buttons on the
site, I tweak it in one place":

\- How many times do I have to change all the buttons on my app?

\- Does changing one class work to change all buttons in practice? Don't I end
up having the color overloaded 3 times, cascading over and leaking in 5 others
spots?

\- Are most of my edits in CSS tweaking existing rules, or piling up more CSS?
Usually, in a large codebase, I end up just adding a class instead of tweaking
one and figuring out if I broke anything anywhere.

\- If I use a component-based approach, like Angular or React, do I really
have to change classes everywhere with functional css, or just in the button
component?

\- Is styling "functional"? Can I always change the styling of a class without
changing its semantics - like if I put the primary button the same as the
secondary, did the naming help?

Your case may be different and our point of view may also evolve. With
functional CSS + component-based approach, I rarely have to use the style
inspector - and produce beautiful, maintainable app with 14KB of CSS and no
styling bug. All my other attempts using CSS "the right way" lead me to 1MB+
of CSS.

The benefits of CSS to factor style by function seems very infrequent compared
to the problems they introduce.

~~~
ashelmire
> \- How many times do I have to change all the buttons on my app?

When making a styling change like this, it's typical to change it app-wide.

> \- Does changing one class work to change all buttons in practice? Don't I
> end up having the color overloaded 3 times, cascading over and leaking in 5
> others spots?

I can change the border-radius on all of my buttons, and they will all change,
and still have their color-specific classes.

> \- Are most of my edits in CSS tweaking existing rules, or piling up more
> CSS? Usually, in a large codebase, I end up just adding a class instead of
> tweaking one and figuring out if I broke anything anywhere.

This is unfortunately quite common in practice - because maintenance is hard
and practices are bad. But it is definitely possible to have robust, reusable
css.

> \- If I use a component-based approach, like Angular or React, do I really
> have to change classes everywhere with functional css, or just in the button
> component?

Phew! A component just for a button. What a twist! I don't think most people
are making components for each html element. In fact, I'd say this is pretty
redundant and overengineering things in a bad way. Guess what - html has these
nifty components called buttons too, and you can also style them. Wouldn't any
minor change to your button component require then passing in props (just like
classes)? <Button propName={"danger"}><button></button></Button> doesn't
really seem better than <button class="btn--danger"></button> to me.

> \- Is styling "functional"? Can I always change the styling of a class
> without changing its semantics - like if I put the primary button the same
> as the secondary, did the naming help?

Not really sure what you're getting at here.

~~~
Izkata
> Phew! A component just for a button. What a twist! I don't think most people
> are making components for each html element. In fact, I'd say this is pretty
> redundant and overengineering things in a bad way.

Welcome to the world of web components. This is actually really common,
especially in React with css modules - this way you can use your custom button
without even having to think about the CSS (or any extra complexity like
tooltips and accessibility), even from a common library used across projects.

~~~
rhizome
I want to call this "transverse encapsulation."

------
hownowbrowncow
Yikes.

I agree that this might help you move quickly when starting a project and
might be a fine approach for a small prototype or personal site (or, more
unkindly, in a consulting project). But you pay a huge cost: maintainability.
There is no encapsulation at all, not to mention the pain of having all these
generic classes floating around, colliding with anything that might
accidentally match. I’ve worked on projects like this where huge HAML views
chain many of these functional CSS classes. It makes it very difficult to
accommodate new external components or design updates which I would say are
pretty much inevitable in any product company. Even if you don’t add anything
new, good luck updating the entire system to adjust the padding on all buttons
unless you were disciplined enough to truly create encapsulating classes
(which is really the opposite approach of functional CSS anyway).

I really think CSS modules got it right (or similar approaches where you have
a unique class name per component). Our team approaches component styles like
a UIView in iOS—it should render acceptably with reasonable constraints. This
means any parent component / view can render this and set display: block,
flex, etc and the contents should largely adapt. These days this is pretty
easy with flexbox and grid. Even better—you can ensure that the markup classes
stay private to you and only allow modifications through JS (or mark some
classes as :global). Even better than that—your components can adopt
delegation or renderProps to allow parent views to replace / modify with their
own markup so everything in the component can truly be encapsulated.

~~~
mschaef
> Yikes.

Agreed. Wholeheartedly.

> I agree that this might help you move quickly when starting a project

I don't even see this... at least I can't imagine a case where I'd want to
replace "background: #333;" with "bg-gray-darker". The CSS has at least been
well established for years/decades, and it'll be much easier to find
documentation/support/etc.

> But you pay a huge cost: maintainability. There is no encapsulation at all,

He's advocating that the encapsulation happen at the level of templated markup
(or JSX, whatever), rather than at the level of CSS classes.

~~~
bennofs
The big difference between this and "background: #333" is that in the later
case it could also be "background: #334" or "background: #435". The functional
framework approach forces a minimal amount of consistency.

------
mcrittenden
Author here. In retrospect a couple months after writing this post, I don't
love it. I still am in love with Tailwind and Functional CSS, but I did a poor
job defending it.

I'd suggest that everyone read this post [1] by Adam Wathan, the creator of
Tailwind CSS. It does a much better job explaining and defending than I did.

[1] [https://adamwathan.me/css-utility-classes-and-separation-
of-...](https://adamwathan.me/css-utility-classes-and-separation-of-concerns/)

~~~
DevX101
To be clear, you don't love the post, or you've changed your mind on
functional CSS?

~~~
mcrittenden
Ah sorry, I just meant I don't love the post (and I just updated my comment to
make that more clear). If anything I am even more a fan of functional CSS now
than I was when I wrote this.

But my post is just a bad defense of it. The section about the separation of
concerns is especially unconvincing, and I spent almost no time talking about
the benefits of it. I'd like to rewrite it at some point.

~~~
pknopf
Well, hey, I dig the honesty.

------
chrisweekly
Functional CSS is a terrific approach. Tailwind in particular is exemplary.

Absent this approach, in web projects of nearly any size, the CSS inevitably
grows and becomes increasingly difficult to maintain. It takes very very few
cases of "I'll just write a bit more CSS" as the default solution to bug fixes
or changing requirements, before the best-intentioned design system becomes a
brittle nightmare. Whereas functional CSS supports composition, and makes
refactoring a reasonable proposition.

As a 20-year veteran of web UI development, I encourage skeptics to read
Tailwind's docs, which make a better case than the OP or I are doing here.

~~~
jonahx
so i'm on board with your central concern here. my issue with functional css
is that your markup has no semantics. you can't just look at it and know what
things _are_ by their names. ie,

    
    
        <div class="m-5 p-5 text-gray-light bg-gray-darker border border-gray-light">
    

what the hell is that thing described by all those styles?

versus:

    
    
        <div class="profile-card">
    

and i know immediately what it is, and can instantly map the markup to what i
see on the page.

you just lose too much by not having that imo.

i really like composing styles out of small little semantic utility classes as
in the first example above, but you can do that _and_ still have semantically
named classes easily enough with a preprocessor.

i'd be curious to hear your thoughts on that. when i've discussed this concern
with functional CSS purists they usually just shrug and say something like
"you get used to it" or "you just don't need those semantic class names" but i
find that response unsatisfactory.

clean, readable markup is _so much_ more pleasant to work with.

~~~
darekkay
One possible solution is in the article - nothing prevents you from using:

    
    
      <div class="profile-card m-5 p-5 text-gray-light bg-gray-darker border border-gray-light">
    

with "profile-card" being use just for identifying the component.

Other than that, I rarely go through HTML without Dev Tools, which shows me
exactly what a certain div is for.

~~~
jonahx
yeah that's better than nothing, but your markup is still super noisy and hard
to scan.

> Other than that, I rarely go through HTML without Dev Tools, which shows me
> exactly what a certain div is for.

I do all the time. I'd much prefer to work in my text editor, without being
obliged to use chrome tools to extract semantic meaning from my code.

------
cfv
But wait, what exactly is so hard about doing something like

    
    
        // _profile.scss
        .profile-card {
          @extend .m-5;
          // several more lines of extending
          @extend border-gray-light; 
        }
    

and just get the best of both worlds? That variant also has the advantage of
letting us JS folk use element classes for useful stuff, and makes changing
all instances of "profile-card" simultaneously a lot simpler.

~~~
achairapart
Most of the people commenting are missing one of the major point in
"functional CSS": Keep specifity low = lower code size, less side-effects,
higher maintainability.

Yes, you add bits of complexity in the HTML, but you also gain almost no
specifity on the CSS side.

~~~
dwaite
Could you elaborate on this more? All three of these points seem
counterintuitive to me.

1\. "profile-card" takes fewer bytes than "m-5 p-5 text-gray-light bg-gray-
darker border border-gray-light", so the space-savings of not defining
profile-card within the CSS seems to be lost the more you reuse semantic
styles within your HTML.

2\. "m-5 p-5 text-gray-light bg-gray-darker border border-gray-light" and
"profile-card" should amount to the same CSS styling applied at the same level
of specificity in an apples-to-apples comparison, so I'm unsure about side
effects. Are you saying that using exclusively functional styling you can
count on naming conventions to know if two styles would conflict?

3\. "m-5 p-5 text-gray-light bg-gray-darker border border-gray-light" looks a
heck of a lot harder to maintain than "profile-card" once I have 50 profile
cards in my application styling, spread out across multiple app development
teams (and even development languages).

Are you saying it provides other maintainability benefits which are cross-
cutting improvements that outlay the ability to think of your HTML as being
made up of semantic components? Or are you saying that you are relying on
component frameworks which make component definition in CSS a duplication?

~~~
achairapart
1\. Think about this: You have to write or customize .profile-card for every
project, with "m-5 p-5 text-gray-light bg-gray-darker border border-gray-
light" you're writing 0 lines of CSS. Zero. All your CSS will be your utility
framework (sizes around 5~15kb) and it will never increase in size. Now, tell
me you never seen a two year project where CSS alone reached 2+Mb because at
every edit someone added another class to the list...

Also: When you gzip your HTML those repeated classes will compress pretty
well.

2\. Yes, you're right! Same specifity for the example in question. My point
was more in general. Think @extend[0], nested selectors in SCSS. They look
less scarier than "m-5 p-5 text-gray-light bg-gray-darker border border-gray-
light" but they do not always do good.

And I can tell you'll have no side effects: If you look at the HTML only, what
".profile-card" does? Does it add padding, typography, borders, transitions?
How do you extend it? I can't tell. But I know for sure that "m-5" will add
margin and margin only. "bg-gray-darker" will add background-color and
background-color only. And so on. Every class does only one thing. They don't
overlap. Once you memorize the simple naming convention you can't go wrong.

3\. Why it looks harder to maintain? Do you all really get scared by a few,
readable, classes? Also, classes are no meant to be semantic or content-
dependent[1].

At the end, I don't want to defend to death this practice. Maybe it's a
concept that is hard to explain (and the OP tried a bit lightly) but I assure
you, there are concrete benefits in using this approach. Many may not like it,
and it's completely fine, but it's not the hell most of you are shouting here.

Peace! :)

[0]: [https://webinista.com/updates/dont-use-extend-
sass/](https://webinista.com/updates/dont-use-extend-sass/) [1]:
[http://nicolasgallagher.com/about-html-semantics-front-
end-a...](http://nicolasgallagher.com/about-html-semantics-front-end-
architecture/)

~~~
dwaite
> At the end, I don't want to defend to death this practice.

I tried to phrase things such that I didn't seem to come across as aggressive.
We all have such limited views of the world, and opinions are an expression of
those views. I found attempting to understand other opinions can widen your
own viewpoint, sometimes in surprising ways :-)

My expectation of what people would give as their three benefits are as
follows:

1) abstraction of CSS - CSS is not especially crafted to be readable, and you
typically need to code workarounds for older browsers using legacy/vendor
styles and progressive enhancement. Merely using a functional CSS framework
can make the CSS much more readable than manually specifying style
information.

2) DRY/directness in component frameworks - if I'm abstracting a profile card
into a component, there is little value to stylize based on a profile-card
class, especially if that means my style is now separate from the rest of the
component definition.

However, if you are _not_ using a component framework but instead using
something like templated HTML pages, you really do worry about whether people
will identify a particular piece of markup as a profile card or the like, or
that profile cards on one page will start to deviate from the rest of the app.

3) (Harder for me to explain) one of the maintenance issues with CSS comes
from (logical) components, selectors, and styles all having M:N relationships
with each other. So I might define my profile-card styling entirely within a
single selector. But I might also elsewhere say something like:

``` a, .nav .selected, .profile-card .info { color: #ed0a1f; } ```

This is slightly different from the concept of side effects, but IMHO this is
what makes CSS so difficult to reason about and maintain.

Use of functional CSS (and encouragement to embed styles within the HTML
directly, rather than composing new classes via something like @apply in a
stylesheet) means that you have created a pretty clear/classical relationship
of styles to presentation.

So you might make an argument that classes should be leveraged more for
semantic information, the actual styling becomes much simpler.

That sort of argument would make me wonder if there is a potential tool for
those who are using templating rather than component frameworks for their
buildout - a CSS lint tool that encourages you to use semantic classes, but
that those classes must be composed entirely from an extensible set of
functional components, rather than raw CSS.

~~~
achairapart
I'm sorry, didn't want to appear aggressive either. Maybe when I wrote my
comment I was influenced by the great number of negative comments here, but
obviously, nothing personal!

Maybe there is a lot of confusion also because the naming of this methodology.
The whole "functional" thing. It's funny that the very same practice has also
been called "Atomic CSS" and "Object-Oriented CSS (OOCSS)"(!).

I would name it "Non-Cascading Style Sheets" because the whole point is
actually giving away most of the "C" in "CSS".

I was also thinking that another point of such negativity may be that to use
it you have to somehow master all the CSS rules, where not-so-experienced
developers may rely on some "trial and error" or some bad pratice (eg. adding
many nested selectors) to achive the same result. I might be wrong.

I remember that there are tools that throw a warning when a class is mutated
(ie. overwritten by another rule) because you don't really want to - let's say
- add a border when using something like "bg-gray-darker".

Yes, this practice can be a great choice for component frameworks. But it's
also great for rapid prototyping and designing UI components or whole web
pages directly in the browser.

And for templated HTML pages you can be more expressive using something like

    
    
        "profile-card: m-5 p-5 text-gray-light bg-gray-darker border border-gray-light" 
    

Where the "profile-card:" bit has no effect on the presentation but gives the
code reader an insight of the markup.

I actually used to do something like this at first during
prototyping/designing, but then I stopped. Maybe just because at some point I
became so accustomed that I was able to catch every part of the page at first
sight.

------
Drdrdrq
Awful idea. Just awful. The reason for splitting content (+hooks in form of
CSS classes) and presentation is to make problem space smaller. If you say
that HTML is now concerned with presentation too, you are basically going back
to inline styles. And yes, I would prefer style "font-size: 10px" to class
"fs10" anytime. At least I don't need to learn new classes with every single
codebase I come across. There is a reason developers get emotional when
someone tries to defend ideas like this - it's not because we don't
understand, it's because we do, and we've been there. The location of the CSS
is a solved problem, just let it be.

------
dangerface
This is really bad advice.

You reduce errors by reducing code by wrapping your code in functions, thats
functional and its how classes work. This article suggests the opposite just
write everything from scratch perfectly, not going to happen.

> there's nothing stopping you from continuing to add those semantic classes,
> even if they're irrelevant for styling If they are irrelevant to style then
> it could be applied to anything, it has no meaning and is not semantic.

They don't know what separation of concerns is, or why its a good thing.

>when you get into a situation where one of the buttons needs to have slightly
more margin-top than the others

Yea just break your designs consistency im sure your users will love that.

~~~
ArchTypical
I tried this at one company. I have never gone back. It's terrible advice? You
can only reconcile this as a matter of experience.

~~~
dangerface
> You can only reconcile this as a matter of experience.

I was able to give three common and specific reasons why its bad advice, none
of them where to just trust me, or my experience.

If the only reason you like something is because you like it, fair enough,
good for you, you like a thing. Its ok to like things, but that doesn't mean
there is any solid logic backing the things you like.

------
sklivvz1971
This seems to misunderstand the basics of why we have CSS in the first place,
to separate "how something appears" from "what something is", and suggests to
mix the two.

The obvious result is that you would end up with similar objects with
different styles. A button with "main" role should have a consistent style
across instances, not be green in one place and grey in another because you
forgot to add the "green" class. Also changing the color of "main" buttons
from green to blue should not entail changing each usage of the "green" class
to a usage of a "blue" class.

~~~
collyw
I often wonder how useful this septation actually is. Most of the apps I have
worked on seem to be horribly coupled despite separate css.

~~~
lucideer
You can introduce implicit coupling in any app (i.e. in a non-CSS programming
language). It's bad practice in both cases.

This kind of separation doesn't magically make your frontend code good, it
just gives you the freedom to architect it well. Whether you do is up to you.

Admittedly it is very difficult to find an example where this has been done
well, but this is I guess why we have abominations like AMP.

~~~
collyw
Sure it is bad design, I won't argue with you on that.

But the other thing is that we rarely upgrade just CSS, usually we get a whole
new front end, or even more likely a whole new app.

------
weego
This stuff never scales. No one can remember the class names, no one want's to
search through the examples and style guides for a project, no one want's to
standardise naming of their own hacks etc and so you start of with good
intentions and end up with a lot of duplication and a whole lot of shit.

CSS is an expressive markup. You shouldn't try to turn it into programming.

~~~
1_player
> This stuff never scales. No one can remember class names

Are you saying that with a CSS file with one-class-per-component it's easier
to remember the hundreds if not thousands of class names, compared to a
functional library, where you only have to remember a handful of them?

You might not like it, but the very reason of existence of functional CSS
libraries is to limit the number of classes and improve reusability and
composition.

~~~
yakshaving_jgt
Have you written a line of CSS, ever?!

Why would anyone restrict themselves to one class per component? Do you know
that classes can be combined? Do you know how specificity works?

CSS fundamentally lends itself to being compositional. Suggesting that this
isn't the case without added libraries is either ignorance or madness.

------
meandmycode
As a frontend developer of 15-20 years now I've been pretty dumbfounded and
unconvinced by any arguments for this style of css, I think it's especially
hard for frontend developers of such duration because this is effectively the
first ever style of css you write, and then you were force fed xhtml, semantic
web and then later responsive became the "Told you so!" of the methodology.

Despite my scepticism of extremes of semantic web, I realise now when I read
articles talking about switching to this style of css, their problems are
entirely unrelatable to me because I implicitly see the conceptual structure
of a design vs its visual specifics.

This just feels like a new age of developers don't see the need for the
abstraction and so it's a constant mental burden for them without any
benefit.. I think what has propped this up is that some of the problems that
semantic css has historically only ever been able to solve (such as
responsive) are now being solved differently, either through more powerful css
layouts that implicitly layout better responsively, or that they rely instead
on javascript to switch classes/html/components out with media query
listeners.

Ultimately I think whatever you decide should be based on what your team
aligns to best, don't feel guilty about 'not getting' this pattern, but I
think it's important you pick one way, as mixing these worlds just doesn't
work (at a project level), but certainly you should always try new things for
new projects or experiments.

~~~
criswell
I'm a frontend developer of about 15 years as well and I think functional css
makes a lot of sense. My biggest argument for it is not having to name every
thing. You know how many times I've had to think of a name for a random
container that exists simply to align some crap? Then if you need another
wrapper or something for that for some reason? It eliminates the name game
(whenever you want it to).

~~~
avisser
> My biggest argument for it is not having to name every thing.

This x 100. As a guy who is the only American on a team with a bunch of non-
native speakers, taking away naming responsibility is a big win.

------
darekkay
Wow, this gets some real hate on HN. I highly recommend reading [0] instead
(which is by the way linked in the main article).

If you're writing HTML by hand, then yes, it will be a PITA changing all those
"bg-blue" Profile Cards using functional CSS (while it's just a single change
when using .profile-card instead). In reality, it's not the functional CSS
being the issue, but the markup duplication. If I extract a real reusable
ProfileCard _component_ , I can apply functional CSS to it exactly once. If
the color changes, it's just a single place I need to look into.

There is no silver bullet. If you design web _sites_ , try some templating
language to extract your components. If you develop web _apps_ , take any
modern framework like React, which enforces using reusable components. If you
still prefer writing HTML by hand, then yes, functional CSS is not for you.

[0] [https://adamwathan.me/css-utility-classes-and-separation-
of-...](https://adamwathan.me/css-utility-classes-and-separation-of-concerns/)

~~~
blauditore
> If I extract a real reusable ProfileCard component, I can apply functional
> CSS to it exactly once. If the color changes, it's just a single place I
> need to look into.

Then you're basically moving re-use from CSS to HTML templates. And if both
exist only once, it shouldn't matter where you have to adjust that one line.

~~~
darekkay
You're right. My main point was to separate your code by purpose instead of
technology. That's where component-based development is heading to. _If_
you're using components, then you're still free to choose one or another CSS
aproach, but most functional CSS downsides don't apply anymore.

My team in fact combines both approaches. I don't need to define a CSS
component just to add some margin, but I am also free not to use 15 functional
classes to clutter the HTML.

~~~
wvenable
I don't understand why I'd use functional CSS over inline styles. With inline
styles I have editor auto-complete, no confusion as to whether it "pt-10" or
"pt-15" even exists.

I make pretty heavy use of cascades and don't put classes on every single HTML
tag and try and keep my HTML as semantic as possible even though I actually do
have components for every button. I will put an inline style of something if
that is the most logical approach but proper semantic classes allow me to work
at a higher level than individual styles.

~~~
darekkay
For me, it's about atomic design. I want to use predefined, reusable values
only. So I'm only able to use "pt-10" for 10px and "pt-20" for 20px (as an
example). With inline styles, nothing prevents me from using "padding-bottom:
11px" (which may not be defined in the style guide).

Also, from the article:

\- Inline styles don't respect media queries, which basically rules out
responsive design

\- Inline styles aren't limited to pre-defined options, meaning you can still
end up with 90 different shades of blue)

\- Inline styles cause specificity issues, since they trump separate
stylesheets.

\- Inline styles don't support print-specific styles.

\- Inline styles can't address pseudo-elements (such as ::before and ::after)

\- Inline styles can't apply to multiple elements. Utility classes can define
.bg-blue once and have it apply to many things, which leads to shorter markup
and quicker rendering speed.

\- Inline styles are a pain to type. Compare class="f-sm bg-blue" to
style="font-size: 10px; background-color: #0000ff;".

~~~
wvenable
> For me, it's about atomic design. I want to use predefined, reusable values
> only. So I'm only able to use "pt-10" for 10px and "pt-20" for 20px (as an
> example).

I would call these "padding-small" or "padding-big" in that case. Of course, a
better way would probably be to abstract that even further in actual purpose
rather than style.

> Inline styles don't respect media queries, which basically rules out
> responsive design

I question how you could have style-like-classes like pt-10 and be responsive
at the same time. So this style is padding-top: 10px as it's name suggests
_except_ on mobile. That makes no sense.

> Inline styles aren't limited to pre-defined options, meaning you can still
> end up with 90 different shades of blue)

That's fine. Although why limit yourself to calling the class "blue" when you
could call it "brand-color" and actually be able to change it something other
than blue in the future.

> Inline styles cause specificity issues, since they trump separate
> stylesheets.

I don't think you want your "pt-10" style to be "trumped" by another style
otherwise that would be confusing. So again this is not an advantage to this
style.

> Inline styles don't support print-specific styles.

Again, it would be confusing if "pt-10" suddenly didn't apply when printed.

> Inline styles can't apply to multiple elements. Utility classes can define
> .bg-blue once and have it apply to many things, which leads to shorter
> markup and quicker rendering speed.

So the advantage is you get to type 5-10 fewer characters per element you
apply it to?

> Inline styles are a pain to type. Compare class="f-sm bg-blue" to
> style="font-size: 10px; background-color: #0000ff;".

Only if you know all the classes that actually exist for the particular
project you are working on. Does f-md exist? Is really "fd-small" in this
project? My editor will autocomplete inline styles so they might actually be
easier to type.

~~~
darekkay
>> For me, it's about atomic design. I want to use predefined, reusable values
only. So I'm only able to use "pt-10" for 10px and "pt-20" for 20px (as an
example).

>I would call these "padding-small" or "padding-big" in that case. Of course,
a better way would probably be to abstract that even further in actual purpose
rather than style.

This is perfectly fine. Functional CSS does not enforce any naming. In
Bootstrap it's just "p-1" through "p-5". But I would rather go with more
semantic names, too.

>> Inline styles don't respect media queries, which basically rules out
responsive design

>I question how you could have style-like-classes like pt-10 and be responsive
at the same time. So this style is padding-top: 10px as it's name suggests
except on mobile. That makes no sense.

Following your example, you can have "padding-small" with different paddings
on Desktop and Mobile. Which is not possible using inline styles. For
Bootstrap you get media query suffixes for many classes. One common usage is
"d-flex flex-column flex-md-row", which makes an element "flex", with column
direction on mobile and row direction on desktop. Handy for simple use cases
like that.

>> Inline styles aren't limited to pre-defined options, meaning you can still
end up with 90 different shades of blue)

>That's fine. Although why limit yourself to calling the class "blue" when you
could call it "brand-color" and actually be able to change it something other
than blue in the future.

Again, I think you're mistaking a single Functional CSS implementation (like
the one used by the author) with the concept itself. You are not forced to use
color names and numbers in your functional CSS class names. And I fully agree
that semantic naming is way better.

>> Inline styles cause specificity issues, since they trump separate
stylesheets.

>I don't think you want your "pt-10" style to be "trumped" by another style
otherwise that would be confusing. So again this is not an advantage to this
style.

What the author means: using only functional classes, you know exactly that
your "pt-10" padding is not overwritten (unless you use another "pt" class by
mistake). With "traditional" classes, you can't be sure of that. And more
often than not you will get problems with the cascade, especially in bigger
projects with many developers. That's where all the "!important" hacks are
coming from.

>> Inline styles don't support print-specific styles.

>Again, it would be confusing if "pt-10" suddenly didn't apply when printed.

You can do much more with CSS than adding padding ;) Hiding elements for print
is the main use case here. You can't achieve this with inline styles only. A
"print-hidden" utility class can do that.

>> Inline styles can't apply to multiple elements. Utility classes can define
.bg-blue once and have it apply to many things, which leads to shorter markup
and quicker rendering speed.

>So the advantage is you get to type 5-10 fewer characters per element you
apply it to?

No, the advantage is that you can use only pre-defined, reusable, atomic
definitions. If the style guide says there are only 2 types of padding
("padding-small" and "padding-big"), you won't be able to set another padding
using functional CSS only. With inline styles, you can do whatever you want.
This also applies to raw CSS stylesheets. That's why pre-processors are so
valuable - you can define your SASS/LESS/whatever variables and achieve the
same effect. And before you ask: "then why do I need functional CSS in the
first place?" \- it's because of the other advantages, like not having to use
a pre-processor or defining/importing a stylesheet in the first place.

>> Inline styles are a pain to type. Compare class="f-sm bg-blue" to
style="font-size: 10px; background-color: #0000ff;".

> Only if you know all the classes that actually exist for the particular
> project you are working on. Does f-md exist? Is really "fd-small" in this
> project? My editor will autocomplete inline styles so they might actually be
> easier to type.

If you don't know all the classes, then you need to know all the style guide
values. Otherwise, how do you implement a consistent-looking design? Take our
"only 2 padding values defined" example. You will have to look stuff up, be it
functional class names, traditional class names, SASS variables or simply the
values to be used. Also, _my_ editor will autocomplete functional CSS classes,
too.

~~~
wvenable
> I think you're mistaking a single Functional CSS implementation (like the
> one used by the author) with the concept itself.

Honestly at some point what you describe I would just describe as normal CSS.

Functional CSS is classes based on their visual function rather than an
abstract concept. This the definition. But the more semantic your names are
the less they related to an actual visual function.

If on mobile you don't apply any padding then your padding CSS class is a lie.
And if you don't call it "padding" in some way then it's not Functional CSS. I
also think conceptually having a few utility classes like "print-visible" or
"print-invisible" is not really applying Functional CSS as an overall concept.

------
Flenser
What about theming/branding so that you can make your enterprise web-app fit
in with each of your clients other web-apps?

If your class names are semantic like _profile-card_ it's easy to have a
branding css file for each client.

If your class names are functional like _m-5 p-5 text-gray-light bg-gray-
darker border border-gray-light_ you're going to... what? make code changes
for each client?

Obviously if the website is only going to have one branding, this isn't an
issue, but advice like "use semantic css" or "use functional css" needs to be
put in context. What you do in an agency context for content sites would be
different from an in-house web-app context, or a web-app for SAAS context.

~~~
ekzy
It's all about tradeoffs, there are no silver bullets. If your class name is
like _profile-card_ then it _could_ be simpler... until it's not. Because it
turns out that one of your client _profile-card_ needs to behave slightly
differently on hover or whatever. In theory, _profile-card_ is a great idea,
in practice it can be a headache

~~~
Flenser
What I'm saying is you have files client-alice.css and client-bob.css, and you
define different profile-card:hover rules in each. But with functional css you
have nothing to hang your rules on.

------
have_faith
I usually don't want people to be able to create infinite variations of things
because of a lack of consistency.

I like defining a few concrete component styles BEM style and having it easy
to re-use them and other people not abuse them too much. After the initial
components are defined I don't want to think about what border or colours are
involved I just want to drop profile-cards in various places. It feels like
this "functional" approach doesn't solve enough real-world use cases (that I
have experienced at least) to justify using it.

~~~
naasking
> It feels like this "functional" approach doesn't solve enough real-world use
> cases (that I have experienced at least) to justify using it.

I suggest reading:

[https://hackernoon.com/full-re-write-with-tachyons-and-
funct...](https://hackernoon.com/full-re-write-with-tachyons-and-functional-
css-a-case-study-part-1-635ccb5fb00b)

------
RpFLCL
We did this at my last job, but inevitably ended up with a mix of half
functional CSS and half component CSS.

If you have lots of repeated components on a page (comments, thumbnails, tags)
then it's difficult to defend repeating, potentially dozens, of the same
declarations. You're better off with the component defined in a stylesheet.

I think the real use for functional CSS is for one-off adjustments on those
components:

    
    
      <div class="comment">..</div>
      <div class="comment">..</div>
      <div class="comment disabled">..</div>
    

It's also a pain to edit all of the instances of an object when you want to
update styles consistently. One upside, though, is that you have to consider
the impact of the change in each spot.

~~~
naasking
> If you have lots of repeated components on a page (comments, thumbnails,
> tags) then it's difficult to defend repeating, potentially dozens, of the
> same declarations.

That's where you have two choices:

1\. Use your HTML templating language to define a dynamic variable
representing the set of classes and use that.

2\. Like the article says, make use of the functional CSS's tools to create a
new class that includes the styles you use. Same idea to #1, just at a
different stage.

~~~
HelloNurse
Both "solutions" don't address the problem of repeated class names, they just
help repeating them in a correct but not less obscene way. Bloated markup
cannot be defended.

~~~
naasking
Yes they do, at least in a way that's no worse than every other CSS toolkit in
widespread use.

And there's nothing "correct" or "incorrect" about it. I suggest reading [1]
if you want some real data on the usefulness of functional CSS.

[1] [https://hackernoon.com/full-re-write-with-tachyons-and-
funct...](https://hackernoon.com/full-re-write-with-tachyons-and-functional-
css-a-case-study-part-1-635ccb5fb00b)

~~~
HelloNurse
I mean "correct" in the formal sense that every element gets the intended
style, which is possible even with bad design and bad technology.

------
risto1
I've used BEM, atomic design and functional CSS. I actually like some kind of
combination of all three. This is my 2c:

The pros of functional CSS as a replacement for CSS/SASS variables:

\- You define your 'palette' up front: which margins, font sizes, colors are
acceptable, etc. You could do something similar with CSS/SASS variables, but
you'd give up the capability to rapidly prototype on any machine with any
browser and you'd need HMR set up everywhere. Also since it's a class you can
(de)compose it with other classes and build up 'abstractions'. So I'm really
using functional CSS as a better replacement for SASS variables.

\- It's easiest to start hacking away at designing widgets without worrying
about things looking inconsistent eventually, because you're working with a
limited palette

And then what I take out of atomic CSS is splitting up the code into different
levels. Instead of atoms, molecules, organisms, I have: palette, abstractions,
components. Abstractions are composed of other abstractions and/or things from
the palette. Ie: an abstracted class might be like: .center-vertical, .center-
horizontal, and then composing those would give the .center class. Components
are concrete widgets like buttons, popovers, modals, tables, lists, etc.

And I use the submodule idea from BEM. So if I need to create custom themes,
it would be the like .button .button-(theme name) and writing the theme works
just like inheritance would here but I'd be using composition instead

------
Yahivin
Why does it seem like no one knows anything about CSS? BEM, "Functional" CSS,
all this nonsense simply because nobody know about the child selector as
opposed to the "any descendant" selector. (Maybe because it wasn't supported
in IE6 and we're still reeling from that to this day...)

Take ten minutes and learn. Here's some tips:

Attribute selector:

    
    
      button[disabled]
        background-color: gray
    

Modifiers are just classes, never have disconnected .some-classes floating
around. Keep them scoped to their element :

    
    
      button.large, a.button.large
        font-size: 2rem
    

Child selector:

    
    
      profile-card > h2
        font-size: 1rem
        margin: 0
    

Everyone forgets to put in the alligator and then complains that their
ridiculously nested markup gets out of control. This way a card can contain
_anything_ and not have to worry about stomping its styles.

Semantic elements:

    
    
      profile-card
        display: block
    
      profile-card.active
        background-color: green
    

You don't need to be limited by span/div-itis. It's 2018 go wild.

Pro-tip:tm: try learning CSS before creating or adopting a CSS "framework" to
solve problems that CSS already solves.

Hope this brief rant saves a life or two. Hang in there people.

------
err4nt
Applying CSS using utility classes it just a different way to abuse HTML for
the purpose of inline styling.

\- How do you set a class for states like hover, focus, active, hidden,
checked, etc

\- How to you use/create/style pseudo-elements?

\- How do you add responsive control (like CSS media queries)?

'Functional CSS' is like sitting down at a full piano keyboard and trying to
bang out a tune by only hitting one key - there's a LOT more range possible in
CSS, and it's only difficult mostly because we MAKE it difficult by ignoring
this.

The only/best 'functional' CSS tooling I would even look at these days is
[http://css-blocks.com](http://css-blocks.com) from the people who made Sass,
it's a much more modern approach and you end up with highly optimized code,
HOWEVER you write human-readable CSS stylesheets and you let the CSS-Blocks
compiler and Opticss optimizer output the 'functional css' you need.

Let humans do what humans are best at (writing nice stylesheets) and computers
do what computers are best at (compiling things). It will outperform and human
pretending to be a compiler, and with better accuracy.

~~~
criswell
This is how you can do all of that:

    
    
      class="hover:red" -> .hover\:red:hover { color: red }
    
      class="before:red" -> .before\:red::before { color: red }
    
      class="medium:red" -> @media (min-width: 500px) { .medium\:red { color: red }
    

The important thing though is it doesn't need to be used for everything. I
think it makes a lot of sense for structural stuff. When you dig into like,
children of a hovered element I can see it getting a little messy.

~~~
err4nt
How come people who do this only ever use class names? Why not invent your own
data attribute like data-hover="red" where you create new namespaces for
things like hover, or pseudo classes, why it it always only ever class names?

~~~
criswell
Totally talking without thinking about it too much here:

The classList API makes modifications to the class property very easily.

You'd be essentially limited to one identifier in attribute selectors. You
can't really select from multiple identifiers with a data attribute without
doing like:

    
    
      [data-hover*="foo"]
    

which would search for "foo" anywhere in the attribute, which could mean
incorrect substring matches.

Chaining attribute selectors would be rough too:

    
    
      [data-hover*="foo"][data-hover*="bar"] {}
    

vs

    
    
      .foo.bar {}

~~~
err4nt
> The classList API makes modifications to the class property very easily.

So does the dataset interface for custom data attributes:
[https://developer.mozilla.org/en-
US/docs/Web/API/HTMLElement...](https://developer.mozilla.org/en-
US/docs/Web/API/HTMLElement/dataset)

> You'd be essentially limited to one identifier in attribute selectors. You
> can't really select from multiple identifiers with a data attribute…

That's just not true, there's an attribute selector that targets strings in a
whitespace separated list: [attr~=value], so you could think of .demo as being
a shorthand for [class~="demo"], or #demo as a shorthand for [id="demo"].

    
    
      [data-hover~=foo][data-hover~=bar] {}
    

would target a tag like this:

    
    
        <div data-hover="foo bar"></div>
    

But not a tag like this:

    
    
        <div data-hover="foobar"></div>
    

More info about attribute selectors:
[https://drafts.csswg.org/selectors-4/#attribute-
representati...](https://drafts.csswg.org/selectors-4/#attribute-
representation)

~~~
criswell
I wasn’t aware of the tilde attribute selector. Still a lot more characters,
though.

The classList api is still a lot more suited for this than dataset. None of
the modifications done through the dataset api would reflect in the DOM and be
readable by CSS unless you were to convert the list to a space separated
string and explicitly set the attribute. classList handles all of this for
you.

~~~
err4nt
> None of the modifications done through the dataset api would reflect in the
> DOM and be readable by CSS unless you were to convert the list to a space
> separated string and explicitly set the attribute.

I'm really not sure what you mean by this. If you set the data attribute any
of these ways, it can be targeted in CSS with [data-demo="example"]:

    
    
        el.dataset.demo = 'example'
        el.dataset['demo'] = 'example'
        el.setAttribute('demo', 'example')
    

CSS doesn't require a space separated anything. When you use an attribute
selector in CSS it treats the entire value as a string, spaces included. But
it's not classes versus attribute selectors, as class is an attribute, and
therefore also something you can select with attribute selectors.

Also, think about the asymmetry between CSS and HTML when considering saving
characters, one CSS selector targets ∞ tags, so I'd rather write slightly
longer selector one time, than need to use a much longer 'namespaced' value on
each element where I want the style to apply. That's leveraging what CSS does
best!

~~~
criswell
I'm just saying if you want to target something on an element it needs to be
set in an attribute and classList takes care of this.

I use classes strictly for styling. I change these styles by adding and
removing class names and classList handles it very well without me needing to
read the data attribute, make it an array, manipulate it, join it and update
the attribute.

~~~
err4nt
I feel like you're still thinking small in terms of attributes, and big in
terms of values. Many many values all crammed into one attribute (class), but
the reality is you can invent infinite (∞) data attributes. There's literally
no need for you to format the values as a list of space-separated
values…unless you want to. But if you don't want to, there's no need. Consider
this, instead of targeting something with classes like this .active.demo, and
setting it like this

    
    
        el.classList.add('active')
        el.classList.add('demo')
    

You would NOT need to do something like this to use data attributes, [data-
example~=active][data-example~=demo] and to set it like this:

    
    
        if (!el.dataset.example.split(' ').includes('demo')) {
          el.dataset.example += ' demo'
        }
    

You could instead easily set two attributes and test for their presence, even
if they don't have values (or you're not using them)

    
    
        el.dataset.active = el.dataset.demo = true
    

And then you can target that in CSS with [data-active][data-demo]. To remove
them later is just as simple:

    
    
        el.dataset.active = false
    

And it's gone! Try to think BIG in terms of attributes, and small in terms of
values. It's a lot nicer than trying to cram all of your values into just one
attribute when you literally have infinite attributes available to work with!

Not only do you have infinite attributes to work with, but you can

Using classes as your only way to target styles, and ignoring the other
aspects of how CSS selectors can target elements is like picking up a guitar
and trying to play a song, but only plucking one string. You might be making
it harder on yourself to get the job done, and the result isn't any better for
the effort.

EDIT: Just for kicks, have you ever considered the flexibility of what data
types you can set as an attribute value other than a space separated list of
strings? Try this:

    
    
        // set JSON to attribute value
        document.documentElement.dataset.example = JSON.stringify({one: 1, two: 2})
    
        // get JSON from attribute value
        JSON.parse(document.documentElement.dataset.example)
    

You can even stick a bit of JSON there as the attribute value, which can be
parse/stringified by JS, is _easy_ to add or remove properties from and work
with on the JS side (not requiring helper methods like classList), and is
_still_ targetable by CSS once set on an element :D The possibilities are
endless, the apparent limitations a lot of people butt up against are self-
imposed.

~~~
criswell
I'm sorry I'm just not seeing the value in it. I'm just seeing more complexity
JS and CSS wise without solving any problems.

------
vinceguidry
I'd call this style "compositional" rather than "functional". You're composing
an element's style from smaller chunks.

My main problem with this is that some people like working that way and some
people don't. This leads to a mish-mash where you have two completely
different places to look for where your styling might be. Since you can't
specify _all_ of your styles in this fashion, then in order for there to be
one spot where the styles live, putting them in CSS files with semantic
classes is the sensible default.

My other problem with it is that it encourages many DOM elements with one
style each as opposed to fewer elements with more style rules. I feel like I'm
swimming whenever I'm looking through the markup with an inspector.

More ideally what I'd like to see is styled-components, so the entirety of a
component lives all in one code file. I don't particularly care for the use of
javascript to specify literally everything on the page, from the markup to
behavior to styling, but the siren song of having everything there in one
place makes up for it. If you want terseness in style definition, which is the
main problem this "functional" approach solves, then you can simply invoke
short javascript functions.

My ideal approach though actually would lean on a text editor / IDE to keep a
list of components, and opening up the markup, styling, and scripting of a
component all at the same time, and just using HTML templates, SCSS, and
vanilla Javascript, keeping each file unsullied by the syntax and semantics of
the other languages.

I'm unconvinced that everything really needs to be Javascript, but I don't
mind wandering down that rabbit hole with everybody else until the React
fascination passes. It's not the worst way in the world to specify UI.

------
AltruisticGap
As usual maybe it is wiser to take the good parts from different approaches,
rather than going "all in" with one ideology / methodology.

For my sites I find it useful to have a small collection of very generic
classes. One common case that was annoying is how the spacing keeps changing
as you move text and components around a page, and you end up fiddling with
the rules all the time to adjust for how the top/bottom margins merge. No
matter how "logical" it is, from a graphic design pt of view, the spacing is
right when it _looks_ right.

So I have a few very generic classes like this:

    
    
        .mb-0   { margin-bottom:0; }
        .mb-1   { margin-bottom:1em; }
        .mb-2   { margin-bottom:2em; }
    
         /* text */
        .txt-lg { font-size:1.4em; }
        .ta-r   { text-align:right; }
        .ws-nw  { white-space:nowrap; }
    

These are useful for making small adjutments to the layout. That said, going
all in with atomic css doesn't make sense to me.

~~~
richjdsmith
I do the same. I have a scss file with a few margin and padding mixins that I
can throw into the dom when I need to. Otherwise, I'll stick with updating all
my buttons at once in my css `button` class.

------
frebord
This ridic argument boils down to code reuse and components.

The whole reason for css is to facilitate style reuse when writing markup. In
normal html pages you write a bunch of markup, chunks of that markup might
represent the same "component" and so css is a great way to style those
similarly using semantic class names.

If you use small components that exist in some type of template (react, vue,
etc...) you can take advantage of that to facilitate your code reuse instead
of a "semantic-component" css class. I think that is where utilities become
valid because you still only change a components styles in one place.

------
dukoid
Why is this named "functional" CSS?

Something like "const FIVE = 5" doesn't seem to capture the essence of
functional programming either?

~~~
skrebbel
Maybe it's not a reference to functional programming but to that other
definition of "function", you know, the one used by everybody except
programmers.

------
nerdponx
_Have you ever really looked at a thing with class= "profile-card" and said
"oh this is a profile card", when it wouldn't have been just as easy to tell
that based on the context or what it contains?_

Wait, what? Who _hasn 't_ done this?

------
Zelphyr
Oh God. Please don't let this be a thing. I hate to be negative but this is a
bad direction for a set of technologies (HTML/CSS/JS) that have already veered
heavily down a miserable path.

------
DevX101
This thread is why I love HackerNews. I'm in the middle of considering
something like this w/ Tailwinds and share some of the concerns expressed in
some comments here, but I'm still keeping an open mind.

Is there anyone who's tried it for a project and still hated it? Seems like a
lot of the detractors haven't actually used it yet.

------
ian1321
I used this technique in my previous startup. I even had shell scripts that
generated my LESS files.

One of the driving philosophies was that when one saw a CSS class, they should
easily be able to find it's definition in the source. Another driving
philosophy was that one should easily be able to determine what the class is
doing.

This lead to classes like `u-centered`. The `u` tells me it's in the
utils.less file. Classes starting with `l-` were layout classes, `t-` text
classes, etc..

I had classes like this:

u-{max,min}-width-{xxs,xs,s,m,l,xl,xxl}

t-white

u-bg-red (red background)

t-h3

l-container-{xxs,xs,s,m,l,xl,xxl}

You get the picture.

(The nice thing about xl and xs is that you can keep adding x's as you need.)

I found it to be very effective. I understand the arguments that it kind of
defeats the purpose of CSS, but I think CSS is pretty easy to mess up, and
this give you a solid, consistent structure to work with.

Of course, I didn't follow this style 100%. There were some cases where it
just made sense to use a more semantic style, but I found those case to be few
and far between.

~~~
wvenable
Seems like a waste of time when you can just do style="background: red;".
You're not adding anything to CSS you're just renaming and enumerating all the
style attributes and values.

I think it makes sense in small doses but I think once you're using shell
scripts to generate all these combinations you've lost the plot.

~~~
ian1321
There's a big difference between class="u-bg-red" and style="background:
red;". The big difference being that the class make it so that it is first-
class application idea.

And I think that may be one of the larger points here. CSS can be simple, and
using techniques like this forces it to stay that way. You have to take a step
back and understand what we're trying to do as engineers. I would argue that
being able to quickly understand code (e.g. the context to understand a line
of code is small) should be a top priority of most software project.

~~~
wvenable
"u-bg-red" vs. "backround:red" is just the same thing aliased. If you were to
introduce an actual concept like "warning" or "error" that was red that would
be different.

~~~
ian1321
You are correct from one point of view. But, the point I was making was that
the class definitions for bg color can be contained within a single file in
your application. Using `style` is completely different in that anything is
possible. This is a big deal, as cutting down on possibilities/simplifying is
a very important process in software engineering.

~~~
wvenable
> But, the point I was making was that the class definitions for bg color can
> be contained within a single file in your application.

But that doesn't matter because it's not an abstraction. If you have 10 HTML
files and 1 CSS file, you can make a class called "warning" and have it be a
background color red you've simplified those HTML files because you have less
style information in the HTML.

But if you are using classes like "bg-red" or "pt-10" then you're not actually
reducing the style content of your 10 HTML files. You've just renamed a style
to a class. Sure you've reduced some possibilities but you've actually made
the situation worse because now you have 11 files with style information.
You've added new names for basic styles which adds even more complexity.

If you take that idea of reducing style possibilities to the logic extreme
then you wouldn't be using classes like "bg-red" and "pt-10" anyway. You'd
just do what everyone already does with CSS and abstract your styles
appropriately.

------
jekrb
My experience with functional CSS was skepticism followed by delight. Reading
BEM style actually makes me more skeptical now. A class of "Button
Button__Primary" tells me much less about the styles of that button than a
string of functional CSS classes would.

~~~
HelloNurse
When the customer asks me to change the background of primary buttons from
green to yellow and the background of nonprimary buttons to red, while
changing other green backgrounds to a green-brown gradient, classes like
"Button Button__Primary" tell me much more than classes like "bg-green".

~~~
cmccomas
Your customers speak a different language than most of mine. The requests are
more like "I need the green buttons to be yellow now!" It's easy to find bg-
green on buttons and just find/replace with bg-yellow.

Also, using Tailwind/functional CSS for items that are repeated over and over
on your site like buttons, you can easily extract them to a component.
Switching from bg-green to bg-yellow would be as simple as opening your
SASS/LESS file for components or button components and replacing it in that
one spot.

~~~
marcosdumay
> It's easy to find bg-green on buttons and just find/replace with bg-yellow.

Oh, that's because running sed over all your project files, all in a set of
weak typed languages is easier than changing a definition in a single place. I
totally get it.

------
bootsz
Everything old is new again (sort of). There was a similar paradigm being
promoted several years back that was dubbed "Object-Oriented CSS (OOCSS)":
[https://www.smashingmagazine.com/2011/12/an-introduction-
to-...](https://www.smashingmagazine.com/2011/12/an-introduction-to-object-
oriented-css-oocss/)

It's a little unfortunate that the use of the terms "functional" and "object-
oriented" were chosen in these cases as they can easily be confused with
functional vs. OO programming, when in reality CSS or any paradigm of writing
CSS has nothing to do with this distinction.

~~~
yakshaving_jgt
This was my first thought too.

There's nothing novel here. There's just a misunderstanding of how CSS works,
an over-engineered solution to a non-existent problem, and then a misused name
added for a veneer of sophistication.

------
DanielBMarkham
Neat.

Now add a way to hierarchically roll-up these micro-classes into semantic
classes behind the scenes (Perhaps in webkit?). Compile things so you only
carry-around the css micro-classes you've used, and make a flag to either
deploy using the semantic or micro class method.

Best of both worlds. There are also some other mix-and-match ways of doing
this. Where the real value is separating the tiny CSS adjustments you make
from the business-class stuff, creating a middle tier (which this guy deploys
directly)

It might make things easier. Or it could be yet another dumpster fire. I think
it depends on how it's used.

~~~
Flenser
You could do this with SASS or LESS.

Make all the "functional" classes as _abstract_ mixins or placeholder
selectors (in SASS parlance), and then use them to define your _concrete_
semantic classes.

~~~
Semaphor
variables and mixins, clean css, readable templates instead of some overloaded
hodgepodge of classes.

~~~
DanielBMarkham
Yeah. I was reading this thinking "If only we had some way of abstractly
creating CSS!"

Which of course we already do. Maybe there's a case that the toolchain or
conventions need tweaking. So it's worth the discussion in my mind. Most times
you really don't realize what you need from a tool/framework until you've
reinvented it, so we need folks like this doing sanity checks on where the
rest of the industry is going.

------
jasim
Functional CSS changes a mistaken way of thinking about CSS classes: as a unit
of visual abstraction.

When you have a "ProfileCard" class, you expect it to encapsulate the profile
card without leaks, and with perfection. But that is never the case - there
are so many variations of profile cards that almost everyone who uses
"semantic" CSS (BEM, SMACSS etc.) end up with hundreds of tiny variation of
this class, each one of them scoped to their particular container or page. Not
to mention the proliferation of different shades of the same color,
inconsistent typography, and ad-hoc spacings.

The right level of abstraction for user interface is the DOM+CSS; neither of
them stand alone. This idea "separation of concern" has taught us to think of
them in separation, and feel guilty everytime we have messy CSS that breaks
that idea. But it is the idea that is wrong.

The right level of abstraction is the "component". eg: in a React component
library you might have multiple Buttons, each of which is a highly reusable
non-leaky abstraction. Here Functional CSS abstracts a lower granularity:
design tokens/scales. It will give you consistent spacings, colors, and
typography. These two in tandem is a fantastic way to look at building UIs
that are consistent, reusable, and extremely easy to write and maintain.

------
cphoover
I really hate this style.

I think the solution is using elements/components as the means of sharing
styles. If you need a slightly different style you extend and modify an
existing component. This can be achieved using libraries like `styled-jsx`,
`styled-components`. Or hopefully as the shadow-dom spec progresses this will
take care of this issue. I also think doing a way with the `scoped` attribute
on the style tag was a dumb idea. As it made compartmentalization way easier.

------
woodpanel
First of all I love reading arguments about CSS architecture like this, since
even for me doing CSS 19 years now I still haven’t found a „goldstandard“ -
and I think he makes good points.

However, I would be more inclined to use his utility classes as one layer in
an ITCSS architecture and then have component styles that inherit from them,
keeping them away from the markup as much as possible, while allowing to use
those utility classes in the markup for quick prototyping.

------
scotty79
> Also, if you find yourself in a situation where you're using the exact same
> classes in a bunch of different places, that's probably a DRY problem with
> repeated markup, and you should likely consider abstracting that into a
> reusable fragment or template so that you can define it in one place and
> just include it wherever you need it.

This pretty much resolved my objections towards this approach. I think it
makes a lot of sense with react.

------
jpetitcolas
Another interesting CSS framework taking this approach: UniversalCSS:
[https://github.com/marmelab/universal.css](https://github.com/marmelab/universal.css)

A few advantages: self-documented classnames, zero dependencies, classnames
are reusable across projects, removes the need for a CSS preprocessor or
bundler, no need to switch between HTML and CSS file while developing, etc...

------
jacamat
This is all really terrible advice and my only conclusion is that you have
never actually had to maintain websites that use this approach toward CSS as
they grow past being a little one off blog into a large, customer facing, PWA.

With this method of CSS it will take years to consolidate, update and redesign
your application. Ask me how I know. :-)

------
madrox
In the old days, I was doing CSS by hand for every site I made. It kind of
sucked.

Then Bootstrap came out, and the idea of CSS frameworks was a thing. I loved
Bootstrap, but so did a lot of other people, and as a result you started
seeing Bootstrap everywhere...like when you buy a car and you start seeing
everyone else driving one where ever you go.

So I started trying to customize Bootstrap to make it look less like other
bootstrap sites by adding custom CSS, which basically _brought me back to
where I started_.

In practice it has been much, MUCH easier to work with CSS frameworks that use
utility classes, because it makes customization easier. I do think there needs
to be an intermediate layer where it's easy to define semantic classes as
composites of utility classes. I would think this should be possible in the
days of Less, Sass, and precompiled web sites.

------
ARCarr
I tried using Tachyons for a project and it really broke down when I needed to
make really custom components.

For instance, one component was a cropping viewport that had to be a set
height and width. There really isn't any solution for that other than adding a
very specific utility class, or creating a semantic class.

~~~
grabeh
I think the point is that Tachyons should be good for 90/95% of the styling
you want to apply to the site. I think the creator would be the first to say
that if you need something specific which Tachyons can't do you should do that
but it doesn't make Tachyons redundant.

Personally, Tachyons still provides me tremendous value even though I
sometimes have to write custom classes. I'm also often surprised to find that
something that I thought would need a custom class, could be done with
Tachyons when I dug a bit deeper.

------
mellett68
We did this for a project a few years ago and it was alright. In the end we
decided against doing it again purely because the DOM became so extreme with
one-rule classes that it became a nightmare to read the templates. So much
noise.

For building things out and prototyping it was amazing though.

On the plus side our css file was so tiny.

------
koboll
Most of the "a lot to love" points are also hit by BEM/SMACSS. In regard to
this point:

>You never have to deal with one instance of a thing needing a slightly
different style than the other instances, which screws up your reusable
classes.

...what I found was that just as often, I'd need a new Atomic class different
in a subtle way from existing ones, and this was annoying to implement because

a) it expands the kludge-dictionary of short class names you have to memorize,
but often in a way that's too situational for anyone to actually memorize it,
meaning the next time someone runs into the same problem they will re-invent
the same solution rather than reread the entire list of Atomic classes to see
if one exists, and

b) the whole point of Atomic is that I _shouldn 't_ have to be writing CSS,
and I was, all the time.

~~~
jasim
Tailwind takes care of this. You just need to define your spacings, colors,
typography, and a few other details like borders and shadows, and all the
classes you'll need are all there. You can use PurgeCSS to trim down the final
CSS size to just the classes you use.

------
TimTheTinker
I agree somewhat for web _pages_ , but this looks like a maintenance disaster
for a web app of any significant size. I will probably turn down any offer to
work on a team with a large project that uses this approach, unless fixing it
would be part of my job.

For web apps, I contend that _modularity_ ought to be the goal for HTML, JS,
_and_ CSS. In the project I'm working on now, each widget/component has its
HTML, JS, and CSS together in a single folder. When a widget/component is
first loaded, its CSS is added to the DOM. Each component has a unique parent
class name, and all its markup and styles are nested under it.

Having cross-cutting styles that are re-used throughout the app sounds
decidedly un-modular. Why not re-use components/widgets instead?

------
ljm
More fundamentally speaking, I'm wondering what the intrinsic value of CSS is
when you compare the work involved in building a UI in web-land and native-
land.

I remember once looking up on the proposed alternatives to CSS. One was
basically a lisp, or at least the syntax, as far as I recall it. Think of what
you could do with that!

However the problem now is that the problem CSS intended to solve can only be
considered in terms of CSS itself. I'm curious what other approaches could be
taken if we worked entirely from a clean slate. Would it involve changing the
DOM? Would it require a separate language? Who knows...

CSS works great for websites but not so much for full-blown apps, where you're
programming with a totally different mindset than what the web originally
anticipated.

------
tambourine_man
Problem is, defining quantity in the class name doesn’t work.

.m10 may be fine for desktop but not for mobile.

Then you’ll have media queries which define .m10 as margin: 5px or something,
which is nuts.

You could go for unspecified .mSmall etc, but in real life, things tend to be
more specific and messier, in my experience.

~~~
dsego
In bootstrap 4 you get responsive variants like .m-sm-1 and .m-lg-1. Then you
can have class="m-3 m-sm-1" to have different margins for mobile and desktop.

------
1ba9115454
_> I think that separation of concerns (i.e., the whole idea that the markup
should be completely independent from the styling) is something that has been
burned into our brains because of the history of CSS (trying to get people
away from using tables, sites like CSS Zen Garden, etc.)_

CSS has come a long way since CSS Zen Garden.

With CSS grid and flex, you can create components with less markup and small
amounts of CSS.

The example on the tailwind site [https://tailwindcss.com/docs/what-is-
tailwind/](https://tailwindcss.com/docs/what-is-tailwind/) just looks like a
steep learning curve to me. I could write that same component with much less
HTML and just a few lines of responsive css.

------
jarek83
I believe this type of CSS works well in projects with no real concept or
design - I call it wild-west front-end where you design as you go ending up
with no patterns and real identity.

If it's popeprly designed functional CSS would be exaclty what it actually
looks like - garbage.

------
anotheryou
Can't you do the same with SCSS and at least keep the DOM clean and have it
nest more naturally?

Like include "materialShadow(3)" for a hovering button, but when you want to
build a special card thingy you include "card", which than includes the shadow
already.

------
drinchev
Using sketch / photoshop these days gives you "Copy CSS Attributes"
functionality for most of the elements, which is basically 50% of your CSS,
the rest is layouts ( super easy these days with flex box / grid ), media
queries and probably some more.

I agree that Cascading part of the CSS is very troubling, but I don't think
functional CSS solves it in an elegant way. Actually I think it's hardly
readable and confusing :(

As of the argument that you don't need to write CSS properties anymore, I
would suggest using a plugin like Emmet [1].

(1): [https://docs.emmet.io/css-abbreviations/](https://docs.emmet.io/css-
abbreviations/)

------
jacamat
I don’t get why people are still defending this method of CSS. When - or,
perhaps I should say 'if' \- your webapp has to scale you will realize the
enormous amount of problems you’ve created for yourself using this method of
CSS.

------
mcherm
I'm not particularly good at identifying satire, but this is a joke, right?

I mean, the ONE BEST THING about CSS is its ability to promote consistent
styling across a site by creating REUSABLE, NAMED styles that are SEMANTIC and
applying them consistently.

Let us run through the author's claimed list of advantages:

> You don't have to write any CSS of your own (which, to me, is fantastic)

This one is an obvious troll.

> You can likely build things faster (obviously non-scientific, but
> anecdotally I've seen many people confirm this)

The combination of "likely" and "obviously non-scientific" undermines this
claim (and rightly so) in the middle of making it.

> You don't ever have to think about naming things

Again, I presume this is a troll. Naming things is hard _if you care about
having meaningful names_. If you don't care, then naming is trivial. This
approach eliminates meaningful names so it is hardly a benefit.

> You can tell what something looks like by just reading the markup for it

That one is an actual advantage, and makes me wonder slightly what's going on.

> You don't ever have to worry that changing the styles for one thing will
> break something else (which may make visual regression testing irrelevant)

Another obvious troll. If you never reuse anything, you'll never have to worry
about a change breaking anything else. Also true if you never change anything.
Also completely meaningless.

> You never have to deal with one instance of a thing needing a slightly
> different style than the other instances, which screws up your reusable
> classes.

True enough... if you never reuse anything, then you never need to worry about
the impacts of reuse.

> Your CSS always stays the same size rather than expanding over time

Well, sure! If you move all of the intent out of the CSS file and into longer
and more complex style attributes, then the CSS file itself will get shorter
(while the length of the CSS file PLUS the style attributes will get longer).

> It's easy to un-apply a style by just removing the class (as opposed to the
> traditional cascade where you typically have to override, adding even more
> CSS)

This isn't even well-considered. Using a fixed set of single-visual-effect-
not-semantic-intent styles will have no effect on the complexity of cascading.
Choosing to apply styles only to individual elements and eschew the use of
cascading WILL avoid all the complexity of cascading, but the choice to do
that is independent.

> Rendering speed performance is supposedly improved (though I have seen no
> proof of this)

There is no reason this would be true, and the author isn't even claiming it.

After reading it through, I am beginning to seriously doubt that this was
intended as satire. In which case the author is very, VERY wrong. I continue
to hope that I am simply missing the joke.

~~~
nickdandakis
Same thoughts as you, and it looks like we both went through the benefits
line-by-line with a comment in this thread!

It sounds like the author wants Functional CSS to be the Ultimate CSS
Solution™, when in most cases, you can write better CSS and/or stick to a
design system and/or plan out and manage your components better.

------
tracker1
I think, in the end, I'd much rather use JavaScript + React + react-jss for
this kind of work. It's actually really nice with material-ui and re-using
most options from the theme and/or existing components. yeah, 2/3 of my app
come from react-dom and material-ui, but at the same time it's very
consistent, easy to inherit from and easier to comprehend.

Web-Components may help someday, but so long as component properties are
effectively strings, and hard to pass in from the outside, same for events, it
makes it harder to manage discreetly.

------
devit
This "functional CSS" approach is obviously wrong.

It causes repetition that would be avoided by defining a single CSS class
(this can and probably should be done inside in the file defining the
component), and also prevents making appearance changes outside of the
component (e.g. in non-component JavaScript or with a CSS-changing browser
extension).

If you want to obfuscate the semantics, then "minimized" class names are a
better solution.

If you don't care about repetition, then inline styles are just as good, and
actually better since you can for instance use any of the 2^24 sRGB colors.

None of the "downsides" listed in the document are reasonable arguments:

> Inline styles don't respect media queries, which basically rules out
> responsive design

"Utility classes" also don't, unless you define one for each possible media
query and style (that's > 2^16 possible widths, > 2^16 possible heights, > 2^8
attributes...).

> Inline styles aren't limited to pre-defined options, meaning you can still
> end up with 90 different shades of blue

That's a downside, and also CSS has built-in color names.

> Inline styles cause specificity issues, since they trump separate
> stylesheets.

Use !important.

> Inline styles don't support print-specific styles.

True I suppose, but nobody cares about printing webpages nowadays, and those
who are meticulous enough to care probably aren't choosing between inline
styles and utility classes since they are both bad approaches.

> Inline styles can't address pseudo-elements (such as ::before and ::after)

You can just put the content in the HTML itself if you are explicitly
specifying the appearance.

> Inline styles can't apply to multiple elements. Utility classes can define
> .bg-blue once and have it apply to many things, which leads to shorter
> markup and quicker rendering speed.

class="bg-blue" has to be repeated just as much as the equivalent background
style...

> Inline styles are a pain to type. Compare class="f-sm bg-blue" to
> style="font-size: 10px; background-color: #0000ff;".

You should use IDEs with autocomplete, and then they are going to be easier to
type, and most importantly developers already know them and can thus easily
read and write them without consulting any documentation or CSS file.

~~~
dsego
> CSS has built-in color names.

You can't be serious can you? Css has what around 150 color names? That is jut
not good enough for any serious work.

> Use !important.

Please don't use !important, avoid it as much as possible. It just compounds
the issue.

> class="bg-blue" has to be repeated just as much as the equivalent background
> style

But the definition of what shade of blue we're using is in only one place.
Forget bg-blue and think of theme-blue, theme-blue-highlight, theme-blue-mid
and so on. A professional design needs vocabulary.

> You should use IDEs with autocomplete

Do these IDEs help with reading and interpretation?

------
Existenceblinks
The way people using CSS ties to the way they write markup. I like to think
like thinking about Big O; read, insert, delete, update. Database design
involves this kind of thinking too. What operation you do most on your data
structure (html in this case)

Atomic CSS

What's time complexity for each operation(by human)?

Read: O(sigh)

Insert: O(1)

Delete: O(n)

Update: O(n)

Pre-BEM era CSS

What's time complexity for each operation(by human)?

Read: kinda O(1)

Insert: O(1)

Delete: O(1) without garbage collect (unused css)

Update: kinda O(n^n)

That's a quick thought, maybe your operations are more arbitrary.

Probably when someone introduces new css framework/technique, showing some
kind of complexity measurement (if possible) would be good idea?

------
mind-blight
I've been a semantic CSS proponent for years, but I'm intrigued. CSS puts
everything in a global namespace, which is an anti-pattern everywhere else.
Most modern approaches have been moving towards limiting the scope of
Cascading (CSS Module, Styled Components).

The semantic approach forces you to generalize your HTML up front and leads to
over-engineering styles. Plus JS component libraries make refactoring across a
project a lot simpler.

------
sbussard
The everydollar web app used to have a lot of utility classes and it was a
nightmare to work on. We've spent a lot of engineering hours cleaning that up.
I suppose if you were completely strict about only using utility classes you
might get a little farther, but I still wouldn't recommend utility classes.
The best idea I've seen is utility SCSS mixins applied behind the scenes to
BEM classes or locally scoped css.

------
Rumudiez
I moved away from “utility-first” CSS in favor of heavy usage of SASS mixins.
If you can modularize your CSS to the degree shown in Tailwind, then you can
get the best of both worlds by keeping your class names in BEM while the
underlying SASS is primarily composed mixins.

Referencing the OP’s example in short:

    
    
      #m-5 {
        margin: 20px;
      }
      .card {
        @extend #m-5;
        /* custom styles */
      }
    

Edit: formatting

------
aphextron
Has anyone ever maintained an SCSS codebase like this, with all kinds of
logic, mixins, deep nesting, and variables? It's a nightmare.

Keep your CSS as absolutely shallow, declarative, and "noun-based" as
possible. Stay away from utility classes and "adjective-based" classes.
Preferably everything should be within it's own component (React/Vue/Web
component/etc.).

------
gwbas1c
I'm still a little confused. The wording in the example makes it difficult to
figure out which example is really "functional css"

------
dyeje
Like most things, the best approach lies somewhere in the middle. I’ve had a
lot of success with using component driven CSS (BEM, SMACSS, etc style) in
combination with utility classes. The components keep everything consistent
and make building pages much faster. The utility classes let you do the
inevitable little tweaks without a bunch of one off, weird component modifier
classes.

------
hesarenu
After using bootstrap4 i have come to use this approach more often. Its just
easy to use d-flex, justify-content- _, p-_ , m-* classes to construct a
component.

After reading [https://adamwathan.me/css-utility-classes-and-separation-
of-...](https://adamwathan.me/css-utility-classes-and-separation-of-concerns/)
i might use it even more!

------
masklinn
That seems much more procedural than functional. There's nothing functional
about "set this element a 5px margin and a light gray text and a darker
background and a light gray border" which is quite literally the statement of
the first snippet's @class.

Composing .profile-card out of these _could_ be a functional approach, but
you're just writing @style via @class.

------
pruett
I think producing atomic css classes falls should be done by a computer.
[Styletron]([https://github.com/styletron/styletron](https://github.com/styletron/styletron))
and [CSS Blocks]([https://css-blocks.com/](https://css-blocks.com/)) comes to
mind.

------
mcamac
If using React and looking for a similar approach -- check out Rebass and
styled-system ([https://github.com/jxnblk/styled-
system](https://github.com/jxnblk/styled-system)). Their APIs are a pleasure
to work with

------
bsaul
I’m about to start writing a very simple html page ( think search panel +
result table underneath) after having stayed out of html for a few years. What
are the current best practices regarding css tools and framework that could
make my life easier ?

~~~
matt4077
HTML + CSS, pure and simple. Don't overthink. Frameworks like bootstrap were
useful back when they started: column layout (and other popular patterns) were
hard to achieve, and each browser (and version) had their own quirks to work
around.

Today, CSS Grid and Flexbox are easier and more powerful than any framework,
and aside from bleeding-edge features the major browsers have converged.

~~~
bsaul
thanks, indeed last time i checked (a few years ago), flexbox weren't really
widespread. I think i'll stick to that.

------
typeformer
I use Webflow so I don't have to deal with these types of decisions.

------
nickdandakis
The benefits?

> You don't have to write any CSS of your own (which, to me, is fantastic)

This applies to any CSS or UI framework.

> You can likely build things faster (obviously non-scientific, but
> anecdotally I've seen many people confirm this)

Yes, this is anecdotal and debatable. At the end of the day, you still have to
read the documentation of __this __specific CSS framework.

> You don't ever have to think about naming things

I don't think developers that are creating anything don't ever have to think
about naming things. If you're creating something, you have to name it. But
yes, you don't have to add that name to your CSS class.

> You can tell what something looks like by just reading the markup for it

You could also tell what something looks like by just reading the CSS for it.

> You don't ever have to worry that changing the styles for one thing will
> break something else (which may make visual regression testing irrelevant)

There's a couple other approaches to this like style localization/isolation
that the author called "ton of crazy randomly-generated class names". As
opposed to the ton of single-purpose utility class names, which is more sane?
You could also write stricter CSS selectors (like BEM or your own).

> You never have to deal with one instance of a thing needing a slightly
> different style than the other instances, which screws up your reusable
> classes.

Sure, as long as if you stick to a framework. If you're building a one-off
with no collaboration with other people, then this is easier to pull off with
an off-the-shelf CSS/UI framework.

> Your CSS always stays the same size rather than expanding over time

Okay!

> It's easy to un-apply a style by just removing the class (as opposed to the
> traditional cascade where you typically have to override, adding even more
> CSS)

You could isolate styles that are prone to removal into a single class with
regular CSS too. Hate to be the nerd to say this, but the "Cascade" in CSS is
what makes it such a versatile interface styling engine.

> Rendering speed performance is supposedly improved (though I have seen no
> proof of this)

Once again, anecdotal.

————

Sounds like the author is allergic to reading/writing CSS and wants the markup
to be heavily coupled with styling. Also sounds like having a strict framework
makes their developer experience happy, which is applicable to any well-
designed design system.

There's nothing wrong with any specific CSS methodology or framework, and
there's a time and place for every single one of them.

I think I would prefer vanilla CSS with strict rules for one-offs before using
something like this, though.

------
newsbinator
I like using functional CSS for utility classes

e.g.

> .mb-1 {margin-bottom: 1rem}

> .text-center {text-align: center;}

> .flex {display:flex;}

But why would you give up the templating win of CSS?

Make a standard button class.

When you want it to have a different (standard) margin, use a utility class on
it.

~~~
aphextron
>When you want it to have a different (standard) margin, use a utility class
on it.

Then when the next PM wants this button to be blue, you make another utility
class and end up editing HTML. It's better to just think entirely in terms of
components that are independent of any external framework or guideline, which
are only responsible for themselves. Everything on your page is a concrete
implementation of an abstract component, and in that implementation you can
customize all you want. Otherwise you end up with a massive dependency graph
between components of various "utility classes" rather than a completely flat
hierarchy of components which handle their own dependencies.

~~~
wvenable
> Then when the next PM wants this button to be blue, you make another utility
> class and end up editing HTML.

So you're suggestion that when the PM wants this button to be blue, you make
another component for that button? You haven't changed the problem, or the
amount of work, you are just using a different layer to implement it.

~~~
aphextron
> You haven't changed the problem, or the amount of work, you are just using a
> different layer to implement it.

Changing the layer you're implementing on is the whole point. It's about
maintainability and keeping things encapsulated.

Now when someone comes back to look at this button a year later, they're not
left wondering why this usage of "Button" is colored blue, and tracking down
the utility class. They will know that it's an instance of "BlueButton" and
can just edit the component directly.

~~~
wvenable
How is a component called BlueButton more informative than <button
class="blue">? The information content is _exactly_ the same.

Now, more than likely the component isn't called BlueButton and the CSS class
isn't called "blue" but rather both would have a name more semantically
appropriate.

------
tannhaeuser
Found myself in agreement up until the concept of "semantic CSS class names".
If you want semantic markup, then CSS is absolutely not the place to implement
it IMHO.

~~~
williamdclt
It doesn't seem to me that the author defends semantic class names

------
icholy
I see functional css classes as a better primitive than raw css. Using
tacyon's + less, all my classes can be composed from functional classes. Best
of both worlds.

------
Brosper
Today is the day I deleted last atomic class in my project. It was a long
journey but it was worth it!

------
barryhoodlum
Functional CSS reminds me of React and JSX - there are plenty of people who
will argue at length what a bad idea it is, having not tried it.

------
therufa
i don't see a big difference here to plain inline styles. seems to be very
inconvenient

------
sleepychu
Font + colour scheme made this article unreadable.

~~~
mellett68
I found the background colour a bit easier on the eyes personally. The font is
a bit ugly though.

------
aaaaaaaaaab
As a native-focused engineer I find it fascinating how web developers always
find new ways to make their platform even worse than it already is...

------
callesgg
[deleted]

~~~
hobofan
The second paragraph "Isn't that basically the same thing as inline styles?"
discusses exactly that.

