LESS and specificity - css

I am trying to organize and structure our applications better with LESS and I'd like to know the best route in doing a task using "!important". Currently we have a lot of these and I'd like to get rid of them if it makes sense. My example is:
<div id="test">
<ul>
<li>One</li>
<li>Two</li>
</ul>
</div>
<button id="button">
Select
</button>
$('#button').on('click', function(){
$('#test li').toggleClass('blue');
})
Option 1:
#test {
ul{
li{
color: red;
}
.blue{
color: blue;
}
}
}
So with LESS, if I have the class after the initial color, it should over take. If I want to add the blue class, then I would insert it into each area within the LESS file, or do:
Option 2:
#test {
ul{
li{
color: red;
}
}
}
.blue{
color: blue !important;
}
In this case I would have it listed once, and then whenever it is called it will override the class. Or have an Option 3 if someone thinks there is something better than these two. I'm not sure what the best route is, but I'd like to get rid of !important if possible.

I subscribe to the view that you should only use !important as a temporary fix while you refactor your styles. Clearly you have a specificity problem to address (which your example doesn't quite demonstrate). In your example, I would first do Option #2 (if it was hard enough to figure), then refactor overrides like .blue into a style which is loaded last.
https://jsbin.com/cekobodixe/edit?html,css,js,output
If we change it slightly we reach a common problem: the use of id doesn't allow cascading precedence by load order:
https://jsbin.com/xikolenevo/1/edit?html,css,js,output
and so that suggests a second factor to the fix, replacing ids with classes.
Another thing that might happen is that a set of rules for a specific component were added to an override stylesheet instead of to the component. So now, the rules are overriding otehr components as well. The solution here is to relocate the offending styles to their respective components. This can get ugly fast, so its best to do this early.

The only thing I could think of is making two different classes, one red and one blue. Set the li objects in your html to .red and changing the class on click. But I don't think that's a very pretty solution.
Otherwise I think you have to stick to your !important.

Related

overwrite css items depening on className

I'm having problems with my CSS markup in my code.
I'm building a control and my plan is to add a standard class to it so it has a fixed layout and add any userdefined css classes behind it, to personalise the control. but during my tests I noticed a problem which I can't resolve.
when I have an element like this
<div class="test1 test2"></div>
and underlaying code in another stylesheet file.
.test1
{
width: 200px;
height: 200px;
background-color: red;
}
.test2
{
background-color: yellow;
}
then it doesn't matter if I put test1 first or test2. the div will always be yellow only because test1 is written last on the css file.
if I replace test2 with test1 in the css file itself then the div will always be red.
how can I make the background-color overwrite incase its added a second time depending on the order its written in the className itself?
I also want to take notice I don't want to force users to use the !important tag. I already know about this and yes that works fine but I need it without. Any ideas on how to resolve this issues is welcome. I'm open for alternatives
You could make it so .test2 when combined with .test1 becomes yellow
.test1.test2{
background-color: yellow;
}
a better way tough is not to work like this at all. have a read of this article instead. It explains a technique for CSS called BEM (Block, Element, Modifier) which is pretty awesome. When trying to modify a existing style it will look like:
.test{
width: 200px;
height: 200px;
background-color: red;
}
.test--warning{
background-color: yellow;
}
and your div will look like <div class="test test--warning">
You can twiddle the precedence of the class's selectors like this:
.test2[class*=test2]
{
...
}
This should make class test2 override other classes that have only class name selectors.
(sorry, this part is not correct)
If you want to lower test1's precedence, you could do it like this:
[class*=test1]
{
...
}
(I haven't tested this, you might need to name it *[class*=test1] instead)
I been researching for a long time and posted here because I couldn't find a good answer. thx to the answers and responses here I was able to find an article over the problem I'm facing here CSS howto
What I'm trying to do is not possible because of the order css in generated. What I wanted is my css to work between browser default and external or internal stylesheets. I will look for an alternative solution to my project.

Double class declaration in CSS

So, due to two sets of messy procedural code colliding in horrible Lovecraftian horror that I can't do much about, I am forced to deal with a situation where I'm going to have two seperate CSS class declarations on the same objects. For example, I might have an end result that looks like...
<div class="my_class" class="cuthullus_child_class_that_overwrites_EVERYTHING">
...something goes here, or so I have been told...
</div>
I know having multiple declarations like this is bad, but there's not anything I can really do about it at present. However, I can control the content of one of those classes, and potentially the order they appear in...
Given this, what effects will the order have on the classes showing/not-showing? Will one overwrite the the other? Will it error out and I'm effectively left with no class? Will they combine as if both were in the same declaration? Or with it simply destroy Dunwich and everything I hold dear?
Edit: Looking into it deeper, it looks like the div will completely refuse to display, but I"m trying to find some way around that if possible.
The two class attributes on the same element will break. The second class will be ignored, see below.
The only alternative is to add an inline style unless you can clean up the code in the first instance.
.my_class {
color: blue;
}
.alt_class {
color: red;
}
<div class="my_class" class="alt_class">
...something goes here, or so I have been told...
</div>
Using duplicate attribute class for one element is invalid in HTML.
This is valid when you need to use multiple classes:
<div class="firstClass secondClass"></div>
The order does not matter, the classes will be targeted equally from HTML but depends on CSS order.
For example:
.secondClass{background: salmon}
.firstClass{background: skyblue}
firstClass will override secondClass because it's set after secondClass
Why don't you use just like this:
<div class="my_class second_class third_class">
...something goes here, or so I have been told...
</div>
Isn't this working for you?! or you're trying to achieve something else?!
Why don't you just use
<style>
.parent_class{
margin:10px;
}
.parent_class.child_class{
margin:20px;
background:red;
}
</style>
<div class="parent_class child_class">
...something goes here, or so I have been told...
</div>
first of all, you need to put all the classes in one 'class' attribute separated by a single space, otherwise the browser will only take the first one, aka:
<div class="my_class cuthullus_child_class_that_overwrites_EVERYTHING">
...something goes here, or so I have been told...
</div>
To answer your second question, whichever one comes later in the stylesheet, will overwrite any rule that also exists with the first class, aka:
.my_class{
color: red;
}
.cuthullus_child_class_that_overwrites_EVERYTHING{
color: blue;
}
The color would be blue. If they were ordered the other way around, the color would be red. If any of the rules contains '!important' it would take precedence.
Also, if there are different rules within the classes, they won't conflict and will all apply, aka:
.my_class{
color: red;
}
.cuthullus_child_class_that_overwrites_EVERYTHING{
font-size: 36px;
}
The color would be red and the font-size would be 36px.
It is actually common and not problematic to declare more than one class for a single object; as jQuery is often used to add/remove classes based on different events.

Priorizing CSS properties

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.

Is there a way to apply a CSS class from within a style?

I'm trying to be more modular in my CSS style sheets and was wondering if there is some feature like an include or apply that allows the author to apply a set of styles dynamically.
Since I am having a hard time wording the question, perhaps an example will make more sense.
Let's say, for example, I have the following CSS:
.red {color:#e00b0b}
#footer a {font-size:0.8em}
h2 {font-size:1.4em; font-weight:bold;}
In my page, let's say that I want both the footer links and h2 elements to use the special red color (there may be other locations I would like to use it as well). Ideally, I would like to do something like the following:
.red {color:#e00b0b}
#footer a {font-size:0.8em; apply-class:".red";}
h2 {font-size:1.4em; font-weight:bold; apply-class:".red";}
To me, this feels "modular" in a way because I can make modifications to the .red class without having to worry so much about where it is used, and other locations can use the styles in that class without worrying about, specifically, what they are.
I understand that I have the following options and have included why, in my fairly inexperienced opinion, they are less-than-perfect:
Add the color property to every element I want to be that color. Not ideal because, if I change the color, I have to update every rule to match the new color.
Add the red class to every element I want to be red. Not ideal because it means that my HTML is dictating presentation.
Create an additional rule that selects every element I want to be red and apply the color property to that. Not ideal because it is harder to find all of the rules that style a specific element, making maintenance more of a challenge
Maybe I'm just being an ass and the following options are the only options and I should stick with them. I'm wondering, however, if the "ideal" (well, my ideal) method exists and, if so, what is the proper syntax?
If it doesn't exist, option 3 above seems like my best bet. However, I would like to get confirmation.
First of all you cannot do apply-class:".red";
to perform this type of action i will suggest you to use this method
.red {color:#e00b0b;}
h2 {font-size:1.4em; font-weight:bold;}
.mymargin{margin:5px;}
<h2 class="red mymargin">This is h2</h2>
and to use in div
<div id="div1" class="red mymargin"></div>
In this case if you will change in .red class.it will be changed everywhere
Short answer: There's no way to do this in pure CSS.
Longer answer: Sass solves this problem via the #extend directive.
.error {
border: 1px #f00;
background-color: #fdd;
}
.seriousError {
#extend .error;
border-width: 3px;
}
This lets you keep your CSS modular in development, though it does require a precompilation step before you use it. It works very nicely though.
You can use the DOM in javascript to edit the id and/or class attributes of HTML tags dynamically.
I agree with DarthCaesar and jhonraymos. To update a class using JavaScript, all you would need is a simple:
function toggleColorClass(e){
var redClass = document.getElementsByClassName('red');
redClass.removeAttribute('class', 'red');
/*Set the class to some other color class*/
redClass.setAttribute('class', 'blue');
}
Of course, to make this work, you would need to include the above function in your document somewhere... if this is all the JS you're using you can probably stick it in the head or even use it inline. You would probably also want to write it so that the toggle goes in both directions, i.e. turning red on and off. Furthermore, jhonray's snippet is probably how you would want to mark up your CSS.

Make entire CSS sheet !important

Is there a way to make an entire CSS Style sheet take precedence over another? I know you can do the !important but can I do that with one line rather than modify all thousand properties on the sheet?
Thanks!
Make sure the stylesheet you want is called last (or a specific style you want is called last). For example, using this:
span { color: red; }
span { color: blue; }
...will turn all text in <span>'s blue. Take a look here.
Rules with identical specificity that come later will overrule previous ones, so if both style sheets contain the identical selectors, you should be able to do this by just loading the one before the other.
If they contain different selectors, like
#navigation h3 { color: red }
and
.mainpage .navmenu h3 { color: blue }
you are likely to get specificity conflicts. The only blanket solution for that is indeed !important (although that is really, really terrible architecturally. Are you sure you need this? Maybe explain why, it's possible somebody is able to come up with a better solution.)
There is, however, no single-line directive to elevate the "importance" of one style sheet over the other.

Resources