Why does .b:not(#a>.b) not work? - css

I'm working with some CSS and wondering why the following piece doesn't work:
.container:not(#topic-title>.container)
Is there anyway else I can achieve the same thing? I'm open to JavaScript solutions.

You could use this selector :
:not(#topic-title) > .container
.container {
height:20px;
}
:not(#topic-title) > .container {
background:green;
}
<div id="topic-title">
<div class="container">parent #topic-title</div>
</div>
<div>
<div class="container"> parent not #topic-title</div>
</div>

Take a look at the spec for the :not pseudo class: (bold is mine)
The negation pseudo-class, :not(X), is a functional notation taking a
simple selector (excluding the negation pseudo-class itself) as an
argument.
where
A simple selector is either a type selector, universal selector,
attribute selector, class selector, ID selector, or pseudo-class.
Hence #a>.b is not a simple selector and that's why the selector .b:not(#a>.b) doesn't work.

Here's an example with background-color, a margin example would be analogous. The idea: set a default page-wide, then cancel for instances where you don't want it.
.container {
background-color: red;
}
#topic-title > .container {
background-color: inherit;
}
<div>
<div id="topic-title">
<div class="container">A</div>
</div>
<div class="container">B</div>
</div>
<div class="container">C</div>

Related

CSS Selector Within a Selector

Essentially what I am trying to do is have one element react as the hover state of a different element.
.page-template-page-services-new .imgBlock:hover { .page-template-page-services-new .ButtonService {color: #6395ce; background-color: #fff; } }
Not currently working - is this a thing? If not, how might I accomplish it. I know the selectors are correct, they work independently.
What I think you are referring to is that you've seen something akin to
.selector-one{
//style definitions
.selector-two{
//other style definitions
}
}
This comes from pre-processors such as SCSS (Sass) or LESS, I'll assume you can do a quick google on those.
For the other part of your question, yes, you can style an element differently if it's parent container or even a sibling is hovered.
Example
.container-hover:hover .red-on-hover{
background-color:red;
}
.sibling-hover:hover + .sibling-hover{
background-color:blue;
}
<div class="container-hover">
<h3>Other Text</h3>
<div class="red-on-hover">Background will turn red on hover</div>
</div>
<p class="sibling-hover"> When I am hovered, my sibling will be blue</p>
<p class="sibling-hover"> Blue? Blue</p>
For the sibling hover, please note that if you added more .sibling-hover elements that all but the first one would be able to turn blue if you hovered over it's immediately prior sibling.
It can work if they have a parent child relationship.
.page-template-page-services-new {
background: #ccc;
}
.page-template-page-services-new .imgBlock:hover .ButtonService {
color: #6395ce;
background-color: #fff;
}
<div class="page-template-page-services-new">
<div class="imgBlock">
<img src="http://placehold.it/100/100" alt="">
<div class="ButtonService">
<p>
This is a test
</p>
</div>
</div>
</div>

How do i style two same class divs differently?

So basically I've got a setup that spits out the code in the following fashion..
<div class="parent">
<div class="subparent">
<div class="TARGETCLASS"></div>
</div>
<div class="subparent">
<div class="TARGETCLASS"></div>
</div>
</div> //close for the parent class
Now what I'm trying to do is to style "TARGETCLASS" that comes above one way and the "TARGETCLASS" that comes second in another way. I tried n-th child, but unable to achieve the result I'm looking for. There's no way to add additional classes or ID to the existing "TARGETCLASS" class. Otherwise I wouldn't be posting this question :)
Also, the "subparent" class also is same. for both the targetclass classes. That's the issue
Thanks in advance for taking your time to answer this question for me.
Cheers!
Looks like you've got some mal-formed tags in your html. And nth-child should work just fine. Also, make sure you place the nth-child selector on the subparent class, and not TARGETCLASS. It's common to mis-place the child selector. Try this:
<div class="parent">
<div class="subparent">
<div class="TARGETCLASS">
first-child
</div>
</div>
<div class="subparent">
<div class="TARGETCLASS">
second-child
</div>
</div>
</div>
<style>
.parent .subparent .TARGETCLASS {
background-color:#f00;
}
.parent .subparent:nth-child(1) .TARGETCLASS {
background-color:#0f0;
}
</style>
fiddle: https://jsfiddle.net/8ejxokuj/
I would use nth-of-type selector like so:
.parent{}
.parent > .subparent {} //targets both subparents
.parent > .subparent:nth-of-type(2) {} //targets the second subparent
.parent > .subparent:nth-of-type(2) > .TARGETCLASS{} //targets the child of the second subparent
The nth-of-type() selector enables you to style a specific element amongst a series, in this case we targeted the second .subparent then specified the child we needed.
I hope this helps!
It seems, it is working by the nth child.
it is about how childrens are called. Not like "Ask parent to find nth child, but ask child, how far is he from parent"
.parent .subparent:nth-child(1) {background: #FEE; color:RED;}
.parent .subparent:nth-child(2) {background: #EEF; color:blue;}
<div class="parent">
<div class="subparent">
<div class="TARGETCLASS">aaa</div>
</div>
<div class="subparent">
<div class="TARGETCLASS">bbb</div>
</div>
//close for the parent class
</div>

How to properly select these elements?

<div id="main-content">
<div>
<div>target me
<div>don't target me</div>
</div>
</div>
<div>
<div>target me too
<div>don't target me</div>
</div>
</div>
</div>
I've tried this:
#main-content div>div {
}
But this ALSO targets the divs saying "don't target me" I wish not to target those divs.
Of course we can use Id's or classes, but the point is to declare a general rule for all.
Please advice.
Just refine the selector a bit to enforce the hierarchy: #main-content > div > div
http://jsfiddle.net/zXaLU/
As a note, when using structural selectors it's nice to reference non-generic tags.
Example: #main-content > NAV > UL is more meaningful than #main-content > DIV > DIV
If you want styles only to apply to the outer of the two divs, you need to use two style definitions. The first sets the style for the div targeted and the second for the inner div not to be targeted:
#main-content div>div {
/* set some styles */
}
#main-content div>div>div {
/* reset the styles defined before */
}
In general the inner div (not targeted) inherits all the styles of its parent div, so in order to nullify that effect, you have to explicitly reset all those styles again.
EDIT
After all comments: If "targeting" does not include usual CSS inheritance, Tim Medora's answer is more suitable. My answer tried to account for inheritance as well.
How [dooes one] properly select [the specified] elements?
The "proper" way would be to give the items you want to select a class that is indicative of their status:
<div id="main-content">
<div>
<div class="someclass">target me
<div>don't target me</div>
</div>
</div>
<div>
<div class="someclass">target me too
<div>don't target me</div>
</div>
</div>
</div>
...and then you can simply use the class selector:
.someclass {
...styles...
}
But if you're unable to modify the markup, you can still use the child selector chain:
#main-content > div > div {
...styles...
}

What's the difference between CSS classes .foo.bar (without space) and .foo .bar (with space)

Would you please explain me the difference between these two CSS classes syntax:
.element .symbol {}
and
.element.large .symbol {}
I don't understand the difference between the two. The first line indicates two different classes to which are applied the same styles. But about the second, what's the meaning of '.large' which is written attached to '.element'?
.element .symbol
means .symbol inside .element
.element.symbol
means .element that has the class symbol as well.
So,
.element.large .symbol
means .symbol inside .element that has the class large as well.
I think you got a slight misunderstanding what the first one means.
.element .symbol {}
Means that those CSS settings are applied to any HTML element with the class .symbol that is inside an element with the class .element.
<div class="element">
<div class="symbol" />
</div>
In this example your first CSS entry would affect the <div> tag in the middle.
Your second example means that the first class requires two classes to be affected. Other than that it's equal to the first one.
<div class="element large">
<div class="symbol" />
</div>
So if the HTML looks like this, the CSS values will be applied to the inner <div> tag as well.
If you want to set CSS tags that apply for multiple classes separately then you need to split them up using a comma. So it looks like this:
.element, .symbol {}
Edit: By request the link to the documentation of the CSS selectors.
Using
.element.large
refers to an element with both classes:
<div class="element large"></div>
rather than a descendant of an element:
.element .large
meaning that in:
<div class="element">
<div class="large"></div>
</div>
only
<div class="large"></div>
is 'receiving' the styles.
Basically, being separated by a space implies two elements with a descendant relationship.
You would use .element .symbol this where you have an element inside of another element. For example:
<div class="element">
<i class="symbol"></i>
</div>
If down the road you wanted to differentiate some divs, you could add an additional class to target only those that differ, and target it with .element.large .symbol. So, for example:
<div class="element large">
<i class="symbol"></i>
</div>
In your second example, the first part of the selector is simply an element with two classes, as in <span class="element large"> or <span class="large element">.
In general, each part of a selector applies to one HTML element.
table[border].clname means a table with a border attribute and a class of clname, while table [border] .clname means an element with class clname, in an element with a border attribute, in a table.
(Edit: well, I say "one HTML element", but of course you can have more than one table that this applies to. You understand.)
Without whitespace, you are simply more specific with the selector. Because classes can appear several times in the html dom. But two or more classes in one element is rarer and therefore more precise.
Selectors with a whitespace (.a1 .b2) say search for the class a1 and see if there is a child or child-child element with the class b2 in this element.
An even higher degree of accuracy can be achieved with the >selector (.a1 .b2 > span). This states that only span elements should be taken into account which are direct children of the class .b2 located within an element with the class a1.
.a1 .b1 {
color: green;
}
.a1.a2 .b1 {
color: red;
}
.a1.a2 .b2 {
font-style: italic;
font-weight: bold;
}
.a1.a2 .b2 > span {
color: orange;
}
<div class="a1">
<div class="b1">Hello France</div>
<div class="b1">Hello Spain</div>
<div class="b2">Hello Sweden</div>
</div>
<hr/>
<div class="a1 a2">
<div class="b1">Bye France</div>
<div class="b1">Bye Spain</div>
<div class="b2">
Bye
<span>World</span>
</div>
</div>

first-child not working

Should this work am I going crazy?
.project.work:first-child:before {
content: 'Projects';
}
.project.research:first-child:before {
content: 'Research';
}
<div class="project work">
<p>abcdef</p>
</div>
<div class="project work">
<p>abcdef</p>
</div>
<div class="project work">
<p>abcdef</p>
</div>
<div class="project research">
<p>abcdef</p>
</div>
projects:first-child works fine, research:first-child doesn't stick. Any ideas?
Demo It doesn't work, but whats the best way to achieve this?
:first-child only selects the first child of its parent. Nothing else.
As mentioned in a few of my other answers on the site (1 2 3 4), there is no :first-of-class pseudo-class. If you are looking to apply styles to the first of each class of your div elements, a solution is to apply the styles to all children of that class, and a general sibling selector to undo the styles from subsequent siblings.
Your CSS would then look like this:
.project.work:before {
content: 'Work';
}
.project.research:before {
content: 'Research';
}
.project.work ~ .project.work:before,
.project.research ~ .project.research:before {
content: none;
}
From the specification:
Same as :nth-child(1). The :first-child pseudo-class represents an element that is the first child of some other element.
.project.research is not the first child of its parent.
I believe you want this CSS:
.project.work p:first-child:before {content:'Projects';}
.project.research p:first-child:before {content:'Research';}
or
.project.work > p:first-child:before {content:'Projects';}
.project.research > p:first-child:before {content:'Research';}
Updated fiddle
That matches the first child of an element with the classes "project" and "work" (or "project" and "research"). You don't have to use p:first-child if it may not be a p element, you could use *:first-child instead.

Resources