Reputation: 6294
I have a button: <button class="outline">Outline</button>
which I want to set the outline on, but all of the other buttons should not have outline.
If give it a class b1
and do:
[dir="ltr"] .b1 {
border: 0;
}
[dir="ltr"] .b1.outline {
border-width: 1px;
}
It does not have an outline.
However, if give it a class b2
and do:
.b2 {
border: 0;
}
.b2.outline {
border-width: 1px;
}
It does have an outline!
Codepen to see for yourselves: https://codepen.io/anon/pen/gRMBdZ
Why does that happen?
Upvotes: 3
Views: 154
Reputation: 21675
This has to do with specifity and the use of border: 0;
. The specificity of the two sets of selectors applies border: 0;
in a different order than one another. border
is a shorthand property used to apply border-width
, border-style
and border-color
. Applying 0
or none
will remove the styles for all of those properties.
In your CodePen you have button.outline
which is playing a role in the visibility of the button's border.
Your first set is applied in this order:
button.outline
- border-style
and border-color
properties applied[dir="ltr"] .b1
- border properties removed with border: 0;
[dir="ltr"] .b1.ouline
- border-width
applied, no color or styleBorder is not visible even though there is a width because the rest of the border properties do not have values that would make it visible, like color and style.
Your second set is applied in this order:
.b2
- border properties removed with border: 0;
button.outline
- border-style
and border-color
properties applied.b2.ouline
- border-width
appliedBorder is visible because we have border properties that make it visible, i.e. width, color, style.
Upvotes: 4
Reputation: 90013
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 border-style
property is set to initial
, which defaults it to none
. The width applies, but the style is initial
= none
. You need to set it any render-able value so it applies a visible border:
[dir="ltr"] .b1 {
border: 0;
}
[dir="ltr"] .b1.outline {
border-width: 1px;
border-style: solid;
}
Upvotes: 3
Reputation: 3350
Because the styles with the [dir="ltr"]
selector have higher precedence.
When you set:
[dir="ltr"] .b1 {border: 0}
You make all border-specific declarations in button.outline {...}
obsolete. Therefore you have a border-width
, but neither border-style
nor border-color
which are just as well necessary.
Upvotes: 0
Reputation: 41
Take in count the rules of CSS. If you have more levels of nesting, this will be the priority. In your case, .b2
is the basic level, so when you set button.outline
this will be more important than .b2
rule, for that reason all .b2
elements will have the outline. If you want to rewritte the rules, you have to call button.b2.outline
instead 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;
}
Upvotes: 0
Reputation: 1512
When you add the [dir="ltr"], it changes the order in which 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;
}
Notice how button.outline
is the 3rd rule on Button 1 and the 2nd rule on Button 2 since the specificity changed.
Upvotes: 2