I have this code:
[dir="ltr"] [icon-start] icon {
padding-right: 0.3em;
}
[dir="rtl"] [icon-start] icon {
padding-left: 0.3em;
}
.custom-icon {
padding: 0;
}
And when I do:
<div dir="ltr">
<div icon-start>
<icon class="custom-icon"></icon>
</div>
</div>
The icon element combines the first and the third rules to be padding of 0 0.3em 0 0
This is not the desired behavior. I want css to work normally as it always does, and have the last rule be the shot-caller.
2 possible solutions, that are not welcomed:
add =!important to .custom-icon - not welcomed, as I want to minimise the use of !important + I structured my code such that I don't need to use important.
add directional rules for .custom-icon. undesired because it bloats my bundle size (this needs to happen in like a 1000 places), it is not very friendly, and generally can be misunderstood.
Something like:
[dir="ltr"] .custom-icon, [dir="rtl"] .custom-icon {
padding: 0
}
Is there a way I can tell css to ignore [dir] rules in the priority structure?
Is there a way I can tell css to ignore [dir] rules in the priority structure?
No, you can't have one rule delete arbitrary other rules from the cascade.
You're going to have to match the specificity of the other rules if !important is not an option:
[dir] [icon-start] .custom-icon {
padding: 0;
}
(Technically, you'd also need the icon type selector to really match the specificity of the other rules, but since a class selector is more specific anyway the type selector is not necessary.)
Alternatively, you could exclude .custom-icon from the other rules so you don't have to worry about overriding them:
[dir="ltr"] [icon-start] icon:not(.custom-icon) {
padding-right: 0.3em;
}
[dir="rtl"] [icon-start] icon:not(.custom-icon) {
padding-left: 0.3em;
}
Related
I'm curious if there is an entirely equivalent one-line shorthand for the following selector:
.foo {
margin-left: 30px;
margin-right: 30px;
}
I could use something like:
.foo {
margin: 0 30px;
}
but it isn't clear to me this is equivalent, e.g., the 0 might create a different final result if multiple styles apply to an element.
I'm not sure I understand your question. Typically auto is used for centering.
The browser selects a suitable margin to use. For example, in certain
cases this value can be used to center an element.
The initial value however, is 0.
So unless you specifically need to use auto, you would want the following.
.foo {
margin: 0 30px;
}
The MDN documentation explains how the margin property can be used.
use this
.foo {
margin: 0 30px 0 30px;
}
I have the following CSS problem: a website first import a CSS style file named bootstrap.css (The BootStrap framework CSS settings), then it is imported another CSS file named my-custom-style.css that override some of the bootstrap.css settings (so I can create some custom settings leaving unchanged the bootstrap.css file)
Now I have the following situation, in the bootstrap.css file I have this property that I want to override:
.img-thumbnail {
background-color: #FFFFFF;
border: 1px solid #DDDDDD;
border-radius: 4px;
display: inline-block;
height: auto;
line-height: 1.42857;
max-width: 100%;
padding: 4px;
transition: all 0.2s ease-in-out 0s;
}
Now I have to override it in my my-custom-style.css file in such a way that the .img-thumbnail object have no border. So I delcare a
.img-thumbnail {
}
and I want to say to CSS that the following field (setted in the **bootstrap.css) must not exist in the overrided file (so I have not the border)
background-color: #FFFFFF;
border: 1px solid #DDDDDD;
border-radius: 4px;
height: auto;
Can I do something like this or have I to override it with a specific value?
I tryied to override it with a specific value but I can override the background-color with a new color value (and it work) but when I try to change the border value to 0px it still use the bootstrap.css definition
Can you help me to solve this problem? I think that exist an elegant way to simply say: "don't use the overrided file settings without explicitly override it with new values
Tnx
Andrea
Basically, the CSS engine will decide which rule to use based in 3 things (listed here in order of importance):
!important clauses
More specific rule
Rule order
Now, check out this fiddle.
First, let's talk about the order. We have:
div { background:green; }
and
div { background:gray; }
So, which background CSS will use? green or gray? They are both rules with no !important clauses, and have the same specification level (both are applied for div) only remaining the order to decide. In this case gray comes last so it will be applied to all div elements.
Now, the "specificness" of the rule.
#div1 { background: red; }
This one is a much more specific rule than the other rules that apply only to div elements. So #div1 will have a red background even with a div{ background: gray; } coming later.
And last, but not least !important.
These rules are... important. They can only be overridden by another !important rule that comes later and have the same specific level.
Even if a !important rules is declared in a lower level of specification, it won't be overridden. Like in:
div { width:50px !important; }
#div2 { border:3px solid blue; width: 100px; }
Even coming later and being more specific, width: 100px; will not be applied to #div2.
Now that you know all of this, it's a matter of inspecting the element to see what's going on and then guess "how much power" you'll need to override that rule.
yeah, just override that class in your own css file and add !important at the end
I've got a problem with CSS inheritance. Here's a simplified version of my stylesheet, where I am trying to control font-sizes in nested divs for my web-app :
CSS:
.type-small {
font-size: 24px;
}
.type-large {
font-size: 48px;
}
.type-small .btn {
font-size: 24px;
height: 28px;
}
.type-large .btn {
font-size: 48px;
height: 82px;
}
When you look at this sample HTML, the innermost type-small isn't used to format the "Save" button. It looks like CSS is picking up the classes irrespective of which is deeper nested in the HTML.
HTML
<div class="type-small">
<div class="type-large">
<button class="btn">Refresh</button>
<div class="type-small">
<p>Sample info </p>
<button class="btn btn-inverse">Save</button>
</div>
</div>
</div>
Take a look at this JSFiddle for an interactive version. Is there any arrangement of the CSS that would make this work (at scale)?
http://jsfiddle.net/HA5zy/
The inheritance ( specificity ) of
.type-large .btn { /* line 29 */
font-size: 48px;
height: 82px;
}
is greater than
.type-small .btn { /* line 25 */
font-size: 24px;
height: 28px;
}
When you mention "CSS is picking up the classes irrespective of which is deeper nested in the HTML." well, it's not the way it works.
To make it short, because your 2 declarations have the same weight, the one written AFTER in your css file will take precedence and be applied.
You can correct your situation by giving more specificity to your declarations like so:
.type-small .btn, .type-large .type-small .btn { /* enhence the weight */
font-size: 24px;
height: 28px;
}
Take note that the use if !important is discouraged and will lead you to another kind of problem sooner or later, like having the oposite html construction where you'll have a .type-large inside a .type-small.
One other thing, this point was raised by user Lucky Soni, you should consider constructing with minimum markups. Meaning, your whole html could be reformated to something like this :
<button class="type-large btn">Refresh</button><br/>
<p class="type-small">Sample info </p><br/>
<button class="type-small btn">Save</button>
jsFiddled here
See http://www.w3.org/TR/CSS2/cascade.html#specificity for more details and a better comprehension of cascading style.
6.4.1 Cascading order
To find the value for an element/property combination, user agents
must apply the following sorting order:
Find all declarations that apply to the element and property in question, for the target media type. Declarations apply if the
associated selector matches the element in question and the target
medium matches the media list on all #media rules containing the
declaration and on all links on the path through which the style sheet
was reached.
Sort according to importance (normal or important) and origin (author, user, or user agent). In ascending order of precedence:
user agent declarations
user normal declarations
author normal declarations
author important declarations
user important declarations
Sort rules with the same importance and origin by specificity of selector: more specific selectors will override more general ones.
Pseudo-elements and pseudo-classes are counted as normal elements and
classes, respectively.
Finally, sort by order specified: if two declarations have the same weight, origin and specificity, the latter specified wins.
Declarations in imported style sheets are considered to be before any
declarations in the style sheet itself.
Why use additional markup just to apply these simple classes?
Modify your markup like:
<div class="type-small">
<button class="type-large btn"></button>
</div>
CSS:
.type-small {
font-size: 24px;
}
.type-large {
font-size: 48px;
}
.type-small.btn {
font-size: 24px;
height: 28px;
}
.type-large.btn {
font-size: 48px;
height: 82px;
}
Fiddle: http://jsfiddle.net/z7nzv/1/
.type-small {
font-size: 24px;
}
.type-large {
font-size: 48px;
}
.type-small>.btn {
font-size: 24px;
height: 28px;
}
.type-large>.btn {
font-size: 48px;
height: 82px;
}
Just specify that the .btn is an immediate child of the .type-x with the '>'.
Change your third class to this: (Notice the addition of "button")
.type-small button.btn {
Add the !important attribute like this:
.type-small .btn {
font-size: 24px!important;
height: 28px!important;
}
So, this is what I'm doing:
#id-form td {
padding: 0 0 10px 0;
}
#particular-td {
border: 1px solid black;
text-align: center;
background-color: #DFDFDF;
height: 30px;
padding: 10px;
}
I have a table #id-form, on which I set all tds to have padding-bottom: 10px.
But on one special occasion, I want a particular td to have padding: 10px in all directions, which I set in the #particular-td.
Obviously, I put the CSS styling in sequence in an external file.
But the rendered CSS only has padding-bottom, and padding: 10px appears to be overridden!?
Please explain:
How and why is this happening?
How should I arrange these rules to solve my problem (other than inline styling)?
EDIT: I removed 'table' before #id-form in table. I was never using this, I just mentioned it here to be able to explain it better.
Because of CSS Specificity. A selector's weighting is evaluated based on the components that make it up, with id's given a weighting of 100, classes with a weighting of 10, and element selectors with weighting of 1.
So in your example:
table#id-form td
Has a weighting of 102 (table#id is 101 and td is 1), whereas this:
#particular-td
Has a weighting of 100. If you change your second to this:
#id-form #particular-td
You will get a weighting of 200 which will override the previous selector. Only as a last resort should you ever use !important, as this pretty much prevents you from overriding it further down the line.
This has to do with specificity. table#id-form td is more specific than #particular-td. A rule with higher specificity has precedence over a rule with lower specificity.
Here are a few resources to get you started on understanding how it works:
Smashing Magazine article
W3C spec on specificity
Specificity calculator
About using !important, as suggested by others:
One might be tempted to use the !important keyword to sort this out, but that is rarely a good idea:
It becomes a pain to maintain/troubleshoot
It breaks the normal flow of CSS
The rule cannot be overridden by other rules later on
It might take a few minutes to read up on specificity, but it will be well worth the time spent when you've got a grasp of it.
You have two ways, either add !important after your padding for the particular-td:
padding: 10px !important;
OR, your selector altered like so:
table#id-form td#particular-td {
border: 1px solid black;
text-align: center;
background-color: #DFDFDF;
height: 30px;
padding: 10px;
}
Both are fine. Personally I don't like the use of !important if I can avoid it.
Try this code, I have added !important to your css, in this mode can ovveride padding of table#id-form td
#particular-td {
border: 1px solid black;
text-align: center;
background-color: #DFDFDF;
height: 30px;
padding: 10px !important;
}
I have an HTML django template page that is both RTL and LTR (depends on user's locale).
The CSS of this page is stored in another file, and that file is currently static.
What is the best way to switch the attribute left and right according to the locale? Is there a built in attribute in CSS for this problem? (I don't want to use JS, it feels too messy)
I have:
.elem{
left: 10px;
bottom: 10px;
position: absolute;
}
I want something like this:
.elem{
right-or-left-according-to-html-dir: 10px;
bottom: 10px;
position: absolute;
}
Currently the only option I can think of is turning the file into a template also:
.elem{
{{dir}}: 10px;
bottom: 10px;
position: absolute;
}
Is there a better way that will let me keep my CSS file static?
You say you're making the document rtl or ltr depending on locale. In that case you can use the :lang() selector to make certain parts of your document have styling depending on the locale.
http://www.w3.org/wiki/CSS/Selectors/pseudo-classes/:lang
http://www.w3.org/TR/css3-selectors/#lang-pseudo
If you want a little more support (IE7+) you could use the attribute selector selector[lang='en'] though that will only test the attribute on the specified selector.
http://www.w3.org/TR/css3-selectors/#attribute-selectors
If you specify the language in the html element (which you should, with lang="en" for example) you can just put the html selector in front of the class you want to apply in certain locales:
.elem {
margin: 0 10px 0 0;
color: blue;
}
html[lang='en'] .elem {
margin: 0 0 0 10px;
}
Even better, if you specified the dir attribute you can directly use that in css like so:
.elem[dir='rtl'] {
margin: 0 10px 0 0;
}
Please note that with a class on the body element you will always depend on that class always being there. But the dir and lang attribute can be specified on a more specific scope, like a single div, and still be used in the css along with styles for the 'other' reading directions.
Edit
Lastly, to gaze into the future, the CSS Selectors 'Level 4' will include a psuedo tag which will be able to filter on text directionality. Of course the specs are in development and adoption by browsers may take years before it is possible to reliably use it:
http://dev.w3.org/csswg/selectors4/#dir-pseudo
How about adding the direction to your body element via a special class, then you can write according selectors:
<body class="rtl">
and in the CSS:
.rtl .myclass {
text-align: right;
}