Is tilde attribute selector much slower than class selector? - css

In a case like the following, is the performance impact significant?
html
<div class="6u 12u(xsmall)"></div>
css
[class~="6u"] { background-color: red }
/* instead of */
.\36 u { background-color: red }
The advantage is obviously readability.
Edit: I already proposed changing the classes to be eg u6 and not require escaping, but I am asking in the meantime, since I can not change the markup at the moment.

Related

Nesting CSS selectors without increasing specificity

Let's take these three selectors, sorted from the highest specificity to the lowest:
.special-section p { }
.weird-font { }
p { }
Many CSS gurus recommend against nesting like in the first selector .special-section p, because its specificity is high enough that you can't override it with a simple class like .weird-font. I would like to find a way to still achieve nesting like in .special-section p, but without increasing specificity. Something like this:
.weird-font { }
.special-section p /* with hack to decrease specificity */ { }
p { }
Use case:
It's pretty safe to apply defaults for typography and such document-wide using simple selectors like p. However, I would like to change those defaults for a particular section, similar to .special-section p, without having to use hacks to increase the specificity of selectors like .weird-font. I would rather use a hack to decrease the specificity of .special-section p than use a hack to increase the specificity of .weird-font. Is there a way to do this?
You can't decrease the specificity, but you can add an even more specific selector for the exception.
.weird-font, /* Normal weird font */
.special-section p.weird-font /* Override for special section */
{ }
But as you can see, it's a sliding scale. So those gurus are probably right. If you would remove .special-section p, and instead give those P's their own selector .special-section-para or something, then you won't have this problem.
But personally, I don't mind having to add an exception like the one above now and then. I think the whole specifity thing is there for that purpose, and if you need a more specific selector to style something, to me that seems the right thing to do.
A commonly heard solution is to use !important. The problem with !important is that there is only one level of override. If you make a more specific selector, you can override it again with a still even more specific selector. After using !important, you're out of options. More importantly, using !important may interfere with special style sheets that a user may have for increased readability. For that reason I never use !important in a situation like this.
But then again, I don't consider myself a CSS guru. ;)
These days, in 2018, this is getting close to possible.
First of all, CSS4 will have a way that allows you to create more specific selectors without increasing specificity:
:where(.special-section) p {
color: red;
}
This will set the paragraph color inside .special-section to red, but with a specificity of 001 (i.e. the same specificity that a plain p selector would have).
The spec still calls this special pseudo-class :something(), but chances are it's going to be called :where(). (Side note: I really want this to be known as the "honey badger selector").
But that's still in the future.
However, there is actually a way to achieve this today, if you don't have to support IE anymore (or are happy with less-than-perfect fallbacks), and that is by using custom properties a.k.a. CSS variables.
So you want this:
.special-section p { color: red; }
.weird-font { color: magenta; }
p { color: green; }
but with the first part having a specificity that's lower than any selector with a class in it. You can do it like this:
.special-section p { --low-specificity-color: red; }
.weird-font { color: magenta; }
p { color: var(--low-specificity-color, green); }
If you run the below snippet in a modern browser, you should notice that the second paragraph is red, because it's in a special section, but the third paragraph is magenta, because it's .weird-font -- even though .weird-font has 010 specificity and .special-section p has 011.
.special-section p { --low-specificity-color: red; }
.weird-font { color: magenta; }
p { color: var(--low-specificity-color, green); }
<p>This is a paragraph.</p>
<section class="special-section">
<p>This is a paragraph inside a special section.</p>
<p class="weird-font">This is a paragraph with a weird font inside a special section.</p>
</section>
<p class="weird-font">This is a paragraph with a weird font.</p>
<div class="weird-font">This is a div with a weird font.</div>
This works because while the --low-specificity-color is changed with 011 specificity, it is only applied with a 001 specificity.
As a CSS guru, I bemoan the idea of throwing out everything Selectors has to offer just to avoid specificity issues. That's not to say I don't believe the specificity mechanic is flawed, but surely there are less dramatic workarounds for it.
First off: no, you can't decrease the specificity of a selector. Selectors doesn't provide any features with negative specificity levels that would decrease specificity in such a manner. The lowest you can go is *, which has zero specificity (i.e. it does not make a complex selector any more or less specific).
So your only recourse on the selector level is to increase it. Whether you can do this without using hacks depends on your definition of "hack".
The following is what I would consider a hack, because it makes use of a syntactically legal but semantically nonsensical selector like :not(_) that has no obvious purpose but to add a type selector's worth of specificity to a complex selector (which is far from obvious especially to the uninitiated):
.special-section p { }
.weird-font, :not(_).weird-font { }
The following is not what I would consider a hack, because it's something you would do normally anyway. Pretty much the only "issue" with it is that it's an apparent repetition of the lone class selector:
.special-section p { }
.weird-font, .special-section p.weird-font { }
If you consider any sort of extraneous selector for the sake of increasing specificity a hack — which is a perfectly reasonable POV, make no mistake — then the next best thing that isn't a hack is !important.
Personally, I would choose a specificity hack. !important has, ahem, important repercussions that don't come with a specificity hack — remember that !important and specificity have different semantics. For example, you cannot override an !important declaration with an inline style or JavaScript unless they are marked important as well.1
1 In fact, this was my response to Lea Verou when she had a discussion on Twitter some time ago regarding specificity hacks versus !important.
I like to be as specific as is currently necessary. I do like to leave room for future CSS changes, so don't go as specific as possible for the sake of it, such as:
.great-grandfather .grandfather .father .child { }
I will if I have to of course. But taking the example above, if I wanted to override the .child for a particular element that uses this class which has styling which might be like this:
.child {
color: black;
}
I'd go one parent above to override it, if possible:
.father .child {
color: white;
}
Further down the line, if an element on a particular page uses the .child class and in this case I need to override both the .father .child, I'll go one more level of specificity:
.grandfather .father .child {
color: red;
}
Doing it this ensures you don't need to use !important... Which I avoid like the plague as much as possible!

