Outline on which I want to set the ...">

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?

+3


source to share


5 answers


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

    and border-color

    applied properties
  • [dir="ltr"] .b1

    - border properties removed with border: 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 with border: 0;

  • button.outline

    - border-style

    and border-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.

+4


source


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;
}

      

+3


source


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.

+2


source


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;
    }

      

0


source


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.

0


source







All Articles