I have a button that is displayed in a lot of pages of my website (With an automated javascript Widget).
I want this CSS :
.app.programEditor .col-2 .actions .widget.bt-flat.programs > .bt-flat-icon {
}
to be applied, and not this one :
.app.programEditor .actions .widget.bt-flat > .bt-flat-icon {
left: 145px !important;
top: 19px !important;
But instead, what happens, is the two css are applied, and as a result I get the second element that overwrites what I want to do with the first CSS ( A blank css with no rules )
Please I really need your help
The root cause of your problem is the poorly written rule that uses !important. This is an excellent example of why not to use !important. If at all possible, try to understand why !important was thought to be needed there, and see if you can remove it.
But if you are left fighting against an important rule, your only choice is to fight fire with fire, and toss back an !important of your own, in a rule designed to take precedence either because it is more specific (in this case, your override rule has seven classes, to the original rules's six, so it is more specific), putting it later in the file if it has the same specificity, or if you have no other choice use the various tricks available to jack up the specificity.
Having said that, overall this CSS seems to be poorly structured, verbose, and inefficient.
.app.programEditor .actions .widget.bt-flat > .bt-flat-icon {
First, if .app is a class applied to your entire application, it is probably not necessary. If .actions only occurs within .app.programEditor, then the latter is not necessary at all. If .bt-flat can only apply to widgets, then instead of widget.bt-flat you can just write .bt-flat. If .bt-flat-icon can only occur within .bt-flat, as seems likely, then .widget.bt-flat may not be necessary. And so on. In general, instead of writing down every single class in the HTML hierarchy in your CSS rules, try to limit selectors to those necessary to unique select the element you want. In this case, for example, it is possible your rule could be written as simply as (just an example):
.programEditor .actions .widget > .bt-flat-icon {
Second, the magic numbers 145 and 19 are a massive code smell. They are probably connected to other magic widths and heights elsewhere in the CSS, and would have to be changed if those change. What do the 145 and 19 mean? Perhaps they are actually a percentage of some underlying dimension. In other words, maybe some element is 160 pixels wide, and we want to place the icon to the upper right. In that case, instead of hard-wiring the 145, you can either use a percentage, or specify a right property, or use the transform property perhaps, so no matter how the width changes--such as with the introduction of .col2--the icon remains in the right place with the original rule.
You can simply change it to position:static this is just a demo. Otherwise, if you understand concept of Specificity very well, then there was no need for this question.
$('#change').click(function() {
$('.one').css("position", "static");
$('.one').text("Position changed to Static")
});
.container {
width: 90%;
margin: 50px auto;
position: relative;
border: 1px solid #000;
display: block;
height: 200px;
overflow: hidden;
}
.one {
width: 150px;
height: 150px;
background: tomato;
position: absolute;
left: 118px!important;
top: 30px!important;
display: block;
color:white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div class="container">
<div class="one">
Positioned using absolute or relative</div>
</div>
<button id="change">Change CSS</button>
If many rules exist, the first one takes precedence, but if the last one is more specific, it will override the first one. BUT if the first one is less specific AND has !important that one will take precedence. :) To make matters more complicated, if both rules has !important the most specific rule will take precedence.
So the easy solution here, if you cannot change the already existing rule, just add !important to the code you can edit. If that doesn't work, try to get your code processed earlier in the code than the other one.
.app.programEditor .col-2 .actions .widget.bt-flat.programs > .bt-flat-icon {
left: 40px !important;
top: 40px !important;
}
Related
I came across this problem while handling a large project and felt that i should seek an opinion from the community here.
I have specified a css class 'header' in style1.css, i.e.
.header { color: red;}
In another file, I inadvertently, named a class 'header' again with this rule :
.header { background-color: yellow; }
When i refreshed the browser i noticed the red font and after examining the style inspector found the problem. I tried to avoid the problem by applying specificity, i.e. #some-div .header, but that didnt stop it from applying the red font. Of course i could simply solve the problem by renaming header to something else, but i'm curious how developers who handle large projects handle this. Thanks for your time.
Well, from your code, you specified values for different properties in the two declarations of the header class. The first declaration specifies a color property and the second specifies a background-color property. From all indications you're not really "overriding" anything since you didn't give conflicting values for one property so, CSS is simply giving the values of the first declaration of the header class to the second one because there's no difference. If you wanted to override it for the second you'd have to probably add a different identifier to the second declaration of the header class to point to a unique element and specify a different value for the color property. Hope this satisfied your curiosity.
Just add a different class to one of the cases. For example:
.header {
color: red;
}
.header.yellow-bg {
color: initial;
background-color: yellow;
}
<h3 class="header">Red header</h3>
<h3 class="header yellow-bg">Black/yellow header</h3>
The second declaration for color applies because it is more specific (2 classes > 1 class).
Don't use !important as another user suggested. Avoid it all costs. It's the easy way out for the moment, but once you start going down that road, you're going to end up with a stylesheet that's terrible to manage.
Set your styles for a specific base and use classes and more specific selectors as overrides. Remember that stylesheets cascade.
For example, say you have a typical header font color that should be your .header. If you have other one-off or unique headers that share same structure provide another class to that which makes sense to you.
So as an example:
Both headers have the .header styles but headers with the special class have blue text color which overrides red.
.header {
color: red;
width: 100%;
display: block;
background-color: #eee;
padding: 10px;
margin: 2px;
}
.header.special {
color: blue;
}
<div class="header">Regular Header</div>
<div class="special header">Special Header</div>
At the moment, my usual approach to supporting right-to-left (RTL) languages in a template is to simply add a .rtl class to the body tag, then go through all my existing left-to-right CSS and add left/right overrides as appropriate.
For example, my site menu might be positioned like so by default as below:
.site-nav {
position: absolute;
left: 0;
top: 0;
}
...and then manually overridden for RTL languages this way (using some template logic at a CMS level to add the .rtl class to body):
.rtl .site-nav {
left: auto;
right: 0;
}
My issue is that this seems labour-intensive and not very effecient. I was wondering what solutions others might have come up with to make this simpler.
As an aside, I'm using a Compass environment to generate my CSS. But I don't know how to escape back from the current nesting to write a .rtl modifier adjacent to the current element's default styles. This in theory would be extremely useful, however, but I simply don't know if it's possible to perform a lookup all the way back to the body element or not whilst within a deeply-nested Sass rule.
Add your .rtl-class whereever you want to change the textflow. Even when you don't want to change it (for "normal" languages).
Don't use the class in your default css-file.
Add a css-file which only includes
.rtl {
left: auto;
right: 0;
}
whenever you have a rtl-language. In case you want all your divs to behave that you you could replace .rtl with div as well.
I googled a little bit and I couldn't find the answer.
My question is: does stacking !important works in some way? Or can I achieve the same functionality in another way? I'm aware that it's not a good practice
Example, say I have:
.myOuterDiv
{
margin-left: 5px !important;
}
.myInnerDiv
{
margin-left: 10px !important;
}
It's obvious that the content of the inner div will have a margin of 10px, but can I add another important such as
.myOuterDiv
{
margin-left: 5px !important !important;
}
I wanna do exactly that, override the inner important so I can have a margin-left of 10. Can I do it like this or in some other way?
No, you cannot stack !important.. it doesn't work that way.
!important can be avoided a majority of the time, there are usually alternatives.
You can always override a CSS property by using a more specific selector.
If you have a rule being applied as .myOutterDiv { some-property: some-value !important; }, all you need to do is actually make yours have more weight. You can do that by doing, for example, div.myOutterDiv { some-property: some-other-value !important; }
Edit: You can read more details on CSS Specificity Value
I've been educating myself. Reading this:
The engine evaluates each rule from right to left, starting from the rightmost selector (called the "key") and moving through each selector until it finds a match or discards the rule. (The "selector" is the document element to which the rule should apply.)
For example:
ul li a {...}
#footer h3 {...}
* html #atticPromo ul li a {...]
Now, some example code SASS outputs for me:
#content #blog {
/* ... */
}
/* line 85, ../sass/screen.scss */
#content #flickr {
/* ... */
}
#content #flickr div p {
/* ... */
}
This seems a bit awkward.. am I doing something wrong? Is this a communication problem between me and Sass? Are we losing it?
Edit:
Some SCSS code:
#flickr {
#include columns(5,8);
background: url('../img/ipadbg.png') no-repeat;
#ipod-gloss {
z-index: 999;
position: relative;
}
div {
margin-top: -80px;
margin-right: 20px;
h2 {
color: $white;
font-size: 24px;
}
p {
margin-top: 40px;
}
}
}
Side Bonus!: The article says browsers (or at least Firefox) search the selectors from right to left. I couldn't understand why this is a more efficient why. Any clues?
You have to find your compromise between maintainability (nesting makes it easier to find your way around in the stylesheet) and rendering performance.
A rule of thumb says you should try to restrict yourself to a three-level nesting and you should avoid to nest IDs if it's not necessary.
However, I think nesting too much is not the biggest issue. As soon as I became aware of the power of mixins, I used them a lot.
For example, this is my often used button mixin:
#mixin small-button($active-color: $active-color, $hover-color: $button-hover-color, $shadow: true)
display: inline-block
padding: 4px 10px
margin:
right: 10px
bottom: 10px
border: none
background-color: $button-color
color: $font-color-inv
+sans-serif-font(9px, 700)
text-align: center
text-transform: uppercase
cursor: pointer
#if $shadow
+light-shadow
&:hover
text-decoration: none
background-color: $hover-color
&:last-child
margin-right: 0
a
color: $font-color-inv
&, &:hover
text-decoration: none
&.disabled
+opacity(0.75)
&:hover
background-color: $button-color
&.active
background-color: $active-color
&.disabled:hover
background-color: $active-color
You see, quite a bit code. Applying such mixins to many elements on your page will result in a big CSS file which takes longer to be interpreted.
In the old fashioned CSS-way you would give each button element e.g. the class .small-button. But this method pollutes your markup with unsemantic classes.
Sass provides a solution though: selector inheritance via the #extend directive.
If you set defaults for your parameter of the mixin, you can also provide a simple class, which uses the mixins with your default:
// Use this mixin via #extend if you are fine with the parameter defaults
.small-button
+small-button
And then you can just inherit from this class in various contexts:
#admin-interface
input[type=submit]
#extend .small-button
The resulting CSS statement aggregates all usages of .small button into one rule with comma-separated selectors:
.small-button, #admin-interface input[type=submit] {
display: inline-block;
...
}
Concluding, a naive usage of Sass can effect your CSS performance. Used wisely, however, it is maintainable thanks to well-structured and DRY code, it leads to proper separation of markup and styling (semantic classes only) and allows for smart and performant CSS code.
SASS is only a language that compiles down to CSS. If you're concerned with SASS' performance in terms of how it runs in the browser, then SASS doesn't enter the equation -- it'll be compiled and served to the browser as regular CSS.
From what I can see of your usage of SASS, there's a couple of things I could suggest:
You don't have to nest everything.
The ability to nest rules inside each-other in SASS is a language feature, but you don't have to do it if it doesn't make sense to do so.
In terms of your general CSS usage:
If the nesting gets too severe/unwieldly, consider using classes where it makes sense.
When it's necessary to use the hierarchy of DOM elements, consider using the [child combinator]: .foo > .bar.
IDs are meant to be unique, thus should always only reference a single element. Most of the time, they can be CSS rules unto themselves -- #content #flickr would become just #flickr, for instance -- and browsers will optimise the lookup for a single ID. The only time you would need something like #id1 #id2 is if #id2 needs to appear in different contexts on different pages.
If your selector contains things like #id div p, that div is either superfluous or serving a specific purpose.
If it's superfluous, change the rule to #id p, which selects any <p> that occurs as a descendant of #id.
If it serves a specific purpose, consider classing the <div> with a class name that describes its purpose -- perhaps <div class="photos-list">. Then your CSS could become .photos-list p, which is far more maintainable and reusable.
Short question is: is the following (an id under another id) not recommended for bloating up the CSS file size?
#product-box #product-photo { width: 200px }
details:
Sometimes in SASS, we might have
#product-box
margin-top: 20px
#product-photo
width: 200px
this way, it means it is "nested" -- that is, #product-photo's style of width 200px is only true within #product-box, and the CSS generated from the SASS is
#product-box { margin-top: 20px }
#product-box #product-photo { width: 200px }
but here we have a redundant #product-box before #product-photo, because #product-photo by itself can uniquely identify the element already.
As a result, the CSS file can become bloated. I wonder if it is recommended to un-indent #product-photo in the SASS file, so that it doesn't need to be nested?
I think we could have a .photo class inside #product-box instead... is it true? But in some cases, we might have 2 photos, or 2 li inside a #product-box, and so using a class cannot uniquely identify an element. If we use jQuery, it is true we can say $('#product-box li:eq(2) to get to any element, but it may introduce bug if somebody add another li without knowing the jQuery code depends on it. Having an id will prevent such bug from happening.
if you're selecting an element by its id, you don't need to have a nested selector - the id has to be uique everytime. if you have a class that has a different style depending on it's parent, you have to use such a nestes selector (but, if a class has the same style in every case, you can drop the parent-selector, too).
example:
#product-box #product-photo { width: 200px }
is the same as
#product-photo { width: 200px }
you could also use a class for that:
.photo { width: 200px }
but: if a photo has a different size in some cases, you have to do something like this:
#product-box .photo { width: 200px }
#another-box .photo { width: 150px }
or, alternatively, define a "default" and a special case:
.photo { width: 200px } // the default
#another-box .photo { width: 150px } // special size for photos inside #another-box
note: i have no idea how to do this in sass (i have no idea what sass is), but i hope this is helping you anyway.
note2: you shouldn't worry about this small effect on the css file-size until you have realy, realy, realy much traffic on your site - it's much more important that everything is readable and easy to understand, otherwise you will get in hell if you have to change something in the future (also, if you wan't to decrease you filesize as much as possible, why do you use such long ids? for breaking that down, wouldn't it be the best to use #a #b #c #d... and so on?)