Complex CSS selector having many descendant - css

I want to select h3 and view-grouping-header class which resides under menu-publications parent. Please see the following screenshot:
In the above image, I want to select all <h3> and 2017 or 2016 or 2015 elements. Below is the CSS:
.menu-publications h3{
background-color: red;
}
.menu-publications > .view-grouping-header{
background-color: yellow;
}
I am not able to select view-grouping-header. Please see the JS-Fiddle here.

The correct selector is .menu-publications .view-grouping-header
.menu-publications h3 {
background-color: red;
}
.menu-publications .view-grouping-header {
background-color: yellow;
}
The element > element selector is used to select elements with a specific parent. Elements that are not directly a child of the specified parent, will not br selected.

That should be
.menu-publications .view-grouping-header{
background-color: yellow;
}
without the >- it's not a direct child

Related

How to check if parent is present or not?

I have two situations:
<div class="parent">
<div class="content">TEXT</div>
</div>
or
<div class="content">TEXT</div>
I want to change text color if class parent is present or not.
I write this css but it doesn't work:
div:not(.parent) > .content{
color: blue;
}
How can I solve it?
It doesn't work because in the second example you have no div element wrapping the content so div:not(.parent) is not matched (.content is a direct child of the body element)
Either you write
:not(.parent) > .content {
color: blue;
}
(without defining the element) or just reverse your logic: give a basic style for .content in case there's no parent element and override the style if the .parent exists:
.content {
color: blue; /* no .parent */
}
.parent > .content{
color: inherit;
}

Avoid CSS styling between certain adjacent elements and classes

I would like to add padding-top: 20px; between h3 and body but not if h3 is preceded by another element (e.g., h2). Is this possible?
Adding padding-top to all headings gives the desired padding when a heading is preceded by body text but an undesired padding between headlines:
Note that this document is Rmarkdown created using knitr, so I don't have full control over all the html. A pure CSS-solution would be preferred.
UPDATE:
To anyone also using knitr for Rmarkdown, the solution turned out to be a rather complex targeting:
/* First h2 following h1 */
.level1 > .level2:nth-child(3) > h2 {
padding-top: 0px;
}
/* First h3 following h2 */
.level2 > .level3:nth-child(3) > h3 {
padding-top: 0px;
}
Looking at the generated HTML, I learned that the first h2 after a h1 was in the third element in level1 and that that element was called level2. Similarly for the first h3. This is what is targeted above. The structure is probably different in other documents so take a look yourself.
How about
body > h3:first-child {
padding-top: 20px;
}
That will affect only immediate child of body with a header3, with nothing in between.
Thanks to #Oram, for pointing out missing :first-child
You can use the > selector plus :first-child to target only a direct h3 child.
* {
margin: 0;
padding: 0;
}
.test {
background-color: #cccccc;
margin: 10px;
padding: 10px;
}
.test > h3:first-child { color: red; }
<div class="test">
<h3>Targeted h3</h3>
<p>Paragraph</p>
<h3>h3 not targeted</h3>
</div>
<div class="test">
<p>Paragraph</p>
<h3>h3 not targeted because of the p tag</h3>
<h3>h3 not targeted</h3>
</div>
Try this:
body > h3:first-child {
padding-top: 20px;
}
It will only apply the CSS to the first direct child of the body which is a h3.

CSS nesting: inherit from whom?

