Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a hidden border side inherit border properties in CSS

Tags:

html

css

I came across an unusual issue with dynamic borders in CSS. I am trying to "restore" / show a certain side of a border which has been disabled by either setting its width to zero border-left-width:0; or using border-left:none;

The problem is that I don't want to repeat the same border properties since it should be an adaptive dynamic solution where the hidden border should inherit the element's already set border.

Example code: JSFiddle

/* ================== chic ==================  */

body, html {
    margin: 0;
    padding: 0;
    font-family:Verdana, sans-serif;
    height: 100%;
    text-align: center;font-weight: bold;
    background:#62726b;
    color:#abd4b1;
}

div {
    padding:50px;
    position: absolute;
    left:0;
    right:0;
    margin: 0 auto;
    width:50%;
    top:50%;
    transform:translateY(-50%);
}

/* ============= setting border =============  */

div {
    border:5px dashed #abd4b1;
    border-right:none;   /* hide right border */
    border-left-width:0; /* hide left border by setting width to zero */
}

/* restoring borders */

div {
    border-right: inherit;      /* attempt 1 - make border inherit previous properties */
    border-right: initial;      /* attempt 2 - resest border to initial state */
    border-left-width: inherit; /* attempt 3 - inherit the border width */
    border-left-width: initial; /* attempt 4 - reset border width to initial state */
}
<div>ALL YOUR BORDERS ARE BELONG TO US</div>

Observation 1: a border side will not inherit its "parent" border

Observation 2: using initial resets the border to browser default (I guess that's logical to happen)

So the question really is can a hidden/disabled border side be shown using pure CSS without repeating the border property twice?

like image 226
Aziz Avatar asked Oct 30 '15 23:10

Aziz


2 Answers

So the question really is can a hidden/disabled border side be shown using pure CSS without repeating the border property twice?

I suspect your real question is, as given by your comments,

interesting, a class toggle does the trick, now is there a way to simulate that by css override instead of class?

... to which the answer is, no, because that's just not how the cascade works. An element can only have one value for a property at any given time. So either an element has a border, or it doesn't, and this is determined by resolving all the border declarations that match that element and figuring out which one of the matching declarations wins.

inherit doesn't work because there is no parent border to inherit from. (Technically, there is, it's just that it's set to the initial value of medium none currentColor, and that's what's being inherited.)

initial doesn't work because, again, the initial values of border-width and border-style are medium and none respectively — and only one of them actually disables the border; the other sets it to an arbitrary non-zero width. (Also, this has nothing to do with browser defaults.)

The only way you can toggle between multiple possible values for a CSS property is by declaring each value in one of multiple possible class names that you assign to the same element:

div {
    border: 5px dashed #abd4b1;
}

div.norightborder {
    border-right-style: none; /* hide right border */
}

div.noleftborder {
    border-left-width: 0; /* hide left border by setting width to zero */
}

... which also makes use of overriding rules, except as intended. The first rule is guaranteed to match the element as long as it is a div; the latter two rules match only when the class names are present, and override the first by virtue of being more specific, but the first rule and the values specified by its shorthand declaration are untouched and restoring them is simply a matter of omitting the class names, or at least removing them after the fact.

like image 103
BoltClock Avatar answered Nov 11 '22 16:11

BoltClock


Border is not a parent. When you apply border:5px dashed #abd4b1;, it sets all border to be that style. Something like,

border-right: 5px dashed #abd4b1;
border-bottom: 5px dashed #abd4b1;
border-left: 5px dashed #abd4b1;
border-top: 5px dashed #abd4b1;

When you apply border-right:none; there is no memory of the earlier style any more.

Try to apply it in opposite order.

div {
    border-right:none;   /* hide right border */
    border-left-width:0; /* hide left border by setting width to zero */
    border:5px dashed #abd4b1;
}

So the question really is can a hidden/disabled border side be shown using pure CSS without repeating the border property twice?

No, you can't. You can reset it to its initial state but not to the style that you want to set. You have to repeat it.

border-left-width:0; /*hide*/
border-left-width:5px; /*restore*/

border-left-color: transparent; /*hide*/
border-left-color: #abd4b1; /*restore*/

You can use LESS to save the style as a variable and reuse it. But this is not pure css.

like image 45
Ppp Avatar answered Nov 11 '22 16:11

Ppp