Why is CSS ignoring the selector under the attribute
I have a button: <button class="outline">Outline</button>
on which I want to set the outline, but all other buttons should not have outlines.
If you assign a class to it b1
and do:
[dir="ltr"] .b1 {
border: 0;
}
[dir="ltr"] .b1.outline {
border-width: 1px;
}
It has no outline.
However, if you give it a class b2
and do:
.b2 {
border: 0;
}
.b2.outline {
border-width: 1px;
}
He has a circuit!
Codepen to verify this: https://codepen.io/anon/pen/gRMBdZ
Why is this happening?
source to share
It has to do with specification and usage border: 0;
. The specificity of the two sets of selectors applies border: 0;
in a different order than one other. border
is a shorthand property used for the application border-width
, border-style
and border-color
. Applying 0
or none
will remove styles for all of these properties.
In your CodePen, you have button.outline
one that plays a role in the visibility of the button border.
Your first set is applied in the following order:
-
button.outline
-border-style
andborder-color
applied properties -
[dir="ltr"] .b1
- border properties removed withborder: 0;
-
[dir="ltr"] .b1.ouline
-border-width
, no color or style
The border is not visible even if the width exists, because the rest of the border properties have no values ββto represent it, such as color and style.
Your second set is applied in the following order:
-
.b2
- border properties removed withborder: 0;
-
button.outline
-border-style
andborder-color
applied properties -
.b2.ouline
-border-width
applied
The border is visible because we have border properties that make it visible, i.e. width, color, style.
source to share
It's because
border:0;
... translates to:
border-top-color: initial;
border-top-style: initial;
border-top-width: 0px;
border-right-color: initial;
border-right-style: initial;
border-right-width: 0px;
border-bottom-color: initial;
border-bottom-style: initial;
border-bottom-width: 0px;
border-left-color: initial;
border-left-style: initial;
border-left-width: 0px;
border-image-source: initial;
border-image-slice: initial;
border-image-width: initial;
border-image-outset: initial;
border-image-repeat: initial;
This means the property is border-style
set to a value initial
, by default it is none
. Width is used, but style initial
= none
. You need to set any render value for it to apply the visible border:
[dir="ltr"] .b1 {
border: 0;
}
[dir="ltr"] .b1.outline {
border-width: 1px;
border-style: solid;
}
source to share
When you add [dir = "ltr"], it changes the order in which the rules are processed.
For button 1 (no outline):
[dir="ltr"] .b1.outline {
border-width: 1px;
}
[dir="ltr"] .b1 {
border: 0;
}
button.outline {
border-style: solid;
border-color: #387ef5;
color: #387ef5;
background-color: transparent;
}
button {
font-size: 1.7rem;
}
And for button 2 (outline):
.b2.outline {
border-width: 1px;
}
button.outline {
border-style: solid;
border-color: #387ef5;
color: #387ef5;
background-color: transparent;
}
.b2 {
border: 0;
}
button {
font-size: 1.7rem;
}
Note that there button.outline
is a third rule on button 1 and a second rule on button 2, as the specifics have changed.
source to share
Consider CSS rules. If you have more levels of nesting, this will be a priority. In your case, this .b2
is the baseline, so when installing button.outline
it will be more important than the rule .b2
, so all elements .b2
will have an outline. If you want to rewrite the rules, you should button.b2.outline
instead call only.b2
/* BASE CLASSES */
button {
font-size: 1.7rem;
}
.outline { /* Only use one level */
border-style: solid;
border-color: #387ef5;
color: #387ef5;
background-color: transparent;
}
/* B1 + DIRECTION */
[dir="ltr"] .b1 {
border: 0;
}
[dir="ltr"] .b1.outline {
border-width: 1px;
}
/* B2 NO DIRECTION */
button.b2 { /* Be more specific to replace previous rule */
border: 0;
}
button.b2.outline {
border-width: 1px;
}
source to share
Because styles with a selector [dir="ltr"]
take precedence.
When you install:
[dir="ltr"] .b1 {border: 0}
You make all boundary-specific declarations button.outline {...}
obsolete. Therefore, you have border-width
, but neither border-style
, nor border-color
, which are just as necessary.
source to share