We have a DOM like this:
<div class="outer">
<div class="inner"> <!--// No "copyright" in this node //-->
<div class="content">...</div>
</div>
<div class="inner">
<div class="content">...</div>
<div class="copyright">...</div> <!--// DISPLAY THIS ONE //-->
</div>
<div class="inner">
<div class="content">...</div>
<div class="content">...</div>
<div class="content">...</div>
<div class="copyright">...</div> <!--// Hide this one //-->
</div>
<div class="inner">
<div class="content">...</div>
<div class="content">...</div>
<div class="copyright">...</div> <!--// Hide this one too, etc. //-->
</div>
<!--// etc. //-->
</div>
All elements with class "copyright" must be hidden, with exception of the very first one.
We tried to apply this approach, but unfortunately with no success. It must be a CSS only solution. Any idea?
Thanks for your help!
In this case, each .copyright is the first and only one of its kind in .inner, so you need to select by .inner instead. If you don't need to apply any special rules to the first child, you don't need to use the approach I describe in that other question; simply use this to hide the other elements:
.inner ~ .inner .copyright {
display: none;
}
This is still the top answer on Google for "css select first occurrence of class" so adding the simple technique I found to work.
This solution doesn't specifically solve the OP but does allow you to select the first element with a class amongst siblings.
You can use a combination of the sibling and not selectors as shown in this JSFiddle
For example:
.my-class:not(.my-class ~ .my-class) {
background: red;
}
How does this work?
The sibling selector (~) selects elements which are somewhere after other elements.
So this would select every element except the first one:
.my-class ~ .my-class {
background: red;
}
We then just use the :not selector to reverse this, i.e. select only the first element.
I have only tested this on Chrome but think it should work on most modern browsers.
Try this one JSfiddle
div.inner > .copyright { display:none; }
div.inner:first-child .copyright { display:block; background:#000; }
Related
I'm trying to target an <h1> element within a <div> using the CSS first-of-type property, but I noticed that not only does this target the first child of this <div> that is of type <h1>, but it also targets the children of children that are of type <h1>, which seems less useful to me. Is there any way that children of children can be excluded from this?
In the example below, I have an <h1> that's an immediate child of a <div> called #everything. I try targeting that <h1> in the CSS, but this results in targeting both the correct <h1> as well as another <h1> within a child <div>.
#everything h1:first-of-type{
color: red;
}
<div id="everything">
<h1>hello</h1>
<div id="something">
<h1>goodbye</h1>
</div>
</div>
Is this what you wanted?
#everything>h1:first-of-type{
color: red;
}
<div id="everything">
<h1>hello</h1>
<div id="something">
<h1>goodbye</h1>
</div>
</div>
Update your css code with this.
#everything > h1{
color: red;
}
One more option:
#everything:first-child > h1 {
color: red;
}
For this option #everything:first-child you need to specify the child h1 or it's class/id.
I have a question related to Select first Descendant with CSS or How do I hide only the first element of a type? but my case doesn't match these ones.
I need to target all .page descendants of class .example but excluding nested .example.
In this example, I'd like to target only #h1-a and #h1-c:
<div class="page">
<!-- there could be many levels of wrapping -->
<div>
<div>
<div id="h1-a" class="example">
<h1>h1-a</h1>
<div>
<div id="h1-b" class="example">
<h1>h1-b (nested)</h1>
</div>
</div>
</div>
</div>
</div>
<!-- or there could be none -->
<div id="h1-c" class="example">
<h1>h1-c</h1>
<div>
<div id="h1-d" class="example">
<h1>h1-d (nested)</h1>
</div>
</div>
</div>
</div>
Here is a jsfiddle to get us started.
You can use the CSS cascade to overwrite an earlier rule (applying to a more general context) with a later rule (applying to a more specific context):
.page .example {
border: 1px solid rgb(127,127,127);
}
.page .example .example {
border: none;
}
This is exactly how the CSS cascade is supposed to work - general rules higher up, specific exceptions lower down.
I need to be able to apply a width to a div but only if any of it's parents have a class of grid.
Obviously the child selector allows me to select an element if it's a direct child of the grid div:
.grid > .test {
width: 300px;
}
<div class="grid">
<div class="test"></div>
</div>
I need a selector that allows me to select the .test div even if its not the direct child of grid:
<div class="grid">
<div class="another">
<div class="test"></div>
</div>
</div>
You'd imagine that I could just use a bog-standard selector like:
.grid .test
Problem with this is that I only want to match the first instance of the .test div. The above selector matches all instances even if they're nested. Any subsequent div's with a class of test should be ignored.
<div class="grid">
<div class="another">
<div class="test">
<div class="test"></div> <!-- this should be ignored somehow -->
</div>
</div>
</div>
http://jsfiddle.net/hs3G9/1/
Is there any way to do this with css or do I need to resort to JS?
There isn’t a way of excluding that inner .test element without JavaScript. If the two had been siblings, you could do something like:
.grid .test:first-of-type {}
edit: Right you are; you can cook something up with the :not selector.
Using the :first-child selector in css should work.
So for you case:
<style>
.grid .test:first-child {
background-color: rgba(0,0,0,.2);
}
</style>
<div class="grid">
<div class="another">
<div class="test">
<div class="test"></div> <!-- this should be ignored somehow -->
</div>
</div>
</div>
I'm not sure if this is possible in CSS, but if it is, I would appreciate some help.
I have HTML similar to the following:
<div class="group"></div>
<div class="group"></div>
<div class="group subgroup"></div>
<div class="row"></div>
<div class="row"></div>
<div class="group"></div>
<div class="group subgroup"></div>
<div class="row"></div>
Is it possible to alternate the background colors of the row classes? Always starting with the same color? I've been having trouble achieving this using nth-child and I'm assuming it's because of the group/subgroup classes.
Manual html markup in jsfiddle of an example data set that could be returned and how it is designed to be styled:
http://jsfiddle.net/Qr5Za/
'always starting with the same color' means that the first row after
group/subgroup starts with red
If so, you can set background-color of the first .row red and the others magenta by:
.group ~ .row { /* select all rows comes after each group */
background-color: magenta;
}
.group + .row { /* select and override the first row after each group */
background-color: red;
}
JSBin Demo
These selectors are called General sibling combinator ~ and Adjacent sibling combinator +, you can find more details here.
Update
All new CSS3 selectors like :nth-child(n), :nth-of-type(n) matches every element that is the nth child or type, of its parent.
So the only way to achieve this, is putting .rows in a wrapper for each block:
<div class="group">This is a group</div>
<div class="group subgroup">This is a subgroup</div>
<div class="wrap">
<div class="row">This is the first row</div>
<div class="row">This is the second row</div>
<div class="row">This is the third row</div>
<div class="row">This is the forth row</div>
</div>
And selecting odd and even rows based on their position in the .wraper (their parent):
.row:nth-child(odd) {
background-color: red;
}
.row:nth-child(even) {
background-color: magenta;
}
JSBin Demo #2
.row:nth-of-type(n) + .row:nth-of-type(even){
background: green;
}
.row:nth-of-type(n) + .row:nth-of-type(odd){
background: orange;
}
.group.subgroup + .row:nth-of-type(n) {
background: blue;
}
Updated Demo
So, I've encountered a situation where inserting an element of a different class/id breaks all css-rules on that :first-child.
<div id="nav">
<div class="nSub">abcdef</div>
<div class="nSub">abcdef</div>
<div class="nSub">abcdef</div>
<div class="nSub">abcdef</div>
<div class="nSub">abcdef</div>
</div>
.nSub:first-child { margin-top:15px; -moz-border-radius-topleft:5px; /* ... */ }
.nSub { background:#666; /* ... */ }
.nSub:last-child { -moz-border-radius-bottomleft:5px; /* ... */ }
As soon as I insert an element of another class/id above, like this:
$('nav').insert({top:'<div id="newWF"></div>'});
all declarations for .nSub:first-child are being ignored in both FF 3.6 and Safari 4.
EDIT:
sorry if I did not say it clearly: the element inserted above is supposed to NOT have the classname ".nSub"
<div id="nav">
<div id="newWF"></div>
<div class="nSub">abcdef</div> <!-- BROKEN CSS -->
<div class="nSub">abcdef</div>
<div class="nSub">abcdef</div>
<div class="nSub">abcdef</div>
<div class="nSub">abcdef</div>
</div>
That's because the first element with class nSub is no longer the first-child of the parent, and thus the style no longer matches.
If the dynamically inserted element would also have class nSub, then the rule would still match, and match for the newly inserted element (which is now the first child).
I'm no CSS3 expert, but you could try the :nth-of-type selector:
.nSub:nth-of-type(1) {
/* Rules for the first .nSub here */
}
This is because, you don't set the class for this inserted element, I guess...
In you CSS-File you say ".nSub:first-child", but the element you are inserting is not of that class: "
Maybe it helps, if you add the class-attribute to that element, too:
$('nav').insert({top:'<div id="newWF" class="nSub"></div>'});
What PatrikAkerstrand said about the rule no longer matching is correct. The :first-child pseudo (unfortunately) only targets the first child of its parent that also has the element/class/whatever you specified.
I just spent half an hour cursing at why the following wouldn't work
<div id="header">
<img src="path/file.png" />
<div class="img"></div>
<div class="img"></div>
<div class="img"></div>
</div>
#header .img {
margin:0 25px;
}
#header .img:first-child,
#header .img:last-child {
margin:0;
}
I found that the solution were to wrap the div.img's into a div.images, like this
<div id="header">
<img src="path/file.png" />
<div class="images">
<div class="img"></div>
<div class="img"></div>
<div class="img"></div>
</div>
</div>
#header .images .img {
margin:0 25px;
}
#header .images .img:first-child,
#header .images .img:last-child {
margin:0;
}
Edit: If you don't want to add non-semantic workaround markup, you can use the :first-of-type pseudo-class. This, however, is not supported in earlier versions of IE.