Nesting CSS Styles or inheritance - css

I'm pretty new to using CSS beyond applying directly to each element. I'd like to know how I should be doing this. (simplified from my actual implementation, but relatively the same). Is it possible to inherit styles somehow?
I have 3 div classes defined, each positioning a div in my page. I've left out the css for these, but the style divide my page into 3 sections.
div.left{}
div.center{}
div.right{}
Now, when a user selects one of the divs, it's then highlighted, so I have css to highlight it.
div.lefthighlighted{}
div.centerhighlighted{}
div.righthighlighted{}
I have to now repeat all the styles from div.left{} to div.lefthighlighted{} and add the styles to highlight, and this has to be done for all three div styles I've defined.
OK, I also have a tags within all three of these divs that I want styled different from all other a tags in my application, but they will be the same for the highlightd divs. This is were things get crazy.
I end up with the following for left, center and right. The worst part of this is that all the a tag styling is the same for left, lefthighlighted, center, centerhighlighted, right and righthighlighted, but I can't figure out how to share all of this.
div.left a:link {}
div.left a:visited {}
div.left a:active {}
div.left a:hover {}
div.lefthighlighted a:link{}
div.lefthighlighted a:visited {}
div.lefthighlighted a:active {}
div.lefthighlighted a:hover {}
Keep in mind, I'm simply putting empty braces here, but in my stylesheet, I've got a bunch of styles defined. Is there a way to say
div.left a:link {
inherit div.right a:link;
or
use div.right a:link;
}
I'm finding myself copying and pasting all the same styles and only changing the class name or the parent class name.

Give the elements multiple classes.
<div class="left highlighted">
And then just include the changed properties in the div.highlighted rule-set.

You can group styles by using the , (commas) as a separator. Eg:
div.left a:link, div.right a:link {}
/*Newlines don't matter:*/
div.left a:link,
div.right a:link {}
Note that the following does not work as "expected":
/*Expecting to select all links under div.left or div.right*/
div.left, div.right a:link {/*FAIL*/}
Another note about inheritance. Elements inherit styles from their parents. When a new matching selector is encountered, the styles from the parent still apply, unless defined otherwise:
a:link, a:visited, a:active {
color: red;
font-size: 16px;
}
a:hover{
font-size: 20px; /*font-size changed, while the color is still red.*/
}

Related

Applying :not() with :after

I have a little css code to add an underline to the H2 headings in my blog posts:
.post h2:after {
content:'';
display:block;
border: .5px dashed ;
}
This works.
For a specific post, I don't want this underlines applied. I added an additional class to the H2 headings that I want to stylize differently: .h2lines
Now, I can exclude this new class (.h2lines) when applying CSS directly to .post h2. For example:
.post h2:not(.h2line) {
color: #blue;}
This works. It will make all post H2 blue except the ones with additional class.
However, I can't get it to work on the :after element:
.post h2::after:not(.h2line)
This does not work. It removes the underline from all H2 headings.
Any help is very much appreciated.
You just use,
.post h2:not(.h2line)::after{}

.class a:hover vs .class:hover a

Couldn't find an answer to something I've been wondering about.
Is there a difference between .class2 a:hover {} and .class2:hover a {}? Or a preference for one over the other?
I've been using .class2 a:hover {} to alter anchors on anchor hover (ie: anchor text color), but when I wanted to alter the div that held the anchor as well (ie: anchor color and div background-color both change on hover), I had to use .class2:hover a {} for it to work. In doing so, I got confused as to the difference because between the two as they are written so similarly.
Thanks!
EDIT
Edited the question to be more clear. Thanks for untwisting my brain :)
My understanding is this:
.class2 a:hover will target any hyperlink tags within .class2 elements when the a tags are hovered.
.class2:hover a will target any hyperlink a tags within .class2 elements when .class2 is hovered.
The distinction is which element you hover in order to change those styling rules.
Example:
.box{
background: red;
width: 50px;
height: 50px;
margin-bottom: 10px;
}
.case1 a:hover {
background: blue;
}
.case2:hover a {
background: green;
}
<html>
<body>
<div class="box case1">case 1</div>
<div class="box case2">case 2</div>
</body>
</html>
In this case, do you want to hover the .class2 element or the a?
.class2 a:hover {}
With the above, the style would only apply to a when the a element is hovered specifically, if the .class element has padding or other content, hovering over the other parts of the .class element will not trigger the hovered style for a
.class2:hover a {}
While the above will trigger the hover style for a if any part of the .class2 element is hovered (padding, content, etc..)
Working fiddle here.
Yes. There is a difference.
Behaviorally, there may not seem like a difference, but if you add a margin around your <a> tag, you might find that your first selector (.class2 a:hover {}) will stop working as indended.
.class:hover a selects the a link when any part of the class is hovered upon while .class a:hover selects the a link only when the a link is hovered upon
In class2:hover, you're activating the CSS class under all elements nested in the class. This includes if you wanted to add padding outside the border of your links.
In class2 a:hover, the CSS class is only activated when you're hovering specifically over the link. Otherwise, the class is ignored.
Hope this helps!