Make LESS remove useless IDs when compiling

One feature I really love with LESS is nested rules. It makes the stylesheet much cleaner that way and you can find an element very quickly.
I was wondering if there's an option when compiling to optimize selectors. For example...
#global {
/* Styles here maybe */
.container {
/* Styles here maybe */
#sidebar {
/* Styles here maybe */
.title {
font-weight: bold;
}
}
}
}
will be compiled to #global .container #sidebar .title { font-weight: bold; }.
But the first two selectors are useless, since #sidebar should be unique in my page.
Is there a way to ask LESS to compile this to #sidebar .title { font-weight: bold; } instead?
Your assumption is wrong that multiple IDs in CSS are redundant. Imagine, as an example, a site where the CMS generates the page type into the output, like that it's the contact page:
<body id="contact">
<section id="content">Blah</section>
</body>
According to your logic, the following piece of CSS would be a candidate for 'optimization':
#contact #content {
background:red;
}
Now however, your home page has <body id="home"> of course in this imaginary CMS. And suddenly the content of your homepage has a red background because you decided to erroneously optimize that #contact selector out of the CSS, while it most certainly shouldn't have a red background according to this rule.
So no, LESS cannot do this because it would break code. If you don't want the selectors, don't use them and don't put them in your code.
Other answers, including the accepted one, have explained convincingly why LESS cannot simplify your nested selectors in the way you want.
Actually, SASS has the ability to do this:
#global {
.container {
#at-root #sidebar {
.title {
font-weight: bold;
The #at-root directive essentially ignores all the higher nesting selectors. I don't know if LESS has something similar. The above compiles into simply
#sidebar {
.title {
font-weight: bold;
But there is a deeper issue here, starting with the fact that you "love" nested rules in LESS. Stop loving them quite so much. I don't know about you, but most people love nested rules because they think it's cool to exactly mimic the hierarchical structure of their HTML. The SASS docs even claim this as a benefit:
Sass will let you nest your CSS selectors in a way that follows the same visual hierarchy of your HTML.
So people with HTML such as
<div class="foo">
<ul>
<li class="item">
write LESS like
.foo {
ul {
li.item {
This is a horrible, horrible idea, It makes the structure of CSS completely dependent on the structure of the HTML. If you change one nesting level in the HTML, your CSS breaks. Often this approach is combined with a lot of rules defined against tag names such as ul instead of class names, which aggravates the dependency, so changing the ul to ol in the HTML breaks the rules again. Or it's combined with rules based on Bootstrap classes such as col-md-6, so if you ever change that to col-md-4 things break again.
CSS rules should be orthogonal to the HTML. They represent a different dimension. They represent styling concepts which are applied selectively throughout and across the HTML.
I am guessing that you wrote
#global {
.container {
#sidebar {
.title {
font-weight: bold;
because you are adopting this mistaken idea of mirroring the HTML structure in your LESS. Then, you notice that this compiles down to having selectors which contain multiple IDs, which you imagine must be inefficient (although, actually, the degree of inefficiency is minimal). You yourself are writing extraneous nesting levels in your LESS, then complaining that they may be slowing down performance!
Worse, you've hard-wired assumptions about the HTML structure into your CSS. It's of no consequence that the sidebar happens to fall inside a .container which is inside a global element. So don't write them. Perhaps at some point you decide to change the container class to container-fluid. Boom, instantly your CSS breaks. What is the point of conditionalizing the fact that the title should be bold on it being contained with a container class, which in any case is a layout-related class that has (or should have) nothing to do with styling? If you're going to duplicate your HTML structure in your CSS using preprocessor nesting, just go back to writing inline styles. At least that way you'll only have one file to change when you change your HTML around.
When designing CSS, you should think just as hard about the design of the rules as you do about the design of classes and methods when writing JS. In this case, you need to ask yourself, "What characterizes the situation where I want some title to be bold? What drives that? What is the nature of boldness? What am I indicating by boldness? What is the semantic notion indicated by boldness?"
Let's say that you want all titles to be bold. Then you simply say that:
.title { font-weight: bold }
Let's say that you want a title to be bold only when it's in the sidebar. Then you simply say that:
#sidebar .title { font-weight: bold; }
My suggestion here is to go cold turkey. Stop using nesting during a withdrawal period. Write rules with the minimum number of selector components. Refactor your classes to have semantic names (such as title-emphasis). Once you're "sober", you can go back to cautiously using LESS's nesting capability when it is useful, such as perhaps for hover:
#boo {
color: red;
&:hover {
color: blue;
}
}
This is actually useful and saves you from writing #boo twice, and groups the rules in an easy-to-understand way.

Should I add a element name in front of '#id' or '.class' selector?

I'm reading the book: CSS Mastery: Advanced Web Standards Solutions, and finding the css code inside is almost writed in this format:
elementName#idName
elementName.className
but, I'm used to write code ignoring element name with this format:
#idName
.className
so, I want to figure out what difference is between the two format.
Actually, I understand when should use type.class. And, I just want to find out the impact when I use type.class insead of only using .class when there is only one kind of tag here.
There must be some impact on performance.
Here's a real life scenario as when to use elementName and when to just use class or id name:
HTML:
<a class="blue">I'm blue and underline</a>
<span class"blue">I'm blue and bold</a>
CSS:
.blue {
color:blue //will make both <a> and <span> blue
}
a.blue {
text-decoration:underline // will make only the <a> tags underline
}
span.blue {
font-weight:bold //will make only the <span> tags bold
}
but remember when it comes to IDs you should not have duplicate IDs on your page anyway, this is more practical for classes
The difference between the two is that the first:
element.class
Is calling the element with that specific class.
And the second:
.class
Is calling all elements that contain this class
I think that the element inclusion in the selector is a holdover from days where some browsers required it (I think IE5 does, but I could be wrong). This is no longer necessary, and it does not make sense to include element selector for at least three reasons:
It slows the selector down since the element selector is slower than the other two -- especially id. Assuming selection is optimized so that fast selection is done first (e.g. the element with the matching id is found before the element selector is checked), there is still the additional step of checking the element selector.
It's not as extensible since you can't change the element without also having to change the selector. The implication is also that div.class would function differently than label.class, but I think that the class should be descriptive enough.
It changes the specificity of the selector. This could be very frustrating for some developers who may want to change <div class="foo"> from green to red:
div.foo { color: green; }
/* below is not applied since the above has higher specificity */
.foo { color: red; }
I've never heard an argument that supports type.class unless old browsers need to be supported.

How do you read !important in CSS? [duplicate]

This question already has answers here:
What does !important mean in CSS?
(5 answers)
Closed 3 years ago.
How is the CSS attribute property !important read?
Is it really important, exclamation mark important, ...?
Answer: From the answers below, it seems to be read simply important, or bang important.
an "!important" declaration (the delimiter token "!" and keyword
"important" follow the declaration) takes precedence over a normal
declaration.
http://www.w3.org/TR/CSS2/cascade.html#important-rules
Basically, where two style rules are the same... it gives the one marked !important greater importance and will apply those styles.
Example
div{
opacity:0 !important;
}
div.jason{
opacity:1;
}
The first rule would be applied even though the second rule is more specific (one element + one class as opposed to one element)
Note: IE6 ignores !important when you have two of the same property and one of them is important - it'll always apply the last declaration, whether or not it was marked important. **Added from #BoltClock's comment below.
Warning: !important is a hammer that should only be used when absolutely necessary. Almost always, it is better to use more specific selectors to achieve greater specificity and have your styles applied the way you want. !important can make it very difficult for future developers to find and make changes to your code.
One good use case: !important is great for user-defined styles, where a user wants to manipulate Web site pages in specific way in his browser (say make all the backgrounds black and the text yellow). Without having to worry about specificity, the user can add styles to certain elements (like body) and make the styles render.
Just "important" or "bang important." The ! is definitely not a negation in this case.
It's not a tag, it's a keyword.
body { color: red !important; } means, in English, "The text-color of red is important".
In terms of how CSS sees it, it applies more "weight" to that declaration, so it will be (far) more likely to be the applied style.
For an example of this, we can use
p { color: red; }
p.blue { color: blue; }
Now, any p with a class of blue will show blue text, all the others will show red text.
If we change it to this...
p { color: red !important; }
p.blue { color: blue; }
They will all show red text (even if they have a class of blue), as we've given more important to the first selector.
I like to think of it as "NOT important".
p {
color: red !important; /* The rest is NOT important for this CSS property. */
}
Meaning that everything else from that declaration and on is NOT important and should not be taken into account. The idea came from the usage of the "!" character as a boolean NOT in many programming languages. This way the !important makes sense as you read it.
I guess I read the ! as "very".
p { color: red !important }
I read as "Paragraphs have the color red, which is very important.

Using CSS Classes

<td class="blue">
Hi1
Hi2
Hi3
<div>Not Blue</div>
</td>
I want the class in the tag ("blue") to make Hi1,Hi2 and Hi3 blue.
So what should be the head of that class?
????
{
color:blue;
}
Using a descendant selector:
td.blue a {
color: blue;
}
Or if you only want it for immediate children, a child selector:
td.blue > a {
color: blue;
}
Reference material:
Selectors supported by most browsers: CSS 2.1
Newer selectors supported by some browsers and by various JavaScript libraries (for interacting with the DOM): CSS3 Selectors
Use the following. This means all a elements within any td element that has a class name of blue should be displayed in blue.
td.blue a {
color:blue;
}
However, you should note that semantically it is unwise to give your CSS classes style-specific names (like 'blue' or 'bold' or 'center') - if later you decided to change the colour to red, you would have to change all references to the blue class to red (potentially lots of work) or instead be left with really confusing class names that don't make sense.
Try naming the class after what the elements in question mean. So in this case, it might be td.links for example.
The CSS selector you need would reference both the blue class and the a tags beneath it.
.blue a {
color:blue;
}
Note that there is another syntax which you may also want to consider:
.blue>a {
color:blue;
}
note the > between .blue and a in this example. Both examples will work for your given HTML code, but this version more specific than the first, because it only affects <a> tags that are immediate children of blue. In other words, if you had an <a> tag inside the <div>, the first version would affect it, whereas this version wouldn't.
The downside is that IE6 doesn't support the > selector, so if you need to support IE6 users, you must use the first version. Fortunately, IE6 users are becoming fewer, but there are still a few of them out there.
One other thing: I'd also advise you to avoid using class names which refer to the actual colour. It's usually better to call it menulink, or something like that.
The reason for this? Imagine in the future you want to change your site a bit, freshen it up for a new version. Maybe new corporate colours afer a rebranding exersise. Whatever. You could do that without an change at all to your HTML code; just a CSS update:
.blue a {
color:red;
}
...but now your CSS doesn't make sense. If you'd called it menulink, you will always know what that class refers to, even if things change over time.
Try this.
td.blue a {
color: #0000FF;
}
This sets all a tags that are within a td tag with a class of blue.

Resources