Live data from Hacker News

In defense of functional CSS

mikecr.it

151–160 of 246 posts

Re: In defense of functional CSS

#151

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-...

Thanks for posting this! This article was a really good read that I think communicated the intent behind your original article much better.

Re: In defense of functional CSS

#152

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 on…

You _can_ have the best of both worlds though. For example, styletron[1] lets you write a "button" via something like

    const Button = styled('button', {/* styles here*/});
...and you get deduped atomic classes (plus proper source maps, so the debugging experience is actually pretty similar to vanilla CSS)

There are also more transparent ways to leverage existing functional css frameworks. For example, Mithril.js[2] lets you use CSS selectors in templates, so you can do things like:

    const Button = 'button.some.atomic.classes';
    m(Button) // equivalent to  in JSX
The problem with `class="button button-with-quirks"` has to do with specificity. Yes, you can edit the base class... but then you also need to go hunting for visual regressions anywhere you have a compound class because who knows what might be overwriting your edit and how. Also, your team needs to be extremely disciplined when dealing with 7 slightly different variations of left margin on a button (and usually they are not).

The two most important benefits of functional css that the post doesn't go into that are kinda important to the discussion are these:

- atomic styles can be deduped, making for smaller bundle sizes

- they make it nearly impossible to accrue specificity-related technical debt

Many of the downsides alluded in the article are solved by libraries like styletron.

[1] https://github.com/styletron/styletron/

[2] https://mithril.js.org

Re: In defense of functional CSS

#153

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 on…

Yeah, I really don't get it. As for this part: > 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 You can have this with semantic classnames. In fact, that's exactly what the "cascading"[1] part of "cascading style sheets" was intended to solve. [1]: http://cssspecificity.com/

Cascading is bad and creates more problems than it solves.

Re: In defense of functional CSS

#154

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 on…

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…

> Usually, in a large codebase, I end up just adding a class instead of tweaking one and figuring out if I broke anything anywhere.

It's very easy to just make another CSS class everywhere, but that defeats the point of CSS and you might as well just use inline styles.

Clean well maintained CSS makes a huge difference. The problem is your CSS needs to map to semantic meaning of what's going on, and you need to maintain the effort to keep it clean.

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

How about how often do you need to change all your 'submit' buttons? The HTML element type is again vastly less important than what each element means.

Re: In defense of functional CSS

#155

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 on…

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…

> - 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)? doesn't really seem better than 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.

Re: In defense of functional CSS

#156

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 on…

100% agree with you. I stopped reading after this statement: >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. It's easy to fix in "regular" css too: just add style="margin-top: 10px;" to the button. If this is really a one-off situation, then that is totally fine. Functional CSS feels like over-engineering an already-solved problem.

You totally ignore design systems here. Similar to color palettes you want named styles for consistency and to show purpose (e.g. margin-small, margin-large, etc). Hardcoding margin:10px throws all that away.

Re: In defense of functional CSS

#157
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.

Re: In defense of functional CSS

#158

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 on…

Seriously. This is just inline style with extra steps.

Re: In defense of functional CSS

#159
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.

Re: In defense of functional CSS

#160
post #40

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.

> 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…

No, I'm saying anyone that tries to standardise CSS with a universal theory is wasting theirs and their companies time and resources.

This approach sucks and you end up with "gutter-left-10 skin-primary-blue gutter-bottom-20 row-single col-3 designer-lastminute-overridehack" which is just proxying CSS into class names and does not scale or transfer to anyone you bring onto a project.

BEM is equally awful because you're encoding structural data into the class name which again is just proxying CSS.

Post reply on HN