Why CSS selectors on links are tricky with underline with hover?

Here are two examples based on this HTML.
<a href="#">
<div class="foo">
hello
<span class="bar">world</span>
</div>
</a>
In the first one, I make the link not underline on hover, then make a sub-portion of the link underline, and that works fine:
a {
text-decoration:none;
}
a:hover {
text-decoration: none;
}
a:hover .bar {
text-decoration: underline;
}
http://jsfiddle.net/3qPyX/1/
In the second, I now reverse the selectors so that the second word should be un-underlined. However, now something strange happens. The entire link remains underlined even though the selectors seem like they should remove underline from the second word. <-- (this is the question. why does this happen?)
a {
text-decoration:none;
}
a:hover {
text-decoration: underline;
}
a:hover .bar {
text-decoration: none;
}
http://jsfiddle.net/EAmwt/
Can someone explain what's going wrong in the second example? Inspecting with Chrome shows the span.bar has a computed style of text-decoration:none.
Update: a few answers explaining how to get around the problem, which is great except that's not really my question. What I want to know is why is this behavior different than, say, bold? For instance, if I try the 2nd example with bold, I get the expected results: http://jsfiddle.net/3qPyX/4/
Explanation:
The problem is that some properties (like text-decoration) get drawn to the whole parent inline element, whereas others - like font styling (that get inherited) - get overriden by the children properties.
Just for illustration: simmilarly, if you set a background color to a parent element it will paint the background of the parent ... and you would have to set another color to a child to lay it over (default - transparent - will still show the parent style through), but if you set font-weight at a child it will apply to the text inside the child element and override the parent settings.
You can find more detailed stuff on the text-decoration property in the CSS Level 2 and Level 3 Specifications.
A simple solution
withot changing the markup, you could just display .bar as inline-block.
Like so:
a {
text-decoration:none;
}
a:hover {
text-decoration: underline;
}
a:hover .bar {
display:inline-block;
}
And the inline-block breaks out of the inline/text styling of the parent anchor element =) And you can then style it independently:
DEMO
When you do the text-decoration it is applied to the entire line at once. So the a:hover .bar doesn't cause any effect, because the underline is not being applied in the .bar but on the a.
Here is the specification: http://www.w3.org/TR/CSS21/text.html#lining-striking-props
UPDATE! (As #Cam suggested) :
You need the add in separate elements the parts of your text: http://jsfiddle.net/3qPyX/5/
The CSS:
.foo, a:hover .bar, a {
text-decoration:none;
}
a:hover .foo {
text-decoration: underline;
}

Why is link styling applying to all elements, even though it should be for just one element

Why is it that the links on this page (and all others but best to demo) sharing the link style accross all pages. To demo this click on Portfolio then go back, you will see the link text turns white, even though this should only be for the "message" element (blue with rounder corners) at the bottom of the page?
This is my CSS
.message {
background-color:#54a0d9;
border:1px solid #54a0d9;
color:#fff;
}
.message h2 {
font-size:22px;
color:#fff;
}
.message a:link, a:visited, a:hover, a:active {
color:#fff; }
and HTML is a normal link inside an element (which is not a child of the message element.
Surely that should only apply to the Message elements?
I've done some research on whats causing this but so far nout...
Separating selectors by commas means to consider them completely separately. So here:
.message a:link, a:visited
Means to apply this style to a:links inside of elements with a class of "message", and also to a:visiteds. Note that the latter does not have to be inside of an element of class message. Simply put .message in front of each comma-separated term to fix it.

CSS overriding subsequent attributes

Say I have a div for the main body text of a webpage, and a navigation div for links to the rest of the website. Now say I want the links in the body text to be green instead of the usual blue, but I want the links in the navigation div to be yet another color, perhaps red. If I make links green in CSS, then all the links will be green. If I make the text in the navigation div red with CSS, the link attributes seem to override the div's attributes for links in the navigation div. How can I target only certain links when no links have any classes attached to them?
Because of CSS specificity (I love that word) rules, JMC's suggestion works.
Read more about that here:
http://htmldog.com/guides/cssadvanced/specificity/
Basically, the more specific the rule is, the more likely it is to be used.
Use descendant selectors.
Style regular links, then only links within the #nav div:
a:link { color: blue;
}
a:visited { color: purple;
}
.navigation a:link, .navigation a:visited { color: green
}

Resources