I find
// style.scss
@mixin button($color, $size) { ... }
.download-book {
@include button(
$color: red,
$size: big
);
}
.send-email {
@include button(
$color: blue,
$size: small
);
}
// index.html
<button class="download-book">Download book</button>
<button class="send-email">Send email</button>
much cleaner than // style.scss
.button { ... }
.red { ... }
.blue { ... }
.big { ... }
.small { ... }
// index.html
<button class="button big red">Download book</button>
<button class="button small blue">Send email</button>
1. When you change the visual aspect of an element, you go to the stylesheet and don't go adding/removing classes from the content layer (HTML).2. When using generic names like "button", "big", "small", etc... I always find myself in a naming conflict at some point. The likelihood of semantic names having conflicts is much smaller.
Of course, your CSS file becomes a lot bigger. But when enabling compression, the stylesheets using mixins turn out to be smaller (see https://tech.bellycard.com/blog/sass-mixins-vs-extends-the-d...). Also, your HTML file is likely smaller too when using semantic classes.
A semantic choice of classes should represent the roles that things have in the UI hierarchy: if a "book download" button is the main action of the page, it should have a class of, say "main-action", possibly with an extra "download" class to show UI specific to download actions.
If a "book download" button is just an action, for example a button that is repeated multiple times in a table, then it needs a different class, like "action", still possibly with "download".
This is exactly like properly written HTML is semantic, elements represent hierarchical roles ("nav", "footer"), not their look, nor their content.
Yet your first example has everyone editing CSS files and appending new classes to it all the time, which in my experience is the fastest way to end up with unmaintainable CSS.
Mixins sounded good to me at first, but I've only experienced less maintainability when the CSS was too clever.
css-modules[0] are a nice solution to this. Your nice, simple class names like "button" are transformed as part of build process to something less likely to collide, like "ltuZCYvCyDVU_2kG0Sspr":
>> Of course, your CSS file becomes a lot bigger.
If you use something like webpack and you start splitting code based on the page you are on, this problem goes away as well.
I find that only place the 2nd case makes sense is if you are writing a CSS framework like Bootstrap. Otherwise, I find this way writing CSS increasingly rare.
parent described things like moving the navbar to the left when the html can have it before or after the content on the dom. can you use float:left?
<div class="red pull-left pb3">
<div class="grid row">
<div class="col-xs-4">
when you could look at this: <div class="basket">
<div class="product">
<div class="searchResults">
The latter, aside from sparing your brain endless visual noise, makes it instantly clear how the html maps to the page elements.Taken from http://maintainablecss.com/chapters/semantics/
> If you try to keep visual information out of your HTML, you end up authoring stylesheets designed to nimbly navigate your DOM structure to precisely target elements to style in a way that makes your CSS extremely coupled to the particular site you are building.
As for this technical argument, it's flatly untrue. Writing semantic HTML and the coupling you are referring to are completely orthogonal as long as you are using a tool like Sass / postCSS / etc to author your CSS.
That's because it shouldn't be.
> You shouldn't be using your CSS classes to tag sections, that's what id is for
No, you might can have multiple "products" on the page.
> And now, if I want to change the "basket" style, I'm praying that I didn't break something on the other side of the application. So in order to mitigate that issue, you end up nesting your CSS for safety and now you've re-created your HTML structure with CSS rules and it's incredibly inflexible to changes. I've found that semantic CSS classes are a pipe dream that never pans out.
Absolutely none of this true if you use Sass (or an equivalent) properly.
Why not? Who's reading my HTML? It's not there to be read by a user. HTML is for devs. They're the ones that deal with it.
> No, you might can have multiple "products" on the page.
True, in that case you would use a CSS class with no styling if you need code to select the block.
> Absolutely none of this true if you use Sass (or an equivalent) properly.
It doesn't matter what you use, you can nest your CSS by hand or with Sass. Either way, you now have CSS tightly coupled to your HTML structure and it can be hell to change. I'm literally dealing with this right now (we use sass).
Correct. You make it readable the same reason you make any code readable.
> It doesn't matter what you use, you can nest your CSS by hand or with Sass. Either way, you now have CSS tightly coupled to your HTML structure and it can be hell to change. I'm literally dealing with this right now (we use sass).
No. The whole point is if you use SASS properly you don't have to nest anything unless you want to.
I don't follow at all. One of the biggest selling points of Sass is being able to nest styles. If you don't need to nest styles, then Sass doesn't get you much. But once you start nesting, your CSS is coupled to your HTML. That's absurd.
using sass as you describe is an anti-pattern.
the important thing that sass allows you to do (which CSS should have built in, but doesn't) is to apply chunks of style to a named class. that is, precisely to decouple naming, styling, and html structure. you do this in sass with @extend or @include.
practically, this means i can take canned styles of my own making or from libraries like bootstrap, and then define my semantically named classes in terms of them. this allows composition at any level of granularity, total control over the units of re-use, and clear, readable markup.
There's this dream that you will need to "reskin" your application often, and be able to reuse a bunch of CSS classes all over your codebase. Instead what I've found is that it's better to think of your application as consisting of components with their own styling. Component-oriented frameworks like React are moving in this direction. Take a look at the styled-components library.
There is no way for you to mess up something at the other end of your web app if you use specific sass files for specific web pages. The 'basket' class can be defined as one thing on the page for selling baskets, and it can be defined completely differently on some other page where baskets are, idk, displayed in some other way.
As devs, we can view this html through a browser and use in-browser dev tools to view the associated CSS. There's no need to explain the style in the HTML.
The point is they are orthogonal issues. Creating re-usable chunks of CSS does not suddenly absolve you of the responsibility to make your HTML readable. You can do either one without the other, but you should be doing both.
However, there's no denying the reusability of classes like 'col-xs-4', despite the knee jerk hatred of that 'non-semantic' class from some in this thread, and I maintain that if all you needed was a col-xs-4 and your team know what col-xs-4 is, then why not just stick it in your HTML.
It doesn't make it less 'readable' for your team, and they're the primary audience.
> You can do either one without the other, but you should be doing both.
I guess I'm disagreeing you should always be doing both. Do both (create a new semantic class-name) where it makes sense. But when you already have a reusable class that does the job, and all of your team will understand, just use it.
Also yet to meet one of these 'designers' that would rather change CSS than HTML. And logically ... you can't understand CSS without understanding HTML, so preferring to make the change in CSS is just an arbitrary decision.
http://nicolasgallagher.com/about-html-semantics-front-end-a...
These days I'm quite convinced trying to author your markup such that you can redesign a site by applying a different stylesheet has the dependencies backwards.
If you try to keep visual information out of your HTML, you end up authoring stylesheets designed to nimbly navigate your DOM structure to precisely target elements to style in a way that makes your CSS extremely coupled to the particular site you are building.
Your HTML documents are already coupled to your project, so rather than writing CSS that's coupled to that HTML, I've found it to work much better to author CSS from a mindset that the CSS knows nothing about the document it's trying to style.
This leads to writing what I call "library-style" CSS, where you are almost trying to build your own Bootstrap or similar; something that you could actually use on multiple projects if you wanted.
A class like "download-book" is not very useful if you have multiple buttons in a project that are meant to look the same way and not all of them trigger a book download.