You could put the style right in the HTML tag, or on the page where it's used, but with dynamic pages (and static stylesheets) both options will cost you bandwidth.
And they split up your styles into separate places.
So putting the style on the id is the right thing to do, and I don't understand why the author is against it.
If I need my footer to look a certain way, then #footer {} is exactly what you should do.
Not add some bogus class based style just in case someone decides we need two footers on one page.
My simple rule for id vs class (as a non-expert) is if you say 'this is the x' e.g. 'this is the footer/header/navigation-panel' then it's an Id, if you would say 'this is a y' e.g. 'this the a product/list-item/image' then it's a class.
If you made it a class, I would assume I can reuse it elsewhere.
Now it's ony true for stuff you can't reuse, but unless you are building a boostrap competitors, there are actually a lot of things you never reuse in a real website.
Shared stylistic properties for components use class names. The properties that make a navbar look like a navbar(color, font, and anything that applies to children) would be specified under ".nav" and the same would apply for the body under ".body". Anything that's stylistically-specific to
Shared variations of components are handled with modifiers. An example would be ".nav--dark".
Any one-off variations are handled with parent-scoped class names like ".article__nav", since I treat even that topmost element as a component. (or a block if you're thinking in BEM).
I've found that keeping "style" and "layout" CSS properties separate helps keep components flexible and untangled from a given page layout. The differentiation between IDs and class names makes this more convenient because it becomes obvious what parts of my CSS are intended for.
But what about the internal layout of components? If the children of a component are supposed to change their sizing and positioning at different breakpoints, then how are you supposed to achieve this while keeping components agnostic about the page layout?
It's a tricky problem, but I solve this with Sass mixins. If a component has different internal layouts for mobile and tablet screens, as an example, I write mixins to define those states using the same naming convention that I would use with class names and IDs. If I was using a grid system, I would define them as "@nav--lg", "@nav--md", "@nav--sm", "@nav--xs", etc. Then underneath the page layout, in this case "#article", I would include those mixins under the chosen breakpoints. That way, all layout can be handled by IDs in stylesheets dedicated to page layouts.
It just so happens that I have a Codepen that demonstrates this idea:
https://codepen.io/Ravenstine/pen/xpYoWv
The only part that is different is that I made the masthead and the footer not a part of "#article". If you don't plan on having components like that behave differently depending on the page they are on, that's probably appropriate.
If you don't have much resuable stuff on your site, that's a code smell in itself
It can be reusable and yet unique on each page. And those should get id's, and are not rare at all.
> The percentage of things on a page that are "singletons" is very small compared to reusable widgets.
That isn't necessarily true. Obviously there are different types of pages, but a typical page will have a number of elements on it that are each unique. (They might appear on more than one page, but on any particular page, they are unique.)
Give them id's, that's what they are for.
If you have a choice, use class, then if you need to modify a specific use of the class, use id.
I would still use .footer instead of #footer. Of course you should consider <footer> as well.
<div class="footer special enterprise">
.footer.special.enterprise {
background-color: blue;
}Way more self describing. No team member will ask which one is reusable and which one is not.
This list also assumes the use of a CSS pre-processor.
I have learned to simply accept css for what it is: An unholy legacy kludge we have to live with. Just don't let's speculate on the millions and millions of wasted man-hours over the years.
Welcome to css-tricks.com [0], where you will learn all the current trends. I am a regular reader for things just like this. Where you just want to know what's new and where things are going. Plus they have an amazing stockpile of CSS examples.
Second only to Mozilla Developer Network. [1]
<div class="my-block my-block__my-element my-block__my-element--my-modifier">
becomes <div my-block="my-element my-modifier">
This solves for specificity, and uses built-in CSS features instead of a "manual" workaround. <div class="block">
<div class="block__item">
I am an item
</div>
<div class="block__item block__item--danger">
I am a dangerous item
</div>
</div>
Your simplification relies on an HTML hack and can potentially be more confusing when modifier names start colliding.https://www.smashingmagazine.com/2013/08/semantic-css-with-i...
<div data-my-block="my-element my-modifier">
It's still shorter, more readable and avoids repetitions. The difference becomes even more pronounced as the complexity of your styling goes up.This helped me deliver maintainable and reliable stylesheets that other devs like.
Most importantly using only class names you will gain :
1. Your HTML / CSS is easier to maintain.
2. Is faster to develop.
3. Is faster to refactor.
4. Is more portable.
5. Is faster for the browser.
I even wrote a blog post about it [1].
Maybe I am stupid here, but doesn't SCSS just render out to CSS?
Saying scss is pointless because it outputs regular css is the same as saying that es6 is pointless because it can be represented as regular es5.
SASS, BAM, OOCSS, etc are all good practices. You can/will abuse those as well without proper understanding and planning.
I've seen far too many bad languages come and go to believe that anymore. People used to say that about PHP and VB6 too.
PHP eventually stopped with the "only bad programmers use me badly" and grew up, and VB6 died. A win in both cases.
CSS could be far better; and bad practices won't disappear until doing it the right way is easier than doing it the wrong way.
[data-controller="user_controller"][data-action="new"] {
.header {
background-color: blue;
}
}
This method keeps you organized and completely removes the biggest problem most people have with CSS.This stems from the fact that I have inherited the task of re-writing a very large (at least for one person, I feel) task of re-writing an internal framework that is really gotten too burdensome to add anything to. I have been contemplating instead of trying to get crazy with a ton of different selectors where you end up with a pattern like this:
``` .selector .selector1 li, .selector .selector1 li a { some-style: some-value; } ```
Which I find A little crazy compared to something like this:
``` [class*="selector selector1] { some-style: some value; } ```
or my person favorite:
``` ul > li > a { color: blue; } ```
While these examples are I think very simplistic (I don't wanna junk up the page with tons of stuff) I've met alot of resistance to this idea, and splunking other frameworks for inspiration (Shout out to https://bulma.io ! I like their work, its really wonderful FYI.) I don't see alot of this.
While the resistance I've met from others who have some input on this project (and rightly so, they're also part of our stellar in house design team) seem to resist this idea, but haven't articulated why.
I was wondering if it comes down to: is there actually an issue with using these heavily vs some of the older semantics or, which I feel is quite possible, people have done things for so long one way its hard to see another way?
While its seemingly less verbose sometimes (not always) I feel like the new selectors give you a way to combat specificity problems by controlling when context around your classes is better than having ton of different classes and nesting those over and over.
Am i missing something?
ul > li > a
.selector .selector1 li a
The system will check ALL anchor tags and move left until it has completely matched the rule. This makes the above selectors extremely expensive (perfomance-wise) and can cause slow page-loads. Tag selectors and universal selectors are generally a bad idea for this same reason.And using inheritance to select elements indirectly is actually better for performance than directly selecting the inheriting elements. For example, if you want to set typography for an entire page, instead of selecting all p and h1 tags, just select the body tag.
Here's a link to a more in-depth explanation of all of the above with examples:
You could probably construct situations with very deep selector relationships and thousands of matching elements where the ancestor walking adds up but the other costs of computing style often end up being more important than the selector matching in many scenarios. Not that you shouldn't aim for simpler selectors of course.
(Usually the problems with expensive selectors come from side effects of dynamic changes to the document. ex. Some selectors will make the browser recompute hundreds of elements when only changing something small because the browser isn't tracking that relationship in a precise way.)
This is an odd statement, considering that the C is CSS is "cascading". Maybe it's a perspective issue, because I really enjoy the cascading part of CSS. Don't you think it's better that we _don't_ have to set a color for each element/child element individually?
[1]https://hacks.mozilla.org/2017/08/inside-a-super-fast-css-en...
If you're talking about the difference of:
.a { ... } .b { ... } .ab { ... }
<div class="a b"></div> <div class="ab"></div>
It's probably not going to matter a lot. It's two map lookups vs one, and some associated overhead. Probably better to optimize elsewhere. :)
Isn't that the case with Javascript?
Object internal state is generally true, if you're using prototypal objects. Use function closures when you need to internalize something.
Speaking of which, anything hidden via closure is truly hidden and can't be overridden. Anything public can be overridden, excepting objects frozen via the ES5 spec's Object.freeze method.
I generally enjoy most aspects of JS, and generally detest working with CSS, in large part because I delegate interacting with many browser APIs to JS libraries, whereas there's no escaping the awfulness that is years of backwards compatibility with incompatible vendor specs and CSS implementations.
I suspect I'll be happier once CSS Grids are universally supported (properly) among all of the browsers I need to target, and use postcss for the rest.
This is the go-to article I send to newbies struggling with z-index. https://hackernoon.com/my-approach-to-using-z-index-eca67feb...
So much more logical to write and maintain than plain CSS for a site of any reasonable complexity. You can still apply global styles where they make sense (e.g. styling all body text) and making use of JavaScript patterns for reusing common chunks of styling feels much more robust than the CSS equivalent.
As someone who can do CSS but doesn’t do so that often, I can confirm that it’s getting better with things like Flexbox and Grid, but it is still full of maddening quirks! I do have a lot of respect for people who are CSS experts.
That’s my only real sticking point here.
One of the things I've been doing recently that helps debugging a lot is to group the attributes within a css class into three, separated by a line.
1) Things that control where the item shows up.
2) Things that control the overall appearance of the item, like size and background.
3) Things that control appearance of things within the item, like font color.
Please don't. Tags have semantics for important reasons. Even if you're removing one of those by overriding the default styles, the semantics of tags are still used e.g. for screenreaders. It's not a mistake that HTML 5 added a ton of new semantic tags like <article>, <header>, <footer>, <aside> and <nav>.
If my understanding is correct, the argument is to use
<style>
.my-article {
background-color: fuchsia;
}
</style>
<article class="my-article">...</article>
rather than <style>
article {
background-color: fuchsia;
}
</style>
<article>...</article> z-index: 2147483647;z-index: 2147483648 !important;
Vertical height of text comes up a lot in CSS. It seems many people do not make liberal enough use of the line-height property. Line height is a magic bullet when you need some text to take up the correct amount of space.
With it, and your element styled to inline-block, of float left, or however you are using it. You are able to modify the font size later on without having any effect on the element's surroundings. It's also automatically centered vertically and you can change it without much effort.
Not enough people using line-height.
$some-element-z-index: 1 + max(
$other-element-z-index,
$should-be-below-z-index
);
This way the relationship between elements that should be below or above is more explicit.In my head, it works a bit like a spreadsheet. You update the z-index value of an element somewhere below, and all the z-indexes that depend on it update their value too.
EDIT: Perhaps by implementing the whole browser in WASM? Would that even make sense?
Modular CSS I think is a huge step forward - I totally agree that global scope is killer. As much as people love to hate on CSS-in-JS, I enjoy using styled-components a lot. I've noticed since using it I've been composing CSS instead of inheriting or overriding styles.
This is just the nature of web development - almost every tech in the stack is flawed, but tools and best practices make some sanity out of the chaos.
.rabbit.drivingACar.onIce.withRocketBoosters {
color: pink; /* pretty specific */
}Instead of quitting front-end dev, you might also consider using https://www.styled-components.com/
Styled-components solves all of the issues the author highlights in his writeup.
Bonus: styled-components works both on web and on React Native! So you don't have to throw out all your stuff to participate in the post-browser future...