News for hackers. Stuff that matters.
Re:In defense of functional CSS by crazygringo on Thursday September 27, 2018 @09:35AM (#18084285)
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.

Re:In defense of functional CSS by batmansmk on Thursday September 27, 2018 @11:52AM (#18085650)
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.

Re:In defense of functional CSS by ashelmire on Thursday September 27, 2018 @12:56PM (#18086349)
> - 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.

Re:In defense of functional CSS by RussianCow on Thursday September 27, 2018 @02:04PM (#18087087)
> 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.

We use custom components like this at work, and it actually works quite nicely because you get to see all the different "types" of buttons at a glance by looking at the prop types. Using the component looks something like this:

<Button label="Click me!" primary />

I've found that it's helpful for enforcing consistency, so that you have to go out of your way to apply custom styles to a button (which isn't required 95% of the time). Plus, it helps abstract things that don't have anything to do with the <button> HTML element but are often tied together, like being able to automatically make a button a link without having to wrap it in an <a> tag:

<Button label="Home" href="/" />

It's all minor stuff, but it enforces consistency and keeps you from having to think about CSS classes at all most of the time.

Re:In defense of functional CSS by Izkata on Thursday September 27, 2018 @01:54PM (#18086984)
> 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.

Re:In defense of functional CSS by rhizome on Thursday September 27, 2018 @09:07PM (#18090231)
I want to call this "transverse encapsulation."
Re:In defense of functional CSS by antjanus on Thursday September 27, 2018 @04:34PM (#18088344)
Hey! I'm using basically a Bootstrap-like syntax for my own "framework" at work. We've been running it for almost 4 years so I'd love to respond to everything your saying:

1. it does actually happen but more often than not, individual buttons need some changes.

2. absolutely but that's why we use SCSS to help "cascade" those changes. Unfortunately, those large changes, again, require individual tweaks in some tricky areas.

3. adding classes is always the safer approach. One thing that has helped us is to make sure classes hold little (but valuable!) responsibility.

4. this is an awesome question. So, for us, those little adjustments specified in the post (small margins and so on) were tweaked at component-CSS level while large-changes were kept to our SCSS framework

5. It's basically CSS-in-HTML

So my own experience has taught me a general approach of my own:

1. create a framework for your site in SCSS. This includes basic styles for buttons, input boxes, colors, typography, tables etc. but stay away from more complicated styles (like trying to create CSS for a "profile card")

2. keep "component" CSS inside a component. Profile card CSS goes in profile.component.scss

3. overrides/hacks belong to where those overrides/hacks need to happen.

Re:In defense of functional CSS by darth_mastah on Friday September 28, 2018 @07:33AM (#18092544)
I've been working with the front end for over a decade now in small and big teams, with different approach to CSS. I've seen things go horribly wrong for all the seemingly good reasons. Bloated CSS, people fearing to make any changes to existing "semantic" classes, people making changes to existing classes and introducing unforeseeable bugs in remote parts of the application, you name it. In my view nothing beats functional CSS. It's simple, pragmatic, easy to read and understand. And most importantly it'd hard to introduce hidden bugs with this approach.
Re:In defense of functional CSS by Retric on Thursday September 27, 2018 @12:55PM (#18086341)
> 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 by every_other on Thursday September 27, 2018 @09:44AM (#18084387)
I'm not sure why that was suggested. Our team has migrated to utility css (Tailwind) and we never do this. The basic approaches are either to create a component or template for the button and put the utility class there or use Tailwind's `@apply` utility to create a `.button` class with the utilities applied to that class.

I had some reservations at first but in practice it's been pretty much universally agreed to be great for us. It removes a huge amounts of css cruft that happens over time (unable to determine which classes are still being used, where, etc), keeps colors, margins, etc. standardized through a centralized config file and prevents you from constantly bouncing back and forth between style and markup files.

Re:In defense of functional CSS by arkh on Thursday September 27, 2018 @11:42AM (#18085558)
First line of the first example you get in "what is Tailwind":

  <div class="bg-white
Just accept the fact your HTML contains your styling and go with:

  <div style="background:white"
There was a time when people thought CSS could be used to style some logical HTML:

  <div class="card-wrapper"
So the day you want to change the color of your card-wrapper from white to green you can change a line in some CSS and not have to go around all your HTML or end with a <div class="bg-white"> with a green background.

CSS frameworks feel like a "let's get all the shit CSS was meant to help remove and just put it in divs".

Re:In defense of functional CSS by every_other on Thursday September 27, 2018 @12:03PM (#18085761)
Yeah, think that's everyone's first reaction (you shouldn't mix style and markup) but with a component centered development pattern, those concerns largely become non-issues. `card-wrapper` becomes a component and you update your styles there.

I will just say theory aside, in practice, this has worked out great for our team. In my 5+ years experience, I've constantly run across the issue of legacy code with thousands of classes, referencing potentially non-existent markup and countless one-off tweaks. You can start with the best intentions and organization in your SASS files but eventually things start to get really crufty. Keeping everything in components and keeping styles in the markup alleviates a lot of that.

Re:In defense of functional CSS by sam0x17 on Thursday September 27, 2018 @12:33PM (#18086108)
On that note, would love to see developer tools in the major browsers complain with warnings about missing CSS classes :/
Re:In defense of functional CSS by dwild on Thursday September 27, 2018 @02:21PM (#18087284)
> CSS frameworks feel like a "let's get all the shit CSS was meant to help remove and just put it in divs".

You just made me realize this is why I always have a hard time every time I try a CSS frameworks.

It always goes the same way. I'm first amaze by all what they offer, how simple and quick a great UI can be made. Then when I try to use it, there's always something wrong and I hate how it goes and I always stop and goes back to the logical ways to do it entirely in CSS.

I guess I should try some CSS preprocessor, they must support heritage of CSS class I guess.

Re:In defense of functional CSS by dsego on Thursday September 27, 2018 @03:13PM (#18087695)
You should, you can have mixins, class inheritance, the whole shebang.
Re:In defense of functional CSS by komali2 on Thursday September 27, 2018 @11:19AM (#18085316)
We do this with less + bootstrap. So we'll have have something like

.button-critical{ .btn .btn-red }

Re:In defense of functional CSS by ljm on Thursday September 27, 2018 @11:36AM (#18085489)
This has essentially been my experience with using this. I don't see how it even comes close to 'functional' in style, it just feels like it makes CSS even more painful to deal with than it already is.

Working with CSS is fairly unglamourous. These functional frameworks don't really appear to be a solution to me. What they've done is basically take CSS and create a DSL that has to squeeze into a `class` attribute, without actually adding any extra value than what you would get from writing raw CSS. You don't really get consistency out of it. Just terseness.

This becomes even more bizarre when you see these frameworks used with preprocessors like postcss, because what you end up with then is basically spaghetti.

    .some-button {
      @compose mt-2 my-4 p3 border-radius flex align-bottom;
      margin-right: 32px;
      border-radius-bottom-right: 2rem;

      &:disabled {
        display: none;
      }
    }
At what point did all of this become an advantage?
Re:In defense of functional CSS by lgessler on Thursday September 27, 2018 @10:19AM (#18084711)
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/

Re:In defense of functional CSS by dsego on Thursday September 27, 2018 @12:50PM (#18086291)
Cascading is bad and creates more problems than it solves.
Re:In defense of functional CSS by recursive on Thursday September 27, 2018 @01:49PM (#18086935)
This is definitely the opposite of my experience.
Re:In defense of functional CSS by dsego on Thursday September 27, 2018 @02:08PM (#18087133)
It breaks encapsulation, leaks styles, you have to fight specificity and it makes it hard to change markup and many more.
Re:In defense of functional CSS by jacamat on Thursday September 27, 2018 @02:36PM (#18087396)
You’re 100% correct on the cascade being bad and causing incidental breakage. The people downvoting have clearly not run into these problems yet or it would be obvious to them that your reply is in no way wrong, lol
Re:In defense of functional CSS by dsego on Thursday September 27, 2018 @01:52PM (#18086957)
I see the downvotes already coming. Cascading is bad, it makes it hard or impossible to restructure things and move markup around. And then you have to fight specificity. An example from my work where someone put a bunch of tags under `.new-style` like `.new-style h1` and applies to every container which needs those new styles. Now if I add my component to that container, it completely breaks encapsulation because `.my-component-title` gets overridden by `.new-style h1`. And then you fight that with something ridiculous like repeating classes `.my-component-title.my-component-title`.
Re:In defense of functional CSS by Drdrdrq on Thursday September 27, 2018 @02:12PM (#18087168)
In other words, improperly used cascading is bad? (didn't downvote you FWIW)
Re:In defense of functional CSS by jacamat on Thursday September 27, 2018 @02:43PM (#18087464)
Yes and (moslty) no. Cascading that reaches “outside” of its component to affect other things is bad. So it is all about your approach to the cascade. Most people who have been working on the front end still struggle to grasp the concept of encapsulation & isolation when it comes to their CSS.

In my experience working on a web app that sees +80k DAU, the most difficult updates to our UI are ALWAYS in the cases where somebody wasnt cogniscent of the cascade. Or was, and used it when they shouldn’t have.

IMO, theres a lot of pushback to this technique and not a lot of questions into its benefits, but plenty of questions as to why its “just like this” so “why should I use it.”

I encourage you to consider the benefits of an isolated approach to UI, or perhaps try building something with it and see how the method compares to your current approach.

Or, we can all go on assuming that Airbnb, Facebook, IG, et al, have all opted into this approach for no reason

Re:In defense of functional CSS by SamuelAdams on Thursday September 27, 2018 @10:50AM (#18085037)
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.

Re:In defense of functional CSS by dagenix on Thursday September 27, 2018 @11:24AM (#18085354)
I really hate the phrase "over-engineering". My oppinion is that at this point, its is nothing more than a fancy way to say - "I think this is bad" (or sometimes worse: "I don't understand this, and since I don't understand it, it must be bad").

And this is a great example of that theory. If one had to apply the terms "over" or "under" to describe the engineering of the practice the article describes, it seems like "under engineered" would be the more apt description. This is pure brute force programming and design.

Re:In defense of functional CSS by dsego on Thursday September 27, 2018 @01:07PM (#18086479)
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 by sam0x17 on Thursday September 27, 2018 @12:43PM (#18086209)
The point of this, imo, though, is instead of having a designer design a bunch of components, you have a designer design a bunch of functional styles that can compose components and still be on-brand. So say you have a component, and you want to add an on-brand/in-style shadow to it, you just add the small-shadow class, instead of digging through the css of other components and copy-pasting their lengthy shadow css. I would use this mainly for shadows, fonts, and margins.
Re:In defense of functional CSS by darekkay on Thursday September 27, 2018 @09:59AM (#18084522)
> Because then every time you want to tweak all buttons on the site, you tweak it in one place.

What do you do, when the button markup changes? Let's say you need to make all links open in a new window? Then you still need to change 100 buttons. It's even more common for bigger components, like the ProfileCard example. What if the markup of your ProfileCard changes?

Instead of using CSS to define your components, I suggest using some real reusable components, either using templates or JS frameworks (depending on your use case).

Re:In defense of functional CSS by beaconstudios on Thursday September 27, 2018 @11:33AM (#18085453)
> What do you do, when the button markup changes?

hopefully you'd have a Button component in your preferred UI framework, and you'd change it once there.

Re:In defense of functional CSS by darekkay on Thursday September 27, 2018 @12:02PM (#18085744)
Exactly. The same applies to CSS when using the functional CSS approach. It's basically: if anything changes, I need to update my Button component.
Re:In defense of functional CSS by andrewingram on Thursday September 27, 2018 @12:15PM (#18085871)
Right. With the surge in popularity of components architectures, the maintainability concerns of inline styling methods are much less applicable. Perhaps there are other legitimate problems, but this one should be put to bed.
Re:In defense of functional CSS by yakshaving_jgt on Thursday September 27, 2018 @10:49AM (#18085030)
Open up Vim, and do a global find and replace with a simple regex. That's 100 or even 10,000 button changes in a minute.

That's not really related to "functional CSS" though.

Re:In defense of functional CSS by darekkay on Thursday September 27, 2018 @11:13AM (#18085261)
Your simple regex will take you 1-2 additional minutes to deal with prettified code like this:

  <button
    href=".."
    class="...."
  >Button</button>
And when you start fixing more complex components and HTML edge cases, you will have a lot of fun [0]. This is fine for legacy code. But I don't want to deal with this in modern projects, if I can just change a single file and be sure all components are updated. As you said, this is not related to functional CSS, but it solves many disvantages of it.

[0] https://stackoverflow.com/questions/1732348/regex-match-open...

Re:In defense of functional CSS by lhorie on Thursday September 27, 2018 @12:49PM (#18086286)
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 <Button /> 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 by Semiapies on Thursday September 27, 2018 @08:14PM (#18089988)
Personally, I like a compositional approach, but the "text-color-white" business is just cringeworthy. There's nothing about compositional/functional approach that requires someone to use silly just-above-an-inline-style classes.

    <div class="card notice alert-colors">
        Warning: frobnitz is dangling.  Please address.
    </div>
I gather it's because ridiculously literal styles are the only thing you can offer in an "un-opinionated" functional framework, because you'd otherwise have to engage in some styling.

ETA: And even "alert-colors" could probably be "alert" or the like, if I saw the consistent need to bold the text or whatever in alerts.

Re:In defense of functional CSS by closetohome on Thursday September 27, 2018 @01:18PM (#18086605)
Seriously. This is just inline style with extra steps.
Re:In defense of functional CSS by rvense on Thursday September 27, 2018 @04:01PM (#18088041)
It really isn't. I'd say in some cases it's the opposite.

At my job, we have a mid-size React app where more or less every element has one CSS class with all the styling in it. There used to be more of a framework of reusable styles, but it doesn't get used much any more because it's out of date with what our designers want now. We should fix it, but there's no time because we have to pile on more features to fix later. You know the drill, I'm sure.

But basically, for more or less every HTML tag, there's a custom blob of CSS that's only applied once. This is inline styles, we've just moved them to a different set of files.

Re:In defense of functional CSS by closetohome on Friday September 28, 2018 @01:10PM (#18095019)
I mean in the real world I think the solution is somewhere in between. I use a combination of broad and specific classes so that mass-updates are still easy, but I'm not - as you say - writing a class for every element.
Re:In defense of functional CSS by keb_ on Thursday September 27, 2018 @10:18AM (#18084693)
> 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"?

I think it is more comparable to using function composition, hence the whole "Functional CSS" moniker. The idea is using multiple atomic "functions" (in this case, in the form of classes) to transform an element by composing.

Think like the pipe operator in Elixir:

other_function() |> new_function() |> baz() |> bar() |> foo()

Re:In defense of functional CSS by yakshaving_jgt on Thursday September 27, 2018 @10:52AM (#18085055)
It's actually nothing to do with the pipe operator in Elixir.

In any programming language, the order in which you compose functions is important.

In CSS — and in keeping with your analogy — the order in which "functions" are defined is important.

Re:In defense of functional CSS by strken on Thursday September 27, 2018 @10:16PM (#18090481)
This is a really interesting discussion because it makes me wonder what CSS could have been like if it had cascaded per-element according to the order of classes.
Re:In defense of functional CSS by keb_ on Thursday September 27, 2018 @10:59AM (#18085127)
I never said it has anything to do with the pipe operator, and I did not mean to imply that it is a direct equivalent to the pipe operator. But just as the pipe operator allows you to compose multiple pure functions, the idea with atomic CSS classes is that you are able to compose "pure" classes. The quotes are important here.

Obviously, they are not 100% comparable. CSS is not a programming language.

Re:In defense of functional CSS by yakshaving_jgt on Thursday September 27, 2018 @01:38PM (#18086813)
It's a weak analogy.

In programming, `f . g . h` is not the same as `h . f . g`.

In CSS, `<i class="a b c"></i>` is the same as `<i class="b c a"></i>`.

In programming, the order in which you define functions is not important — it's the order in which you use them which is important.

In CSS, it is the exact opposite.

To further drive the point home: assuming the names of these classes aren't lying, what colour is the text of this element?

<div class="text-red text-blue">foo</div>

It depends on the order in which the classes were defined. This also demonstrates why "pure" is a poor choice of word when describing anything to do with CSS. Nothing here is "pure".

Re:In defense of functional CSS by keb_ on Thursday September 27, 2018 @02:16PM (#18087222)
I understood what you meant. Whether or not I'm supportive of the terminology used for "Functional CSS" is a different story.
Re:In defense of functional CSS by keehun on Thursday September 27, 2018 @09:39AM (#18084330)
It seems like at least his favorite css framework (tailwind) wants you to use @apply instead? https://tailwindcss.com/docs/functions-and-directives#apply
Re:In defense of functional CSS by madrox on Thursday September 27, 2018 @04:41PM (#18088413)
I think this advice is meant for the kind of person that uses CSS frameworks. You seem to be describing problems that don't come up if you're using, say, bootstrap.
Re:In defense of functional CSS by dustingetz on Thursday September 27, 2018 @10:34AM (#18084869)
Functions have rich abstraction capability e.g. they compose and such. CSS has primitive abstraction capabilities (That said, i'm unconvinced, but i'm listening)
Re:In defense of functional CSS by Spivak on Thursday September 27, 2018 @10:22AM (#18084741)
> The author suggests creating button HTML templates instead... but why? That's what CSS already does

I think this is really the core of it, because CSS is kind of bad at it, and just about every project ships with more powerful HTML templating anyway.