How can I write this code more effectively? I don´t want to write .btn:hover every time.
.btn:hover .glyphicon-minus,
.btn:hover .glyphicon-ok,
.btn:hover .glyphicon-remove,
.btn:hover .glyphicon-trash,
.btn:hover .glyphicon-arrow-left,
.btn:hover .glyphicon-arrow-right,
.btn:hover .glyphicon-eye-open,
.btn:hover .glyphicon-floppy-disk,
.btn:hover .glyphicon-print
.btn:hover .glyphicon-pencil{
color: black !important;
}
Try:
.btn:hover [class^="glyphicon-"]
This targets all classes that start with glyphicon-
The carat symbol. It's most commonly used in regular expressions to designate the beginning of a string.
The 30 CSS Selectors You Must Memorize
.btn:hover [class*='glyphicon-'] {...}
... matches all elements children of .btn:hover that contain glyphicon- inside their class attribute. If they are always immediate children, you should use the direct descendant operator:
.btn:hover > [class*='glyphicon-'] {...}
... so it doesn't apply when .glyphicon-* is not immediate child of .btn.
Note: (#Paulie_D) In principle and for the general case, this is safer than using [class^="glyphicon-"], because when the matched children have more than one class and the one being matched is not the first, the selector won't match. For example:
<a class="btn"><i class="glyphicon glyphicon-floppy-disk"></i>Old devices</a>
Note: (#GeomanYabes, on the suggestion to use SASS). Using SASS (or not) usually has to do with the stack of the team/company you work in, with personal choice as a developer or with project/client requirements rather than with writing less code in a particular case in a particular project (like the one above). I mean you don't choose to use SASS if you have a case like the above and drop it if you don't. The decision is based on larger considerations and taken regardless. As a rule of thumb I tell everyone: if you write CSS, do use SASS. Getting back to your suggestion and the question, please note SASS produces CSS and that CSS is not necessarily more efficient, which is what OP seems to ask for, intentional or not.
In terms of efficiency, such as rendering speed and browser performance, I must say I'm really not sure which code is more efficient between the two (specifying each case or a pattern). I'm assuming a pattern should be a little heavier on the parser and the extra weight might not justify the characters saved by the shorter syntax.
In any case, the differences are so tiny they don't really matter in like 99,99% of cases. Regardless, if you decide to pursue this issue, I'm genuinely interested in any results/tests. Let's just say I choose to regard CSS more like a hobby than a job, which is the opposite of how I feel about JavaScript these days.
If efficiency is measured in characters typed, I guess the pattern wins. If it's measured in time spent to code, it varies from person to person and has more to do with knowledge than syntax.
You can use LESS or SASS for that. It allows you to nest classes/tags/IDs and other selectors inside each other. With that you could write
.btn:hover {
.glyphicon-minus,
.glyphicon-ok,
.glyphicon-remove,
.glyphicon-trash,
.glyphicon-arrow-left,
.glyphicon-arrow-right,
.glyphicon-eye-open,
.glyphicon-floppy-disk,
.glyphicon-print,
.glyphicon-pencil {
color: black !important;
}
}
The answers recommending CSS Regex will definitely solve your problem if you don't need to be selective about which glyphicons are being impacted.
In the event you need it to be specific though, unfortunately CSS' limitation stops there and you should consider looking into a preprocessor like Sass or a postprocessor like PostCSS to help with inefficient coding time.
.btn:hover {
.glyphicon {
&-minus,
&-ok,
&-remove,
&-trash,
&-arrow-left,
&-arrow-right,
&-eye-open,
&-floppy-disk,
&-print
&-pencil {
color: black !important;
}
}
}
Would give you the same output if you were using Sass.
try .btn:hover:matches(.glyphicon-minus, .glyphicon-ok, .glyphicon-remove, .glyphicon-trash, .glyphicon-arrow-left, .glyphicon-arrow-right, .glyphicon-eye-open, .glyphicon-floppy-disk, .glyphicon-print .glyphicon-pencil) {/*your css*/}
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
I frequently need to address generic elements inside some specific sections of a page. I find this approach most easy to understand in terms of what any rule is affecting:
.shop > .products > .product > .description > .warning {
color: red;
}
But I often see this:
.shopProductsProductDesc > .warning {
color: red;
}
Does it really matter which approach is taken?
It really depends on the problem you are trying to solve.
The selector .shop > .products > .product > .description > .warning to my understanding would be used for two cases:
You have multiple warning elements but you only want to select the elements inside your description and there are other selectors used for warning that you don't want to overwrite.
You need to overwrite a previous selector that is less specific. Ex. .shop > .products > .product > .description .warning
The other selector .shopProductsProductDesc > .warning is less specific than the first one but assuming the container of .warning has those two classes .description.shopProductsProductDesc then the outcome would be the same as the first one.
CSS is all about specificity, if your selector is more specific than the last one used the properties would change. This is why you have to be careful if you are using specific selectors because your last option to alter the properties would be to use !important.
I hope this helps to clear things out.
After trying a few different styles, I think that personal preference (or a set standard if you have collaborators) is really the way to go. I prefer the second version, but the first one is also quite legible.
If you consider efficiency of what the browser has to do under the hood to render CSS styles, BEM-style for example, is usually the ultimate winner as it is the most lightweight for the browser. I use BEM for some layout/common elements.
In real life unless you are doing something seriously wrong, modern browsers and devices make this difference of CSS parsing and rendering somewhat negligible. But that is if you code everything well.
I've worked with spaghetti CSS codebases that could take minutes to render all SCSS (it was a huge codebase, but a few files were big bottlenecks).
It matters because of specificity. The first style rule will always override the second, regardless of where they both appear in the stylesheet, because it is more specific (basically it has more class selectors in it).
That said, the first rule is a nightmare from a maintainability perspective, for a number of reasons:
It makes code incredibly hard to read and understand
It's harder to override (as we have seen).
If you change the structure of the HTML, it will break
You can only reuse it if you mirror the structure of the HTML exactly.
It's also bad from a performance perspective. When browsers are matching an element to a style rule they read each selector right-to-left and keep going till they either find a match or can exclude the rule. Therefore, the more simple the selector is, the faster a match can be determined. If a selector consists of just a single class name, the browser can match the element with the style rule more quickly than if it has to search upwards in the DOM tree.
The second rule is better, but optimal would be something like the following:
.shopProductsProductDesc--warning {
color: red;
}
This solves all the problems above, and it's long enough that there's unlikely to be name clashes elsewhere, (though obviously not impossible).
In general, nesting selectors in CSS is bad practise, in my opinion, and the best CSS methodologies are those that have ways of avoiding this, e.g. BEM, CSS-in-JS.
According to my own experience, the second option is often best, not for direct technical reasons (in fine, it will perform the same), but rather for UX consistency and code maintenance.
The first option produce an "heavy" selector, which will be harder to override. It can be wanted, but it is often the sign of an overall messy CSS, because if everything is overconstraint, it is less easily reusable/extensible.
From my understanding of CSS and frontend reusable components, you would always only need two levels.
The style of your warning component (no size, no margin, size depends on where you will display it, and margin is position, only internal design here):
.warning {
//Your design here
font-size: 1.5rem;
font-weight: bold;
color: orange;
}
And the positionining and variants inside containers:
.container > .warning {
//This is an example.
position: absolute;
right: 0;
border: solid 1px red;
}
Having long CSS selectors will make things more complex, hard to follow for your teammates, and hard to override because you will probably need a longer CSS selector, and it never ends. Plus, you will get an heavier bundle at the end.
If you want an efficient UX, the UI shouldn't be that different everywhere, so you should not need to have that many variants of the same component. Otherwise, maybe you need multiple different components, but you certainly want a simple and efficient UX, and that often goes with not so much visual concepts, so you must avoid tons of variants.
I am building websites for a while, and I have a question about CSS I can't really rid over. So there is that frequent situation when multiple classes affect a DOM element, and both classes declare the same properties. For example:
.first {
color:white;
}
.second {
color:black;
}
I know that if I have an element with class="first second" in that the text will be black. If I rather want it to be white, I have several options:
Using !important: I know this one is handy and I use it, but sometimes, if I use it too often, my CSS may become messy. I mean, multiple !important's can result the same basic situation.
Reordering the classes inline: if I am correct, which class comes first, it will be the priority one. This is nice, but i often work with environments where I can't affect that. Secondly, this is not a global but a local solution.
Reorder the CSS itself: well, this sounds interesting, but if I work with many stylesheets (and I do), it is hard to track, especially when it is WIP.
Actually what I am looking for is some workaround like z-index but for priorizing which class is stronger. Because I can't really find anything useful in this topic, I am just curious maybe it is a user error, and you guys know something I don't. How do you manage this? What do you suggest?
class="first second" is the same as class="second first". The priority is based on the position of the declarations in your css and not in their position on the html element.
So, if you want priority of a class against another, put the top priority class LAST on the css file.
.first {
color:white;
}
.second {
color:black;
}
in this example, class second has always priority over class first. This happens because browser scans through the css top-to-bottom and always applying the rules of matched classes that finds. So, the last matched class has priority over the previous matched classes.
see this fiddle: http://jsfiddle.net/5c29dzrr/
At the same specificity level, the CSS selector that is furthest down the stylesheet will be applied. So in your example, if you wanted in that situation to have the element with the white colour you would have to order your properties like so:
.second {
color: black;
}
.first {
color: white;
}
The order of the classes in the HTML tag is not important; it is the order in which they appear in your CSS.
The better way to handle this is to go with some better naming convention such as BEM or SMACSS so that you don't have the issue of conflicting class names.
Edit: It might be worth reading up on specificity and the cascade for a better understanding of this. I found this calculator to be pretty handy in determining which rules will take precendence, although these days you can just use the developer tools to find out that information.
Say throughout my site, there is multiple places that I want my text to be coloured #f00
If I want to target them, should I make one declaration to target everything at once e.g.
a, .color, h2 {
color: #f00
}
OR, should I "color" them when I am targeting them anyway e.g.
a {
padding: 5px;
color: #f00;
}
.color {
background: #333;
color: #f00;
}
h2 {
font-size: 20px;
color: #f00;
}
I'm never sure which to do, sure, the first part in this isntance looks like less code, but then I am referencing tags more than I need to. But on the other hand, I am using color: #f00 3 times instead of just the once.
I appreciate neither are "wrong", I was just wondering if one is quicker, more semantic or what.
Note: This isn't my code in any site, just a quick mock up. I'm looking for an answer on a bigger scale
The first one is the preferred method. Typically, a developer's goal is to minimize CSS size to encourage faster loading. Your first example surely takes up less space as a result of combining the classes together.
I think this is mostly a stylistic choice, but I'll tell how I approach it.
If there's something all these cases have in common that implies that they should always have the same color, then group them together.
However, if there's something they have in common, that suggests that you should perhaps give that commonality a name, and make it a class name. Then assign the style to the class. This is good modularity.
If it's just by chance that they have the same color, and you're likely to change one without changing the others, use the second form.
Hope's answers is true, but unless there are a huge number of styles like this I doubt that it's going to have a noticeable impact on loading time.
I haven't played with LESS yet, I wonder if it optimizes this automatically.
The first option should be the best, in the sense that if you write less code, and that if you wanna change this color into another one everywhere, you'll have a single line to change.
But finally, this is more useful to use the second method.
If you still wanna change this color everywhere, event the simpliest editor will allow you to do it easily. But if you wanna change the color of a single div, you'll need to move your code.
A good practice (using the second method), is to reference all used colors at the top of your main css file (in comments), then you can easily pick one to search/replace all matches.
I have lots of CSS files on my current project, and a lot of the styles in these files have !important besides them. A feeling inside me tells me that this is not a good thing. Can someone shed some light on what happens when we use !important and whether it is a good idea or not.
thanks,
Sachin
!important means the rule cannot be overridden. Take note that user stylesheets using !important will override author stylesheets.
http://www.w3.org/TR/CSS21/cascade.html#important-rules
Whether this is bad or good really depends on the usage. I don't use this keyword often myself. One example is that it allows me to override styles pulled in from 3rd party widgets/plugins.
!important gives a style precedence and will ensure (where it can) that it is the style used. If you are using !important because your selectors just aren't specific, or well thought out, enough, then that's not the way they should be used. For me, there more useful for when you may have to deal with styles you have no control over.
To illustrate, where you might want to use `!important, you might have two stylesheets. One 'global' , that you have control over and one 'local', that you do.
In the global stylesheet, you might have the following:
p span {
color: black;
}
In the local one, you could override this by doing:
p span {
color: red;
}
This might work, but if the local one is included before the global one, there will be a conflict and the global styles will take precedence. To overcome this, you can do:
color: red!important;
In the case where you could just be more specific with your selectors, it would be better to do that, rather than use !important.
Global, all spans are black:
span {
color: black;
}
In local, spans inside paragraphs are red:
p span {
color: red;
}
There's nothing 'wrong' with using !important really, I guess it's a case by case scenario, but hopefully the above explains how to make the best use of them.
Some more discussion on 'When using !important is the right choice' over on CSS tricks.
I know that in a stylesheet div#name and #name do the same thing. Personally I've taken to using div#name for most styling I do, with the reasoning that it's slightly faster, and means that I can identify HTML elements more easily by looking at the CSS.
However all of the big websites I seem to look at use #name over div#name (stack overflow included)
In fact I'm finding it very difficult to find many websites at all that use div#name over #name
Is there some advantage to doing #name that I'm missing? Are there any reasons to use it over div#name that I don't yet know about?
Since the div part of div#name is not required (because ID are unique per page), it makes for smaller CSS files to remove it. Smaller CSS files means faster HTTP requests and page load times.
And as NickC pointed out, lack of div allows one to change the HTML tag of the element without breaking the style rule.
Since ID's have to be unique on the page, most ID's you'd run into would only ever appear once in your style sheet, so it makes sense not to bother including what element it would appear on. Excluding it also saves a few characters in your style sheet, which for large sites which get visited millions and millions of times a day, saves quite a bit of bandwidth.
There is an advantage to including the element name in the case where a division with ID "name" might appear differently than a span with ID "name" (where it would show a division on one type of page and a span on another type of page). This is pretty rare though, and I've never personally run across a site that has done this. Usually they just use different ID's for them.
It's true that including the element name is faster, but the speed difference between including it and excluding it on an ID selector is very, very small. Much smaller than the bandwidth that the site is saving by excluding it.
a matter of code maintainability and readability.
when declaring element#foo the code-style becomes rigid - if one desires to change the document's structure, or replace element types, one would have to change the stylesheets as well.
if declaring #foo we'll better conform to the 'separation of concerns' and 'KISS' principals.
another important issue is the CSS files get minified by a couple of characters, that may build up to many of characters on large stylesheets.
Since an id like #name should be unique to the page, there is no reason per se to put the element with it. However, div#name will have a higher precedence, which may (or may not) be desired. See this fiddle where the following #name does not override the css of div#name.
I would guess that including the element name in your id selector would actually be slower – browsers typically hash elements with id attributes for quicker element look up. Adding in the element name would add an extra step that could potentially slow it down.
One reason you might want to use element name with id is if you need to create a stronger selector. For example you have a base stylesheet with:
#titlebar {
background-color: #fafafa;
}
But, on a few pages, you include another stylesheet with some styles that are unique to those pages. If you wanted to override the style in the base stylesheet, you could beef up your selector:
div#titlebar {
background-color: #ffff00;
}
This selector is more specific (has a higher specificity), so it will overwrite the base style.
Another reason you would want to use element name with id would be if different pages use a different element for the same id. Eg, using a span instead of a link when there is no appropriate link:
a#productId {
color: #0000ff;
}
span#productId {
color: #cccccc;
}
Using #name only:
Well the first obvious advantage would be that a person editing the HTML (template or whatever) wouldn't break CSS without knowing it by changing an element.
With all of the new HTML5 elements, element names have become a lot more interchangeable for the purpose of semantics alone (for example, changing a <div> to be a more semantic <header> or <section>).
Using div#name:
You said "with the reasoning that it's slightly faster". Without some hard facts from the rendering engine developers themselves, I would hesitate to even make this assumption.
First of all, the engine is likely to store a hash table of elements by ID. That would mean that creating a more specific identifier is not likely to have any speed increase.
Second, and more importantly, such implementation details are going to vary browser to browser and could change at any time, so even if you had hard data, you probably shouldn't let it factor into your development.
I use the div#name because the code is more readable in the CSS file.
I also structure my CSS like this:
ul
{
margin: 0;
padding: 0;
}
ul.Home
{
padding: 10px 0;
}
ul#Nav
{
padding: 0 10px;
}
So I'm starting generic and then becoming more specific later on.
It just makes sense to me.
Linking div name: http://jsfiddle.net/wWUU7/1/
CSS:
<style>
div[name=DIVNAME]{
color:green;
cursor:default;
font-weight:bold;
}
div[name=DIVNAME]:hover{
color:blue;
cursor:default;
font-weight:bold;
}
</style>
HTML:
<div name="DIVNAME">Hover This!</div>
List of Css selectors:
http://www.w3schools.com/cssref/css_selectors.asp