Given the following HTML, I want to be able to apply CSS to the .first element where .second exists. I understand :has isn't available at the moment, and ideally I don't want to use JavaScript.
<div class="container">
<div class="first"></div>
<div class="second"></div>
</div>
The CSS for :has I'd assume would be below. Is there any other CSS I can apply to make this work without the usage of :has.
.container > .first:has(+ .second) {
// styles here
}
If .second doesn't exist, then no CSS style should apply.
In your simple example you could work with :not(), like
.container > .first:not(:only-child) {
// styles
}
For more complex scenarios you may need a little more creativity, but hope this gives you an idea.
Related
I am making a theme for a website, but I ran into a problem. I can't change their HTML or use javascript, only CSS.
This is what the site's HTML looks like:
<div class="container">
<div style="margin:a ridiculously massive number">
<p id="title"> Title of page </p>
<p> Words that cannot be read because of the ridiculous margin </p>
</div>
<div id="otherContent"> There a lot of divs without ridiculous margin all with different ids </div>
</div>
I want to remove the ridculous margin without affecting the other divs margins. Is this possible?
yes you can target the div that is the first-child inside of .container as to not effect other divs.
.container div:first-child{
//code
}
EXAMPLE 1
Example 1 is specifically for the example you posted where the div you would like to target is the first child of it's parent. Also note if the margin is inline like your example you're going to have to over-ride it with !important like so:
.container div:first-child{
margin: 0 !important;
}
OR
You could also use the :not selector if the other's have a similar class
.container div:not(.classname) {
//code
}
EXAMPLE 2
The point of example 2 is if your div isn't the first child and the only without a class (it would probably be unlikely you would have multiple divs with the same classname except one but it's possible). in your example you could also use :not() to target that other div with id #otherContent like so:
.container div:not(#otherContent) {
//code
}
OR
The last option you can use if the others don't apply would be nth-of-type() to target specifically which one you want to effect:
.container div:nth-of-type(2) {
//code
}
EXAMPLE 3
In this case you will have to use first-child selector with !important keyword, as this is the only way to make rule more specific than style="margin" rule:
.container > div:first-child {
margin: 0 !important;
}
If all the other divs have ID you can use the following:
div>div:not([id]) {
margin: 0 !important;
}
Hope you can help me with this CSS trick.
Basically what I need is this kind of CSS
if 'container' has sibling 'mySibling' {
#myDiv{
}
}
if 'container' has no sibling {
#myDiv{
}
}
For this HTML
<div id="mySibling"></div>
<div id="container">
<div id="myDiv"></div>
</div>
sibling sometimes will not be present, and I need different css for myDiv in these cases
Any help would be appreciated, I tried doing + and ~ selectors but I don't think I have proper logic.
You can do something like this:
#mySibling + #container #myDiv {
background-color:blue;
}
Here is a fiddle showing it off: http://jsfiddle.net/Lzq3S/
Note, I've changed the ids to classes in the fiddle just to show the two sets of div elements, but you get the idea...
This breaks down to myDiv that is a child of container that is a sibling of mySibling.
First off, make sure your html is correct; in your example, you forgot to specify whether you're using an id or a class! Possible options for your html:
<div id="container">
<div class="mySibling"></div>
<div class="myDiv"></div>
</div>
or
<div id="container">
<div id="mySibling"></div>
<div id="myDiv"></div>
</div>
For the sake of your example, we'll use id's, even though some would say it's better practice to use classes
Now for the CSS.
The + and ~ selectors operate in slightly different ways. The + selects adjacent siblings, while the ~ selects all siblings. Because CSS doesn't handle logic quite the same way as actual programming languages, you can't check to see if a container holds a certain element before applying styles, but you can use the sibling selectors to style elements that are next to certain other elements.
My suggestion:
.container #myDiv {
/* Your styles for #myDiv */
}
.container #mySibling + #myDiv {
/* Your styles for #myDiv it is next to #mySibling.
Will override the styles a */
}
You can check out an example here: http://jsfiddle.net/8r2TZ/. Note, I specified "myDiv" as a class, because I used it more than once, and my CSS reflects that.
If you do need to have a CSS rule for each case without relying on overriding, it's still possible, since there's a selector for elements with no siblings:
#mySibling + #container > #myDiv {
}
#container:only-child > #myDiv {
}
(You can even achieve compatibility with old IEs by using :first-child in lieu of :only-child since #mySibling comes first.)
I write a html element as below ::
<div class="box"> Foo box </div>
and write css like
.box {
width: 400px;
height: 40px;
color: red;
text-align: center;
}
or
div.box {
width: 400px;
height: 40px;
color: red;
text-align: center;
}
I want to ask that how the both css for box class is different than each other.
The difference is that in the first class you tell that all element (div, p, span ...) with class box have that attribute.
Like this:
<span class="box">test</span>
<div class="box">test</div>
<p class="box">test</p>
The second class means that only div with class box has that attribute
Only this elements get second class:
<div class="box">test</div>
The selector before the class specify which type of elements can take this class
One very important difference between div.box and simply .box is in something called selector specificity. It is a set of rules which defines which selector gets more weight once the browser starts going through all the selectors that potentially have influence on a particular element.
What this means is easily demonstrated in the following example (DEMO)
We have a simple div containing some text.
<div class="box">
Zarro boogs found!
</div>
Now we add some CSS selectors to the example.
div.box {
padding:0.8em;
background: #bd0000;
color: #fff;
}
.box {
color: #bd0000;
}
One of the most basic rules of CSS is that selectors can be redefined in a way that whatever definition comes last and has influence on a particular element its the one that is going to be used (the sole exception being when using !important which always takes precedence).
Now in the above example redefining the .box class selector should actually hide the text but instead its still visible. How is that possible if we said that latter rules always take precedence? Its because the div.box rule has a higher specificity that .box since it actually gets points for containing both an element (div) and a class selector (.box) in its selector declaration (div.box).
Of course the div.box rule will be applied only on a div element but since class selectors are often reusable pieces of code there is plenty of situations when they are used on divs.
Although the rules in the official W3 specification are not that hard to understand they are sometimes pretty hard to remember. That's why I would like to recommend an excellent article on CSS selector specificity which can be found here.
In my opinion selector specificity is by far the most important thing to master when it comes to tracing inheritance problems with CSS stylesheets.
.box means any element having class box.
Example:
<div class="box">...</div>
<section class="box">...</section>
<span class="box">...</span>
div.box means only div element having class box.
Example:
<div class="box">...</div>
I have this code.
<div class="myDiv">
<div>
I want to be red.
</div>
</div>
<p>I'm some other content on the page</p>
<div class="myDiv">
<div>
I want to be blue.
</div>
</div>
.myDiv div:nth-child(odd) {
color: red;
}
.myDiv div:nth-child(even) {
color: blue;
}
I see why it's not working. It's making every odd div within myDiv be red. What I want it to do is make every odd example of a div within myDiv be red. How can I write that?
Here's a JSFiddle.
There are a couple of problems here. The :nth-child is on the wrong element. The inner divs are always the first child, so the :nth-child(odd) selector works for both. Instead move to
.myDiv:nth-child(odd) div
...however this does not work either because of the <p>. A working solution with your sample is
.myDiv:nth-of-type(odd) div
http://jsfiddle.net/tvKRL/1/
NOTE that the nth-of-type only works because the .myDiv elements are all divs (it's based on the element, not the selector), so the selector ignores the <p>. If there can be another div between .myDivs I don't think any CSS will work for what you want to do.
You can't do this generically, for the reason given by Domenic. To put it simply: there's no selector that lets you filter an existing subset of matched elements.
On the off chance that among your p and div.myDiv siblings the only div elements are the ones with that class anyway, then you could use :nth-of-type() to have it look at those intermediate divs only:
div.myDiv:nth-of-type(odd) div {
color: red;
}
div.myDiv:nth-of-type(even) div {
color: blue;
}
Or if there are other divs without that class which should be excluded, then unless there is some sort of pattern in which they're laid out, you're out of luck.
This is not possible. There is no CSS selector that will do what you want, as you can see by perusing the complete list of selectors.
In general CSS selectors do not "reach out" to encompass elements above the DOM tree of the one selected. You are asking for something even more sophisticated than that, combining characteristics of parent elements with ordinal properties of the targeted elements, even though those targeted elements are distributed among entirely different places in the DOM tree.
Just applynth-childto the first member of the descendant selector, not the last one.
div:nth-of-type(odd) > div {
color: red;
}
div:nth-of-type(even) > div {
color: blue;
}
<div class="myDiv">
<div>
I want to be red.
</div>
</div>
<p>I'm some other content on the page</p>
<div class="myDiv">
<div>
I want to be blue.
</div>
</div>
Here is the html layout
<div class="wrap">
<div class="section">
<span class="text">text1</span>
</div>
<span class="text">text2</span>
<span class="not-text">don't color me!</span>
</div>
Im trying to give a style to all "text" spans which are not in the "section" divs.
I tried this, but it doesn't seem to be working
.wrap :not(.section) .text
fiddle
Any help is greatly appreciated!
Edit: There are several workarounds for this case including the use of > operator like in ".wrap > .text", but I would like to know how to make the :not selector working, to make use of it in the future
When you use .wrap :not(.section) .text, this is what you're telling the browser:
Look for an element with a class of .text
which lives inside an element that does not have a class of .section
which lives inside
an element that has a class of .wrap
If you look closely at your markup, none of your elements meet that selector criteria.
In the markup you provided, I don't think you can specifically select those .text elements that are not descendants of .section using :not().
The closest you could get is by using a direct descendant selector, like this:
.wrap > .text
You could also select and style all .text descendants of .wrap (whether direct or not), and then cancel those styles for any .text elements inside of .section, like this:
.wrap .text {
// your styles here
}
.wrap .section .text {
// your cancelled styles here
}
You can probably use:
.wrap > span
.wrap > *:not(div)
.wrap > *:not(.section)
Best option given the constraints of CSS are to write a rule for all text and then override them back to the previous value for those within .section. So
.wrap .text {
// the styles you want
}
.wrap .section .text {
// styles undoing the styles above... depending on what the styles are it may not always be possible
}