I was researching precedence in CSS and reading some articles, including this: http://www.w3.org/TR/CSS2/cascade.html. According to him, attributes like classes have higher precedence over pseudo-elements. However, when I did a simple test, the opposite happened. Below, my code:
HTML:
<ul>
<li class="item">Item</li>
</ul>
CSS:
ul li.item { font-size: 12px; }
ul li:first-letter { font-size: 20px; }
See it here. Why the font-size of the first letter has 12 pixels instead of 20 pixels if the class has higher precedence than pseudo-elements? Thanks in advance.
I have just looked at your fiddle in Firefox, and you don't have a problem, it is working correctly. The font size of the word is 12px as asked for. But the first-letter pseudo element is all about identifying the first letter as a separate entitiy, and giving it a different style to that used for the rest of the word. As such, the specificity of the first letter is entirely separate from the specificity of the whole word; they do not override each other.
So your first letter in the fiddle is correctly 20px.
Related
What is the level of CSS specificity received by inherited properties? I read through the W3 recommendation regarding CSS specificity and so I understand how to calculate the different specificities of css rules which are directly targeting the same element, but I see no mention there of the level of specificity given to inherited attributes.
In particular, the issue I'm encountering has to do with header elements, though I would be very interested to understand this in general.
For example, here's a snippet of HTML:
<h2>This should be black</h2>
<div class="all_red_text">
<h2>This should be red</h2>
</div>
Now if I include some CSS like this:
.all_red_text { color: red; }
I will get the result I expect. On the other hand, if I the css which I included was
h2 { color: black; }
.all_red_text { color: red; }
then all the text will be black. In the first case there is some default browser CSS which is able to be overridden by the inherited property, but then when the same property is manually specified in the second example it takes precedence over the inherited property.
Any declaration that matches element directly will get priority over the property that's inherited from the element's parent. Specificity has nothing to do with that.
CSS is applied to elements in this form:
Priority 1: inline styles
Priority 2: CSS ID styles
Priority 3: CSS class/pseudo-class styles
Priority 4: CSS element styles
Priority 5: Inherited styles
So, using your HTML structure & CSS:
h2 { color: black; }
.all_red_text { color: red; }
<h2>This should be black (and is black)</h2>
<div class="all_red_text">
(This text is indeed red.)
<h2>This should be red (actually, its parent is red - this text is black)</h2>
</div>
The .all_red_text CSS is telling the div.all_red_text element and everything inside it to have red text. The h2 CSS is telling the h2 elements directly to have black text. When the h2 is rendered, it sees "my parent element wants me to have red text, but I'm directly being told to have black text". The same idea applies to further up parents, including the HTML and browser defaults - this allows you to, for example, set the font-family on the html element and have it apply to everything on your (well formatted) web page, unless something specifically overrides it.
If you want the h2 inside div.all_ted_text to also have red text, you'd need to tell those h2 elements directly to have red text; something like this:
.all_red_text h2 { color: red; }
CSS-Tricks has a pretty nice guide on this, although they don't currently go too deep into inherited properties.
There is no such thing as specificity of inherited CSS properties. Selectors, not properties, have specificity.
In your example, both h2 elements match only one of the rules, h2 { color: black; }. Thus, the color of h2 is black (assuming there are no other style sheets that affect the rendering). Anything set on some other elements (including the parent of the second h2 element) does not affect this the least.
If the rule h2 { color: black; } is absent and there are no other rules affecting the situation, then there is no color set on either of the h2 elements. According to the definition of the color property, the value is then inherited from the parent.
Two or more selectors gets engaged into Specificity War, if and only if
they end up targetting the exact same element. However, If two selectors (targetting the same element) have equal specificity weight, then there are other factors like you said, inheritance or the styles getting over ridden in the css file.
I'm trying underline all letters except the first. I attempted to remove the underline from the first letter via ::first-letter without success. Why doesn't that work here?
<a class="sample underline letter-underline-none"
href="https://twitter.com/ryanve"
>#ryanve</a>
How can I remove the underline without changing this markup? I made a codepen with this CSS.
.letter-underline::first-letter,
.underline {
text-decoration: underline;
}
.letter-underline-none::first-letter,
.underline-none {
text-decoration: none;
}
.sample {
display: block;
}
From https://developer.mozilla.org/en-US/docs/Web/CSS/text-decoration:
Text decorations are drawn across descendant text elements. This means that if an element specifies a text decoration, then a child element can't remove the decoration.
(emphasis mine). Of course, in your case you don't have a true child element (merely a first-letter pseudo-element), but the same logic applies.
That said, some experimentation suggests a child element can add its own underline (covering up the ancestor's), and then specify the color of that underline using the text-decoration-color. So you could potentially hack together your desired visual effect, in most cases, by writing something like
.letter-underline-none::first-letter {
text-decoration: underline;
text-decoration-color: #FFF;
}
(adjusting the #FFF part to match the intended background color). I don't think I'd recommend that, though — it seems too likely to have weird edge cases that look worse than the all-underline effect to begin with.
I'm using css2 to implement some fixes for IE7 on a website.
So I have to put margin-top:30px and margin-bottom:-30px a <h2> title but I dind't find right selector.
<div class="ui-content">
<h2>Text</h2>
<ul class="ui-listview">
List Items
</ul>
</div>
The fact is that Everytime there is a H2 followed by a UL, I must put those two properties, so I wanted to do a selector with h2 and ul, but I don't know wich ones...
Thanks to help me
You can't select h2s followed by uls but you can do it the other way round. E.g.
h2 + ul { /*your css to style the ul*/ }
So you could put fixes/negative margins or whatever on the ul?
This is a only-ie-7 selector:
IE 7 only
*:first-child+html h2 {}
Anyhow, I don't recommend it because almost no one uses this browser anymore, so neither should you program specially for it.
Everytime there is a H2 followed by a UL, I must put those two properties, so I wanted to do a selector with h2 and ul
As stated by #Spudley and #Coop, you can't select an element that is followed by another element (except rare cases with series of li or td or th and :nth-last-child() but it's more of a trick).
The closest thing you can do in pure CSS is testing if h2 is followed by (an)other element(s) or not, i.e. if it's not alone with :only-child pseudo.
From MDN:
The :only-child CSS pseudo-class represents any element which is the only child of its parent. This is the same as :first-child:last-child or :nth-child(1):nth-last-child(1), but with a lower specificity.
Support is IE9+ so if you want to style this element in IE7 and IE8 too (or in the precise case where it's followed by ul but not p or h3...), you'll need JavaScript or to add a class server-side and style this class.
.ui-content > h2:not(:only-child) {
margin-top: 30px;
margin-bottom: -30px;
}
EDIT:
You can also test if H2 is both the :first-child and the second-to-last child of its parent so it'll be styled if it's followed by whatever element but not if this second element has other siblings (third, fourth one, etc)
.ui-content > h2:first-child:nth-last-of-type(2) {
margin-top: 30px;
margin-bottom: -30px;
}
Simplest code would be ;)
<div class="ui-content">
<h2 class="followed-by-list">Text</h2>
<ul class="ui-listview">
List Items
</ul>
</div>
.followed-by-list {
margin-top: 30px;
margin-bottom: -30px;
}
Other trick that'd mean a complete overhaul of your project (say, for next project ;) ): never set a single margin-bottom to content elements (I mean h2, ul, p, etc. It's OK for div and below "blocks") and always set a margin-top to:
an element (general case) ex: p
if needed, an element coming after another like elt1 + p would have a certain margin-top, elt2 + p another one, etc
I don't know what this technique is called, I've only seen it used. It's a way to repurpose the same selectors with CSS.
For example if I create
h1 {
font-size:18px;
color:#FFFFFF;
font-family:Arial, Helvetica;margin:0;
padding:0;
}
h2 {
font-size:18px; color:#000000;
font-family:Arial, Helvetica;
font-weight:normal;margin:0;
padding:0;
}
I can repurpose the h selectors with something like
.whatever h1 {
color: #000;
font: 2.0em arial, sans-serif;
background-color: #fff3ea;
margin: 50px 0px 0px 50px;
}
.whatever h2 {
color: #000;
font: 1.7em bold arial, sans-serif;
background-color: #fff3ea;
margin: 25px 0px 25px 75px;
}
If h1 and h2 appear inside of a div called whatever, then they will assume those properties. You can do this with ID tags and class tags but I can't for the life of me remember how this is done.
Any thoughts?
This is called specificity.
It's a key feature of CSS which means properties in the more specific selector (.whatever h1) will override properties in less specific ones (h1). It allows you to set general styles for most of the elements on the page (e.g. all h1 elements), and then change the properties of a small subset of those elements using a more specific selector that identifies, for example, only the h1 elements inside another element whose class is whatever:
HTML
<h1>I'm green with envy</h1>
<h1>And so am I</h1>
<div class="whatever">
<h1>Because I'm rather special</h1>
</div>
CSS
h1{
color: green;
}
.whatever h1{
color: blue;
}
RESULT
The CSS selector .whatever h1 means "any h1 element inside another element with a class of whatever". You could also give the h1 element its own class to achieve the same effect; you just write the CSS slightly differently to reflect the fact that the h1 element you're targeting now has its own class:
HTML
<h1 class="whatever">I'm special</h1>
CSS
h1.whatever{
color: blue;
}
Always try to give your classes and IDs meaningful names that refer to the element's role within the page, rather than its colour or other attributes. i.e. It is much better to use ".introduction" instead of ".bigredtext" or ".whatever". That way, if you change the colour of your intro text to bright blue, you don't have to rename the class in your CSS and HTML, and everything in your HTML will read better too. (This is what people are talking about when they mention "semantics" and "semantic naming conventions".)
How specificity is determined (simple rules to remember)
User agents (web browsers) use a formula to calculate how specific each selector is and which should take precedence over the other. In very simple terms, from less specific to more specific:
Selectors with only the name of the element (e.g. h1) are the least specific of all
Selectors with a .class are more specific than selectors with no class
Selectors with an #id are more specific than selectors with a .class
Selectors lower down in a stylesheet take precedence over earlier identical selectors
Those are the four main rules worth learning about specificity, and they will cover most simple use cases. These two additional rules aren't related to specificity, but they're worth knowing too:
Inline styles such as <h1 style="color: blue"> will take precedence over external rules declared separately in external stylesheets or inside <style> tags. You probably shouldn't use inline styles, but it's worth knowing this just in case you come across them.
Properties within a selector that use the !important flag "trump" everything and can't be overruled. Likewise, you probably shouldn't choose to use the !important flag, but there are times when you may be forced to.
How specificity is really determined (how to calculate it precisely)
Of course, it gets a little more complicated than the above (but not by much) when you start chaining classes, IDs, and elements together, which is why it can be helpful to learn how to calculate specificity precisely rather than working on intuition alone, as it will save you a lot of time when your stylesheets get bigger and more complicated.
If you'd like to learn more, Smashing Magazine has a piece titled "CSS Specificity and Inheritance" that's worth a look. They reference Andy Clarke's famous Star Wars Chart, which might be an easier way to visualise specificity if you're familiar with Star Wars, but it will probably just make things even more confusing if you're not! (Click the image below to read more on Andy's site.)
You faced overriding the selectors.
example:
<div class="one">
<div id="two">
<h1> This is H1 text </h1>
</div>
</div>
so you have set H1 to FFF - white color by:
h1 {
color:#fff;
}
now we do first override ( using ID ):
div#two h1 {
color:#888;
}
and the third, notice you don't have to put current element, you can set it for each element with given class:
.one div#two h1 {
color:#000;
}
so in the end we have black text color.
The raw ones are to set "global" styling. The nested ones are to give exac styles to given elements.
Also you can use chaining class/id selectors for <div id="one" class="two three four"> you can select it using div#one.two.three.four - without spaces
I have a plugin which outputs a profile section, and I plan to wrap it with an ol>li element. I want to style the list numbers using a different font size/style/color. But if I do that the font style will propagate/cascade into the profile. I don't want to restyle every text inside the profile again. So is it possible to prevent the font style from propagating into the descendant elements?
<style>
#rank li{
font-size:50px;
font-style: italic;
font-family: serif;
font-weight: bold;
width:70px;
margin-right:10px;
text-align:center;
}
</style>
<ol id="rank">
<li>
<div class="profile">
<!-- contains complex stuffs including tables, floated div for displaying profiles-->
</div>
</li>
</ol>
EDIT:
Sorry, I over exaggerated about 'restyling every text again'. I think if I need to make profile style unaffected again, I would need to know the default font styles outside the ul, and apply them in the div. It's not much work, but in the future, one need to modify two places to keep the overall style consistent.
Sorry, but no. All font properties cascade (the "C" from CSS) into all child elements and there is no way to prevent it. You're going to have to reset the properties on the child elements if you don't want the same font.
One thing you can, potentially, do is not actually change the font on the <li>, but on a container near it. This will only work in newer browsers, if it works for you, great :) :
ol {
list-style-type : none;
}
ol > li:before {
content : counter(list_counter) " ";
counter-increment : list_counter;
float : left;
font-family : verdana;
}
ol:first-child {
counter-reset: list_counter;
}
You could "reset" the font style on all child elements. It's not actually resetting but it should work with the universal selector. But be carefull since this will actually enforce the font on all child elements, so if you selector is more specific than others it might in the end still affect other elements.
Check this fiddle for an example: http://jsfiddle.net/79ZK5/1/
As I understand this is related to the selector priority that you can use to override the style. Have a look here to understand the Priority of Styles. If you specify the style in your html that would get the highest priority.