here is a fiddle with the problem:
https://jsfiddle.net/c2exs2f7/3/
How does the second "blue" stay like the first instance (it should have color: white) without changing the HTML structure?
HTML
<div class="blue">
<div class="content">
<div class="label">blue</div>
<div class="yellow">
<div class="content">
<div class="label">yellow</div>
<div class="blue">
<div class="content">
<div class="label">blue</div>
</div>
</div>
</div>
</div>
</div>
</div>
SCSS
// Skip until...
div {
border-radius: .25em;
padding: .5em;
font-family: helvetica, sans-serif;
}
// ...here:
.blue {
background-color: hsl(220,100%,50%);
.content {
color: white;
}
}
.yellow {
background-color: hsl(60,100%,50%);
.content {
color: hsl(0,0%,10%);
}
}
EDIT #1
Thank you guys for these fast responses!
I am working on a grid system where I am able to nest different grid systems (with different CSS values).
The selectors .yellow .content and .blue .content have the same specificity (20 in this case), therefore the selector that appears later in the stylesheet will override the first one due to the cascading nature of a stylesheet. In this case, the selector .yellow .content is overriding .blue .content, which is why the nested .blue element is black.
One quick solution would be to select nested .blue element with the selector .blue .blue:
Updated Example
.blue,
.blue .blue {
background-color: hsl(220,100%,50%);
.content {
color: white;
}
}
An arguably better approach would be to only select direct .content children elements using the child selector, >:
Updated Example
.blue {
background-color: hsl(220,100%,50%);
> .content {
color: white;
}
}
.yellow {
background-color: hsl(60,100%,50%);
> .content {
color: hsl(0,0%,10%);
}
}
Based on your comments, the ordering/layering of the elements may vary. An alternative solution would be to set the color property on the .blue/.yellow element and then set the color property of the children elements to inherit:
Updated Example - this seems to work for all variants.
.blue {
background-color: hsl(220,100%,50%);
color: white;
.content {
color: inherit;
}
}
.yellow {
background-color: hsl(60,100%,50%);
color: hsl(0,0%,10%);
.content {
color: inherit;
}
}
See https://jsfiddle.net/c2exs2f7/4/
What I did was to enforce inheritance only for the child content classed DIV, not the entire descendance.
Applying the immediate children operator > in the SCSS makes the .content div to consider only its immediate parent color.
Go on and try nesting more DIVs, you will see that it works.
You can't. Not with inherent anyway. Because the second blue will inherent from the yellow. So if u want all blue always have white letters and yellow always black letters. Why not just put:
.blue { color: #fff; }
.yellow { color: hsl(0,0%,10%); }
And you won't need the ".content" wrapper.
I had this same issue where the HTML nesting varies and so it's not possible to make more specific selectors due to overwhelming complexity and non-DRY code.
Here's the solution I came to:
https://jsfiddle.net/cg0u8v1s/
Basically, a systematic approach to the class names is key so you can use a CSS attribute selector reliably (although I'd recommend a more unique naming convention than "color-" as it's too generic.).
Example:
.color-blue {
&,
[class*="color-"] &,
[class*="color-"] [class*="color-"] & {// Only needed if you want a 3rd level of nesting to work.
background-color: blue;
.content {
color: skyblue;
}
}
}
.color-yellow {
&,
[class*="color-"] &,
[class*="color-"] [class*="color-"] & {// Only needed if you want a 3rd level of nesting to work.
background-color: yellow;
.content {
color: brown;
}
}
}
This will output selectors that become more specific with nesting without the need for non-DRY code or having to use !important.
The CSS output will look like this:
.color-blue,
[class*="color-"] .color-blue,
[class*="color-"] [class*="color-"] .color-blue {
// code...
}

CSS Style Individual <div=id

I have a ccs sheet with the usual tags
a. {}
a.hover {}
I also have a div=id "footer" that I want to change the font style but the global a. and a.hover are overriding it even when I add a
#footer{
color: #333333
}
Can I override using this or do I need to try? a.#footer or a.hover:#footer
Basically the #footer as is wont work because of the a. mentioned above even though the other elements are working in the #footer div such as margin...just the font color and hover??
Can someone tell me how to style this and not let the global a. interfere with it?
Many thanks
It's all about the hierarchy of code:
HTML:
<div>
Sample link
<div id="footer">
Footer link
</div>
</div>
CSS:
a {
color: #ebebeb;
}
a:hover {
color: #000;
}
#footer a {
color: #3e3e3e;
}
#footer a:hover {
color: #609;
}
Try this piece of code
#footer a,
#footer a:hover{
color:#333;
}
what is dot after a ?
the correct form is a {} , a:hover {} , a#footer and a:hover #footer
If you are nesting a inside div element you need to use
#footer a {
color: #333333;
}
If you only use #footer {} it will apply the styles to div and a won't inherit the color, so you can also write
#footer {
color: #f00;
}
#footer a {
color: inherit;
}
This is a matter of specificity. Styling the <a> elements directly is more specific then just applying some CSS to the <div id="footer"> element and all of its children. You can target any links within your footer by using
#footer a {
color: #333;
}
Due to the descendant selector this rule itself is more specific than the one you're using for all the other <a> elements outside of the footer.

CSS selector: Style the first "a" inside a div

I am having trouble finding the correct CSS selector, the structure I have looks like this:
<div>
</div>
<div>
</div>
<div>
</div>
I would like to style the a element of the first div
I have tried with this selector but with no luck
div:first-child a{}
first-child should work absolutely well, you can try
div:nth-of-type(1) a { /* Or div:first-child a */
color: red;
}
The above selector will select all 1st div element and will apply color to all a which are inside 1st div
Demo
If you are willing to style 1st occurrence of a in every div tag than you need to use
div a:nth-of-type(1) { /* Or div a:first-child */
color: red;
}
Here every 1st a will be selected in every div tag
Last but not the least if you want to select 1st a only in 1st div than use the below selector
div:nth-of-type(1) a:nth-of-type(1) { /* Or div:first-child a:first-child */
color: red;
}
Note: If still the above selectors doesn't work, than the possibility
is either some rule is more specific than the rules you are declaring,
or !important is used somewhere, or (least chances) you are testing
on older browsers
Your own example is working too.
http://jsfiddle.net/7Pea3/
div:first-child a {
color: #f00;
}
The first div will be selected and all a recive the color #CCC. I don't understand why this isn't working.
div:first-child a {
color: #CCC;
}
Else test this solution, that selects the first div and styles the first a tag in the div:
div:first-child a:first-child(1) {
color: #CCC;
}
Else you have problems with the :first-child selector use the :nth-of-type({ number expression | odd | even }) selector.

Resources