I wondered if there is a better solution than to what I found without changing the html-structure
The HTML structure looks like this
<div class="wrap">
<div class="divider"></div>
<div class="block"></div>
<div class="block"></div>
<div class="divider"></div>
</div>
So there's various DIVs on the same level, what I want to do is to color every fourth block differently, until a divider appears, then it'd have to recount.
I thought something like .block:nth-child(4n) would do the trick, but it actually counts the elements based on the parent, not based on the class.
Here's the JSFiddle to try out.
Block #4 and #8 in each row should be differently colored
http://jsfiddle.net/SKgdH/3/
And this is how I made it sort-of work:
http://jsfiddle.net/SKgdH/1/
What I did was to look for the 4th sibling of the .divider like this .divider + .block + .block + .block + .block
It works, however, I'd have to write the same for the 8th, 12th, 16th, .. block, which doesn't make it automatic anymore.
Is there something like .divider + .block:nth-sibling(4) or .divider + .block:nth-of-class(4)?
Maybe one of you got an idea on how to solve this without changing the source code or using javascript.
Such a pseudo-class would not work because you are expecting it to match elements relative to a different compound selector, which is not how simple selectors work. For example, if you wrote a complex selector that only had a single compound selector with that pseudo-class (and no sibling combinators):
.block:nth-sibling(4n)
Would you expect this to match .block:nth-child(4n), match nothing at all, or be invalid?
It'd be nice to be able to abridge + .block + .block + .block + .block and make it repeat somehow, but unfortunately due to how the selector syntax is designed, it's just not possible.
You'll have to use JavaScript and/or add extra classes to the appropriate elements instead.
The issue here is that :nth-of-type refers to the type of element and both .divider and .block are elements of type <div>.
What you really need is for .divider to be a different type of element from .block.
On that basis, if the only two child elements of <div class="wrap"> are:
<div class="divider">
<div class="block">
I'd be tempted to swap out <div class="divider"> for <hr> - the thematic break element.
Then you can use:
.wrap div:nth-of-type(4)
to style .block.
As explained by BoltClock, you can't do this without JavaScript. If you choose that route (even though you explicitly say without JavaScript), it can be done with jQuery like this:
var counter = 0;
$('.wrap > div').each(function() {
if ($(this).hasClass('divider')) {
counter = 0;
}
else if ($(this).hasClass('block')) {
counter++;
if (counter % 8 == 4) {
$(this).css('background-color','#ff0');
}
}
});
That will color the 4th column in every row yellow.
Related
I have an html page with divs that have id(s) of the form s1, s2 and so on.
<div id="sections">
<div id="s1">...</div>
<div id="s2">...</div>
...
</div>
I want to apply a css property to a subset of these sections/divs (depending upon the id). However, every time I add a div, I have to add the css for the section separately like this.
//css
#s1{
...
}
Is there something like regular expressions in css that I can use to apply style to a set of divs.
You can manage selecting those elements without any form of regex as the previous answers show, but to answer the question directly, yes you can use a form of regex in selectors:
#sections div[id^='s'] {
color: red;
}
<div id="sections">
<div id="s1">one</div>
<div id="s2">two</div>
<div id="s3">three</div>
<div id="t1">four</div>
</div>
That says select any div elements inside the #sections div that have an ID starting with the letter 's'.
See fiddle here.
W3 CSS selector docs here.
As complement of this answer you can use $ to get the end matches and * to get matches anywhere in the value name.
Matches anywhere: .col-md, .left-col, .col, .tricolor, etc.
[class*="col"]
Matches at the beginning: .col-md, .col-sm-6, etc.
[class^="col-"]
Matches at the ending: .left-col, .right-col, etc.
[class$="-col"]
An ID is meant to identify the element uniquely. Any styles applied to it should also be unique to that element. If you have styles you want to apply to many elements, you should add a class to them all, rather than relying on ID selectors...
<div id="sections">
<div id="s1" class="sec">...</div>
<div id="s2" class="sec">...</div>
...
</div>
and
.sec {
...
}
Or in your specific case you could select all divisions inside your parent container, if nothing else is inside it, like so:
#sections > div {
...
}
First of all, there are many, many ways of matching items within a HTML document. Start with this reference to see some of the available selectors/patterns which you can use to apply a style rule to an element(s).
http://www.w3.org/TR/selectors/
Match all divs which are direct descendants of #main.
#main > div
Match all divs which are direct or indirect descendants of #main.
#main div
Match the first div which is a direct descendant of #sections.
#main > div:first-child
Match a div with a specific attribute.
#main > div[foo="bar"]
You can' just add a class to each of your DIVs and apply the rule to the class in this way:
HTML:
<div class="myclass" id="s1">...</div>
<div class="myclass" id="s2">...</div>
CSS:
//css
.myclass
{
...
}
I usually use * when I want to get all the strings that contain the wanted characters.
* used in regex, replaces all characters.
Used in SASS or CSS would be something like [id*="s"] and it will get all DOM elements with id "s......".
/* add red color to all div with id s .... elements */
div[id^="s"] {
color: red;
}
This question already has answers here:
Understanding CSS selector priority / specificity
(4 answers)
Closed 4 years ago.
This must be a very simple question for HTML ninjas out there, but I feel I'm missing something obvious here. Here is a snippet:
#red span {
color: red;
}
#green span {
color: green;
}
<div id="red">
<p><span>red</span></p>
<div id="green">
<p><span>green</span></p>
</div>
</div>
If I swap the stylesheet order, all of the text becomes red:
#green span {
color: green;
}
#red span {
color: red;
}
<div id="red">
<p><span>red</span></p>
<div id="green">
<p><span>green</span></p>
</div>
</div>
This happens despite the fact that <div id="green"> is a more inner parent of <span>green</span> than <div id="red"> in the DOM tree. I suppose it doesn't take precedence simple because its CSS now appears first in the order of stylesheets. So the order of stylesheets is what matters here.
Is this an expected behavior? Is this implementation/browser specific? Is there some official specs detailing that?
Finally, is there any CSS selector syntax I can use to make it work as in the first snippet, without relying on the order of stylesheets or adding new class names, ids, etc?
Yes, the result you got is absolutely expected—well, maybe not expected, but they are correct. Here are the official specs. And here’s a tweet poll of mine detailing the exact same problem. (Spoiler: the majority of voters got it wrong.) Read the replies for a more in-depth discussion.
Currently, there’s not any CSS technology that takes “closest parent” scope into account. And this is a common misconception a lot of programmers have. (CSS is not a programming language.) A typical programmer will think, “The selector #red span means wherever I see a #red, look for a span inside, and then apply the styles. Since #green span is inside the #red, the green will apply after the red.” This is simply incorrect.
The way CSS actually applies styles is that it looks at each element, then goes through the stylesheets from top to bottom, decides if it matches, and then applies/overrides styles as it goes. That’s just one aspect of the cascade, among others (such as inheritance and specificity). Since in your second example #red span comes last in the CSS source, it gets applied last, overriding #green span, regardless of “how close” the span is within the #red in the DOM.
To fix your specific problem, the easiest thing to do is use a direct child selector, like #red > p > span and #green > p > span. But as you’d suspect, these selectors would have to be updated if you ever change the HTML. Coupling your CSS and HTML is a hassle, especially as your project grows.
The best strategy is not to depend on the DOM to style your elements. What happens when you move the span outside the #red? Would you want it to keep its style? For maintainable and scalable CSS, you should use classes only (not IDs) and apply the class to the actual element you want styled, without depending on DOM structure or parent-child relationships. That way, when your HTML structure changes, you don’t have to adjust your CSS to match.
Example:
.red {
color: red;
}
.green {
color: green;
}
<div>
<p><span class="red">red</span></p>
<div>
<p><span class="green">green</span></p>
</div>
</div>
You can use > selector to make it apply to only specific span inside the div with the id you give and not all the span inside the div
#green > span {
color: green;
}
span {
color: red;
}
<div id="red">
<p><span>red</span></p>
<div id="green">
<span>green</span>
</div>
</div>
If you want to do it to all descendants, you can achieve it by Javascript like following, it decreases many line of codes if you want to apply many colors, but will be slower time than css. It's up to your preferences
var colors = ['red', 'green', 'blue', 'orange', 'brown']
var spans = document.querySelectorAll('span');
spans.forEach(function(spanElement) {
colors.forEach(function(color){
if(spanElement.closest(`#${color}`)){
spanElement.style.color=color
}
})
})
<div id="red">
<span>red</span>
<div id="green">
<span>green</span>
<p><span>green</span></p>
</div>
<div id="blue">
<span>blue</span>
</div>
<div id="orange">
<span>orange</span>
</div>
<div id="brown">
<span>brown</span>
</div>
</div>
I have an html page with divs that have id(s) of the form s1, s2 and so on.
<div id="sections">
<div id="s1">...</div>
<div id="s2">...</div>
...
</div>
I want to apply a css property to a subset of these sections/divs (depending upon the id). However, every time I add a div, I have to add the css for the section separately like this.
//css
#s1{
...
}
Is there something like regular expressions in css that I can use to apply style to a set of divs.
You can manage selecting those elements without any form of regex as the previous answers show, but to answer the question directly, yes you can use a form of regex in selectors:
#sections div[id^='s'] {
color: red;
}
<div id="sections">
<div id="s1">one</div>
<div id="s2">two</div>
<div id="s3">three</div>
<div id="t1">four</div>
</div>
That says select any div elements inside the #sections div that have an ID starting with the letter 's'.
See fiddle here.
W3 CSS selector docs here.
As complement of this answer you can use $ to get the end matches and * to get matches anywhere in the value name.
Matches anywhere: .col-md, .left-col, .col, .tricolor, etc.
[class*="col"]
Matches at the beginning: .col-md, .col-sm-6, etc.
[class^="col-"]
Matches at the ending: .left-col, .right-col, etc.
[class$="-col"]
An ID is meant to identify the element uniquely. Any styles applied to it should also be unique to that element. If you have styles you want to apply to many elements, you should add a class to them all, rather than relying on ID selectors...
<div id="sections">
<div id="s1" class="sec">...</div>
<div id="s2" class="sec">...</div>
...
</div>
and
.sec {
...
}
Or in your specific case you could select all divisions inside your parent container, if nothing else is inside it, like so:
#sections > div {
...
}
First of all, there are many, many ways of matching items within a HTML document. Start with this reference to see some of the available selectors/patterns which you can use to apply a style rule to an element(s).
http://www.w3.org/TR/selectors/
Match all divs which are direct descendants of #main.
#main > div
Match all divs which are direct or indirect descendants of #main.
#main div
Match the first div which is a direct descendant of #sections.
#main > div:first-child
Match a div with a specific attribute.
#main > div[foo="bar"]
You can' just add a class to each of your DIVs and apply the rule to the class in this way:
HTML:
<div class="myclass" id="s1">...</div>
<div class="myclass" id="s2">...</div>
CSS:
//css
.myclass
{
...
}
I usually use * when I want to get all the strings that contain the wanted characters.
* used in regex, replaces all characters.
Used in SASS or CSS would be something like [id*="s"] and it will get all DOM elements with id "s......".
/* add red color to all div with id s .... elements */
div[id^="s"] {
color: red;
}
Say i have this markup:
<div class='current'>
</div>
<div class='current'>
</div>
<div class='current'>
</div>
<div class='current'>
</div>
<div class='current'>
</div>
Now these divs are not necessarily next to each other in the markup, but could be spread throughout the page.
Can i target only the first occurrence of class "current" using CSS only, i'd ideally like to avoid using javascript (for now)?
Ie.
.current:first-child {
background: red;
}
I believe you're looking for something like this:
.current:nth-child(1){
background:red;
}
Should do the trick!
:first-child targets elements that are first children, not first occurrence of a given class. So this will target all elements with current class, that are first children. It can be all of them if they are in different places on a page or none at all.
It sounds like you may be looking for css3 selector first-of-type
As mentioned in these two answers (along with this new one), CSS3 doesn't bake in a pseudo-class that selects the first element of its class (unlike :first-of-type which selects by type).
You can always use :first-child if .current is guaranteed to be the first child of .group:
.group .current:first-child {
background: red;
}
But if it's not guaranteed to be, then based on your comments and the answer link, since they all share the same parent you can do this instead:
.group .current {
background: red;
}
.group .current ~ .current {
background: transparent; /* Or whatever your default is */
}
The general sibling combinator ~ ignores other elements that may not be .current. All these rules work in IE7+.
If they are spread throughout the page, you can not get what you need with pure CSS solution. Even with first-of-type unless the elements are on the same DOM level. Check the example to see that you can not select the elements.
On the other hand once I move the third .current to the same DOM level where I already have the second one, I get only the second item selected, as it's the first .current on this level.
On the other hand it's a very short one-liner in JS
Don't overcomplicate things ;)
If it's spread throughout the page, you can't target it with css.
In the markup below, I'm looking for a way (perhaps using css selector's) to style the content div differently depending on the presence of menu? Menu may or may not be present in that location in the markup and if it is there, I need to add some top margin to content.
I believe sibling and descendent selector rules might not go this far...
"When menu is present as a child of header set the top margin of content (whose parent is a sibling of header) to 100 pixels. Otherwise, set it to zero"
<div class="header">
<div class="sitetitle">site title</div>
<div class="tagline">tagline</div>
<div class="menu">menu</div>
</div>
<div class="main">
<div class="content">content goes here</div>
</div>
If css allowed groupings, I would do it this way...
(.header ~ .menu) + (.main > .content) {margin-top:100px;}
Not possible in your markup.
CSS selectors can only look at the ancestor and at the sibling axes. You cannot look inside ("what children do I have") - only upwards ("what are my parents") and sideways ("what's next to me").
Examples. This:
div.header div.menu
refers to any <div class="menu"> one of whose ancestors is a <div class="header">.
This:
div.header > div.menu
refers to any <div class="menu"> whose direct ancestor (i.e. "parent") is a <div class="header">.
This:
div.header ~ div.menu
refers to any <div class="menu"> that has a <div class="header"> among its preceding siblings, i.e. they have the same parent and occur one after another, but not necessarily adjacent to each other (that's "looking sideways").
This:
div.header + div.menu
refers to any <div class="menu"> whose direct preceding sibling is a <div class="header">.
There are no other traversing selectors in CSS (this statement refers to CSS2) and certainly there are no conditionals.
You could use jQuery:
$('.header:has(.menu) + .main > .content').css('margin-top', '100px');
Unfortunately the :has() selector didn't find its way into css3.
But why don't you simply apply a margin-bottom to div.menu?
You could possibly use some javascript to detect that. Check if menu is under header at load, and if it is, then set the margin-top of content to 100px
I used this CSS code in a conditional formatting.
Format index by counting from the end.
#stk-service-account-menu ul li:nth-last-child(1):before {