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.
Related
What is the proper way style a specific element that is deeply nested.
For example:
<div class="wrapper">
<div class="content">
<div class="main">
<div class="profile">
<div class="description">
<div class="name">John Doe</div>
</div>
</div>
</div>
</div>
</div>
If I want to make the name "John Doe" bold, do I name every selector:
.wrapper .content .main .profile .description .name { font-weight:bold; }
or do I just specify the selector directly like this:
.name { font-weight:bold; }
I am confused on what is the proper coding method. Thanks for your time!
No, you do not need to reference every parent element to target a nested element; you can simply target the element itself (such as with .name):
.name {
font-weight: bold;
}
<div class="wrapper">
<div class="content">
<div class="main">
<div class="profile">
<div class="description">
<div class="name">John Doe</div>
</div>
</div>
</div>
</div>
</div>
Also, note that you can simply target any of the ancestor elements directly as well, where the rule will cascade down (targetting .profile will target .profile as well as everything nested within .profile, but not any of the ancestors or siblings of .profile):
.profile {
font-weight: bold;
}
<div class="wrapper">
<div class="content">
<div class="main">Main (not bold)
<div class="profile">Profile
<div class="description">
<div class="name">John Doe</div>
</div>
</div>
</div>
</div>
</div>
When you specify additional parent elements such as with .wrapper .content .main .profile .description .name, you're increasing what's known as the specificity.
This can play an important part when you have two rules that both target the same element, where the most specific rule will be applied (in the following, .name is a valid selector, but .description .name targets the same element and is more specific, so .description .name overrides .name):
/* This gets applied */
.name {
color: red;
}
/* This gets applied and takes priority, as it is more specific */
.description .name {
color: blue;
}
<div class="wrapper">
<div class="content">
<div class="main">
<div class="profile">
<div class="description">
<div class="name">John Doe</div>
</div>
</div>
</div>
</div>
</div>
And this increased specificity also be used to denote when you have two elements with the same class or selector, where you only want the rule to apply to a particular element (the second .name here doesn't have the parent .description, so although .name would be a valid selector for it, .description .name is not):
.description .name {
font-weight: bold;
}
<div class="wrapper">
<div class="content">
<div class="main">
<div class="profile">
<div class="description">
<div class="name">Name One -- targetted</div>
</div>
<div class="name">Name Two - not targetted</div>
</div>
</div>
</div>
</div>
It depends if the only hierarchy you want to be selected is the one in your example. If the hierarchy does not matter, use only one class name (.name). If you want to limit your selection to a specific hierarchy (how specific depends on your situation), go for more. It's not entirely uncommon for selectors to consist of many class names, each of them going even deeper into the hierarchy.
However, looking at your code, I want to suggest giving some of your tags IDs instead of class names. IDs are like class names, but they are unique across the whole document (there can/should be only one element with the same ID per document). In your example, is there more than one .wrapper, .content, and .main? Probably not. You'll judge for yourself, but those kinds of structures are typically unique and exist only once in a document.
If you give them IDs, they are #wrapper, #content, and #main respectively.
<div id="wrapper">
<div id="content">
<div id="main">
<div class="profile">
<div class="description">
<div class="name">John Doe</div>
</div>
</div>
</div>
</div>
</div>
If you choose to do so, you can then get rid of the first three class names in your selector.
.profile .description .name
would be the same as:
#wrapper #content #main .profile .description .name
Except if there were elements in the document that had the same class names, but were outside of your #wrapper, #content, and #main.
The decision is yours, but it is commonplace to give such global structures (like main) IDs instead of class names, because they tend to be unique.
How can I write a CSS Rule that selects all div.box that are not inside .container?
The following snippet is not working because there is a div without .container inside the div.container.
div:not(.container) .box {
background:red;
}
<div class="box">box</div> <!-- select this -->
<div class="container">
<div>txt</div>
<div><div class="box">box</div></div>
</div>
<div class="box">box</div> <!-- select this -->
If you do not want to override every attribute, the only way I see is to give an additional class to the boxes inside of the specific container.
.box:not(.exclude) {
background: red;
}
<div class="box">box</div> <!-- select this -->
<div class="container">
<div>txt</div>
<div><div class="box exclude">box</div></div>
</div>
<div class="box">box</div> <!-- select this -->
In a way, the CSS rule you are asking for is sort of backwards. You should start with the most generic rules, and then add more specific ones. In your case, you should do something like the following:
/* Generic Box styles */
.box
{
border: 1px solid black;
}
/* Boxes in a container */
.container .box
{
color: blue;
}
<div class="box">Generic Box</div>
<div class="container">
<div class="box">I'm in a container</div>
</div>
Select all div.box or all div not inside .container? What you ask for and what you say you want selected in the html code sample are not the same thing. That said, your css selectors are just out of order. Try:
div.box:not(.container) {
background:red;
}
and
<div class="box">box</div>
<div class="container">
<div>txt</div>
<div><div class="box">box</div></div>
</div>
<div class="box">box</div>
If you want all the divs, just remove the .box
I want to use css3 nth-child to select matched elements based in their index in the whole document (like jquery :eq() selector) not based in the parent element.
<div id="container">
<div class="result">
<div class="active">content 1</div>
</div>
<div class="result">
<div class="active">content 2</div>
</div>
<div class="result">
<div class="active">content 2</div>
</div>
</div>
This css code select all elements because every .active is 1st child respective to the parent .result
.active:nth-child(1) {
background: red;
}
I tried also to make the body as parent
body > .active:nth-child(1) {
background: red;
}
But it can't do the job.
I want nth-child(1) selects content 1
and nth-child(2) selects content 2
I think you want to use nth-child on .result.
#container .result:nth-child(1) .active {
background: red;
}
JSBin
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>
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; }