This question already has answers here:
What does the ">" (greater-than sign) CSS selector mean?
(8 answers)
Closed 3 years ago.
I have a css reset where I put margin to zero. Then further down the code I want to add a margin-bottom to all the elements. But it isn't working and I can't find out why.
I have tried to use the !important rule but that isn't working either and not really the solution I'm after. In my head the specificity should work because they both have the specificity 0,0,1 and the last rule should apply.
Or is it like that the * rule has specificity 0,0,0 and doesn't "beat" the specificity of the others selectors after html and body tags because they have specificity 0,0,1?
html,body,address, article, aside, footer, header, h1, h2, h3, h4,
h5, h6, hgroup, main, nav, section {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
body > * {
margin-bottom: calc(1 * var(--line-height));
}
The result I'm after is that the body > * should apply.
If you want to target all elements you can use
* {
margin-bottom: 1rem;
}
The > symbol is a child combinator, it will only target elements that are direct descendants of the first element.
My guess is that is styling the targeted elements but that these are not the elements you expect to be targeted.
To better visualize this, try and style the border of these elements intstead:
body > * {
border: 10px solid red;}
Related
I don't understand why scoped tag styling, which is like this
.parent > input {
margin: 0;
padding: 0;
border: 0;
outline: 0;
}
has side effect to the input tag that is not nested in the parent tag.
demo
https://codesandbox.io/s/scoped-styling-question-ecs7o?file=/src/styles.module.css:377-430
I think the second input tag should have outline default style since it is not nested in parent tag.
I used npx create-react-app to set up this project.
In your example, your css is nested inside .parent only for iframe. If you want to nest everything inside .parent, you should transform
.parent > iframe,
h1,
h2,
h3,
... {
...
}
in
.parent > iframe,
.parent > h1,
.parent > h2,
.parent > h3,
... {
...
}
I just saw this in a css file:
#nav { margin: 13px 0 0 0; }
#nav ul li { margin: 0 20px 0 0; }
Doesn't the second #nav property definition cancel out the first #nav property definition?
(Also: am I saying this right? "Property definition"? What's the generally accepted term for the stuff inside the curly brackets?).
No, they are applied to different elements, because they have different selectors.
The first rule applies to an element with id "nav". The second rule applies to an element li, that is a descendant of an element ul, that is descendant of an element with id "nav".
You can read about CSS Selectors here: https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_started/Selectors
1) No. The second selector only applies to li which is descendant of ul which in turn is the descendant of #nav, while the first one only applies to the #nav
2) You call them as "style"
The second definition does not "cancel" the first one; it selects the named elements that are descendants of nav rather than selecting the nav element itself.
List items (li) that are descendants of unordered lists within an element with ID of nav will be styled by the second specification. (Edited per Quentin's comment.) The element with the ID nav will use the first specification. Elements within #nav may inherit from the first specification. For some properties, but not margin, inheritance is automatic. The font-family property is an example. The margin property can only be inherited through an explicit margin: inherit; specification.
If the code looked like this:
#nav { margin: 13px 0 0 0; font-family: Helvetica, Arial, sans-serif;}
#nav ul li { margin: 0 20px 0 0; }
Then the list items, and everything else within nav that did not have a font-family specification of its own would have a sans-serif font.
The things inside the curly braces are properties and values. So, margin is a property, and the margin specifications are the values. The things left of the curly braces are selectors.
Is there a more efficient way to select multiple parent and descendant groups?
What I have now:
aside p, aside h1, aside h2, aside h3, aside h4,
article p, article h1, article h2, article h3, article h4,
section p, section h1, section h2, section h3, section h4 {
width: 75%;
padding: 15px 0;
margin: 0 auto;
text-align: center;
}
:matches()
You can use the :matches() CSS pseudo-class function to group your parents and descendants:
:matches(aside, article, section) :matches(p, h1, h2, h3, h4)
Note that, at the time of writing, this is still an experimental technology, so you may want to view the browser compatibility before using this in production.
Older browsers may require using the vendor-prefixed pseudo-class :any():
:-moz-any(aside, article, section) :-moz-any(p, h1, h2, h3, h4),
:-webkit-any(aside, article, section) :-webkit-any(p, h1, h2, h3, h4),
:matches(aside, article, section) :matches(p, h1, h2, h3, h4)
According to CSSWG issue #3258, :matches() might be renamed to :is() in the future:
:is(aside, article, section) :is(p, h1, h2, h3, h4)
You could remove all the tag specificity.
p, h1, h2, h3, h4 {
width: 75%;
padding: 15px 0;
margin: 0 auto;
text-align: center;
}
Using pure CSS, your current way is probably the most efficient means, other than setting a class on all the h tags.
Using LESS, you could do something like this:
aside, article, section {
h1, h2, h3, h4 { ... }
}
if there are only (p, h1-h4) in parents you can do that:
aside > *, article > *, section > * {
width: 75%;
padding: 15px 0;
margin: 0 auto;
text-align: center;
}
it will affect only direct children.
The most performant, concise and specific selector would simply be:
.selector {
width: 75%;
padding: 15px 0;
margin: 0 auto;
text-align: center;
}
it could be opinable that it will pollute your markup but in pure terms of css performance this is it.
with regards to * selector, its performance is poor and adding a parent selector will NOT improve the situation, as illustrated here
The style system matches rules by starting with the key selector, then moving to the left (looking for any ancestors in the rule’s selector). As long as the selector’s subtree continues to check out, the style system continues moving to the left until it either matches the rule, or abandons because of a mismatch.
one last remark, aside, article, section are not supported in IE < 8 so any styling won't be picked up by those browsers (unless a polyfill is used but that is a JS only way)
In my style sheet, I have overridden the style of H1 and H2 with the following code:
And in my HTML, I have applied that style to a DIV that contains an H1 tag.
However, this style is also applying to H1 and H2 tags AFTER the div in question.
Replicated here: http://jsfiddle.net/89gkQ/1/
Why is the style applying outside of the div where it's applied, and how do I stop it?
In CSS, the comma doesn't work like it does in English:
.featuredtitle h1, h2 {
color: red;
}
That code is equivalent to this code:
.featuredtitle h1 {
color: red;
}
h2 {
color: red;
}
Which isn't what you want. The comma just allows you to write multiple selectors, so you want to be a bit more verbose:
.featuredtitle h1, .featuredtitle h2 {
color: red;
}
Demo: http://jsfiddle.net/89gkQ/2/
The problem is here:
.featuredtitle h1,h2 {
font-size: 1.5em;
font-weight:bold;
color:#a00;
}
You should write the following instead:
.featuredtitle h1, .featuredtitle h2 {
font-size: 1.5em;
font-weight:bold;
color:#a00;
}
The comma starts a new selector, which in this case made the style apply to all H2 tags, regardless of where they are.
I have 2 div elements #container1 , #container2. Can i use styling in below manner ?
#container1,#container2 h5{
}
If yes then i cudn't get it to work for #container3
#container1,#container2,#container3 h5{
}
rule somehow doesn't seem to apply for #container3 ..
What could be the reason ?
That selector will apply to #container1,#container2, and any h5s in #container3. I think you want:
#container1 h5,
#container2 h5,
#container3 h5 {
/* styling */
}
This is exactly what classes are intended for, however. If you add class="container" to each of your container divs, you can simply use the following rule:
.container h5 {
/* styling */
}
The h5 at the end means that particular rule only applies to h5 elements inside the id.
As an exmaple, from your first example...
#container1,#container2 h5{
}
The above rules would apply to an element with id=contrainer1 and also to an h5 element inside an element with id=container2.
With:
#container1,#container2,#container3 h5{
}
You are actually targetting id=container1, id=container2 and also the h5 element inside an element with id=container3
In both cases though, the element with the h5 tag does not target the element itself, only the heading tag inside it.
your code seems to correct but you can use another solution...
why you doesnt use calss for every div you want?
.divcontainer{
css....
}