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.
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.
>> 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.
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":
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.
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.
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.
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.
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.
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.
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.
CSS classnames are purely for the developer's benefit. Not the user's. And as developers, forcing ourselves to find semantic meaning for every element we write leads us to component-oriented CSS like BEM. Which is a fine thing, but we can also use purely visual classes - like `bg-red bold border-solid` if it helps (and it does. check out tachyons.io)
The class names of elements in Google's homepage for example reads like 'tsf-p', `oq`, `gsb` etc. I suspect these are machine generated. Same with Facebook. One of the best libraries to do this currently is styled-components (https://github.com/styled-components/styled-components).
Consider reading http://nicolasgallagher.com/about-html-semantics-front-end-a..., http://mrmrs.io/writing/2016/03/24/scalable-css/, and http://johnpolacek.com/2016/06/17/atomic-css-movement/ for reasoned perspectives.
When I first discovered csszengarden.com, I realized the point of CSS and its power. HTML was made for hypertext and semantic content structure and CSS was made for appearances. Either one could be completely replaced partially or wholly, separate of each other. Classes are like interfaces[0] which allows for HTML to remain dumb and decoupled from presentation. When the HTML and CSS are hardcoded to specific design concepts themselves, then the usefulness of CSS as in "cascading style sheets" is nearly eliminated. These concepts aren't a fad, this is good software architecture brought to you by an international consortium who's been thinking about it for decades.
0. https://en.wikipedia.org/wiki/Dependency_inversion_principle
Ultimately it comes down to how your CSS is authored, and how your teams works. If you develop in a heavily document-oriented way, and make big use of the cascade, you're most likely to benefit from semantic (rather than presentational) class names. This is because when you make full use of the cascade, markup changes tend to be more expensive (you can't just move a block of HTML from one place to another and not expect its appearance to change).
These days though, we're increasingly building things in a UI-oriented way. What you see on the page is a composition of a number of components. If I move a component from one place to another, I expect it to look the same (with a caveat for responsive layouts) assuming it's still rendered with the same input properties. So now i'm authoring CSS that is bound to the structure of this component, naming becomes a lesser issues. The other thing worth pointing out is that it's not too difficult to built a document-UI (like say a magazine) using app-UI patterns, but it's rather challenging to do it the other way around.
If the goal is maintainability, then there should be zero industry-wide dogma. Best practices are going to be coupled to the methodology of the maintaining team. Personally, I did document-oriented CSS for 15 years, now i'm doing component-oriented CSS, and the results are much better. Obviously this is just an anecdote, but i'm not alone in this.
This idea that design is a "layer" on top of structure is somewhat offensive to the designer in me. Visual design is (and should forever be) coupled to structure and behaviour. Design is not a higher abstraction, it's something that pervades everything.
What's preventing you from doing this with your presentation login in your stylesheet, and what about this requires you to split your presentation logic between a stylesheet and HTML?
We use components everywhere. We style in stylesheets. Handily we even keep the stylesheets in the same component as the module, thanks to npm-sass / sass-npm.
Whether you style in stylesheets or by some other means (CSS-in-JS?) is an implementation choice rather than something that affects the fundamental pattern. If your components are truly portable, you're already doing things the way I suggest. If they inherit things like fonts and colors from their parent via the cascade rather than via explicit properties, then you don't have truly portable components - their appearance will change when you move them around.
We're specifically talking here about putting styling logic - "left" "shiny" "big" etc - in HTML.
> is an implementation choice rather than something that affects the fundamental pattern.
Sure, you can still use a component pattern with styling split into HTML and stylesheets - it certainly doesn't effect the pattern.
The issue is: when you want to change the appearance of your component, do you want to modify styling logic in two places or one?
Not sure about the screen-readers but when you add a class for, say, "small", it's a bit confusing because you can't guess how it is used when looking from the CSS side. One day, you decide to represent the unimportant text as grey (bad idea) and then you need to find all instances of .small that are used for the unimportant content and change them to .grey (then you discover there already is a class named gray, oh the horror) whereas if you used .unimportant as a class name, your change would be a single line of CSS. Also, "h1 .unimportant { color: something-not-grey }" is way clearer than ".bold.big .small { color: something-not-grey }".
1) Semantic markup for the sake of screen readers (and Google and so on)
2) Separation of concerns for the sake of maintainability
I don't know how separation of concerns cause grief for developers, my experience is the opposite. Separation of concerns not a "fad", it is a fundamental principle of any kind of systems design. That said, it doesn't directly affect users, just as users don't care if you write incomprehensible spaghetti code.
It's a slightly silly argument because really we're arging between slicing something vertically (tech) vs horizontally (components) and the nicer thing is probably to do both - have lots of components with the documents, styles, and behaviour separated out within each component.
Semantic is based on the idea that describing physicality (the function of html/css) is a task natural language is acutely optimized for, while describing the implementation of behavior ("cooking recipes", or the vast majority of programming implementation) is best served by programming languages.
Part of how natural language optimizes for transmitting meaning is by reducing ideal forms of concepts to words based on the exact amount of specificity for conveying meaning between humans. I.e. "horse" instead of "quadrupedal mammal that has a heart and has eyes and has a tongue..." etc.
These 'units of optimized human idea transmission' (read words) are then clarified using a system of modifiers that take care of removing just enough ambiguity that the idea is communicated effectively. "The kindly, gentle lion", "The angry, hungry lion".
The modifiers themselves carry no absolute meaning. A "large ant" may be smaller than a "small planet", but we understand them -- in context -- of the nouns.
Language is littered with other interesting features like this that are designed particularly for this task of describing physicality. Most of which are absent from programmatic implementations of 'languages for describing physicality' like HTML/CSS.
Other key examples of useful cognitive optimization: Plurality, "Three large red buttons" vs "Large red button, large red button"; significant word order, "left floated right aligned column" vs "right floated left aligned" column.
I think the main drawback with using a natural language approach is that the implementation has to be bullet proof. Although everyone uses language, we never have to implement systems of interpreting language from phoneme to neuronal pathway. So even though the benefits are clear, the path forward in mapping language to systems of programmatic physicality isn't exactly straightforward.
When I first heard about Semantic UI, I was excited because I had hoped someone had finally built something like Bootstrap using only Sass/Less mixins that were pure and side effect free (i.e. not littering the global namespace with generically named classes, not dependent on the structure of the HTML). I was disappointed that was not the case and frustrated with the confusion of the usage of "semantic" when its already widely adopted to mean something specific for HTML.
I really wish UI libraries were built on mixins. Pure mixins would allow for reusable component styles and modifiers such as "three large red buttons" to be mixed into semantically-named CSS classes such as "user-controls." Additionally, mixins would allow for media query usage (e.g. I could use a "big red button" for desktop and "small red button" for mobile), allow for more selectiveness about which components/modifiers I want to use (which may reduce the overall size of the CSS), allow for conditional styling logic, and generally be easier to work with in a CSS preprocessor. This facilitates all the goals you've mentioned while being more flexible, open to extension and enabling us to stick to the way HTML/CSS was meant to be used. Maybe you've already considered all of this and have your reasons for not pursuing it. I'm sure it would be much more work to go that way now regardless, although it seems Bootstrap 4 has started heading in that direction.
<div class="ui icon buttons">
<button class="ui button"><i class="bold icon"></i></button>
<button class="ui button"><i class="underline icon"></i></button>
<button class="ui button"><i class="text width icon"></i></button>
</div>
https://semantic-ui.com/elements/button.html <div class="menu" tabindex="-1">
<div class="item" data-value="ad"><i class="ad flag"></i>Andorra</div>
<div class="item" data-value="ae"><i class="ae flag"></i>United Arab Emirates</div>
<div class="item" data-value="af"><i class="af flag"></i>Afghanistan</div>- Can't have anything but plain text: (e.g. no images, bold text etc)
- Can't have a line-break, or somehow wrap text into a 2nd line if entry is too long
One interesting way I have tried is to add third thing. So I can create stylesheet with visual class names (or use 3rd party) and html with semantic ones. After this I create separated stylesheet-html mapping. In practise it's just a sass where I extend semantic classes with visual ones.
I haven't tried this yet on scale but it's very handy for example mapping icons at least.
With tags like <b> or <font>, the meaning of the tags themselves as they're supposed to be understood by the browser is clear. Semantic tags, on the other hand, are supposed to associate meaning to their content.
On the web, though, "semantics" is applied to the problem domain; i.e. "what application am I trying to build with this code", i.e. "what is the meaning of this word with respect to the final user-facing application". Thus, for HTML you get words for the things that are typically build with HTML: web pages. Then you get tags for articles, images, quotes, headers and footers, side bars, etc. These describe the types of content in the page, not how they look.
The "semantic web" is a generalization of this "domain knowledge" idea, providing tools to define your own vocabularies and build applications with them. This approach amounts to creating your own programming language (a new one for each application) in a way that best suit the problem at hand, rather than using a general purpose programming language.
Well isn't the point here that you'd only have to modify the HTML, leaving the CSS alone for the most part?
I've seen people crap out things like #aboutPage #mainContent p:nth-child(2) div button {styles go here} ... because they follow the "separation" concept blindly. And then, you know, a paragraph gets added in later. Made up example but you get the point.