Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Any way to declare a size/partial border to a box?

Tags:

css

border

People also ask

How do you do a partial border in CSS?

CSS does not support partial borders. You'd need to use an adjacent element to simulate this.


Not really. But it's very easy to achieve the effect in a way that degrades gracefully and requires no superfluous markup:

div {
  width: 350px;
  height: 100px;
  background: lightgray;
  position: relative;
  margin: 20px;
}

div:after {
  content: '';
  width: 60px;
  height: 4px;
  background: gray;
  position: absolute;
  bottom: -4px;
}
<div></div>

I know, this is already solved and pixels were requested. However, I just wanted to share something...

Partly underlined text elements can easily achieved by using display:table or display:inline-block

(I just don't use display:inline-block because, yeah you know, the awkward 4px-gap).

Textual Elements

h1 {
  border-bottom: 1px solid #f00;
  display: table;
}
<h1>Foo is not equal to bar</h1>

Centering, display:table makes it impossible to center the element with text-align:center.
Let's work around with margin:auto...

h1 {
  border-bottom: 1px solid #f00;
  display: table;
  margin-left: auto;
  margin-right: auto;
}
<h1>Foo is not equal to bar</h1>

Well, that's nice, but it's not partially.
As bookcasey already introduced, pseudo-elements are worth gold.

h1 {
  display: table;
  margin-left: auto;
  margin-right: auto;
}

h1:after {
  border-bottom: 1px solid #f00;
  content: '';
  display: block;
  width: 50%;
}
<h1>Foo is not equal to bar</h1>

Offset, the underline is left aligned right now. To center it, just push the pseudo-element the half of its width (50% / 2 = 25%) to the right.

h1 {
  display: table;
  margin-left: auto;
  margin-right: auto;
}

h1:after {
  border-bottom: 1px solid #f00;
  content: '';
  display: block;
  margin-left: 25%;
  width: 50%;
}
<h1>Foo is not equal to bar</h1>

...as davidmatas commented, using margin:auto is sometimes more practical, than calculating the margin-offset by hand.

So, we can align the underline to the left, right or center (without knowing the current width) by using one of these combinations:

  • Left: margin-right: auto (or just leave it off)
  • Middle: margin: auto
  • Right: margin-left: auto

Full example

.underline {
  display: table;
  margin-left: auto;
  margin-right: auto;
}

.underline:after {
  border-bottom: 1px solid #f00;
  content: '';
  display: block;
  width: 50%;
}

.underline--left:after {
  margin-right: auto; /* ...or just leave it off */
}

.underline--center:after {
  margin-left: auto;
  margin-right: auto;
}

.underline--right:after {
  margin-left: auto
}
<h1 class="underline underline--left">Foo is not equal to bar</h1>
<h1 class="underline underline--center">Foo is not equal to bar</h1>
<h1 class="underline underline--right">Foo is not equal to bar</h1>

Block-Level Elements

This can easily be adopted, so that we can use block-level elements. The trick is to set the pseudo-elements height to the same height as its real element (simply height:100%):

div {
  background-color: #eee;
  display: table;
  height: 100px;
  width: 350px;
}
div:after {
  border-bottom: 3px solid #666;
  content: '';
  display: block;
  height: 100%;
  width: 60px;
}
<div></div>

Here is another solution that rely on linear-gradient where you can easily create any kind of line you want. You can also have multiple lines (on each side for example) by using multiple background:

.box1 {
  width: 200px;
  padding: 20px;
  margin: 10px auto;
  text-align: center;
  background: 
    linear-gradient(to right, transparent 20%, #000 20%, #000 40%, transparent 40%) 0 100% / 100% 3px no-repeat, 
    #ccc
}

.box2 {
  width: 200px;
  padding: 20px;
  margin: 10px auto;
  text-align: center;
  background: 
    linear-gradient(to right, transparent 20%, red 20%, red 80%, transparent 80%) 0 100% / 100% 2px no-repeat, 
    #ccc
}

.box3{
  width: 200px;
  padding: 20px;
  margin: 10px auto;
  text-align: center;
  background: 
    linear-gradient(to right, transparent 20%, red 20%, red 80%, transparent 80%) 0 100% / 100% 2px no-repeat,
    linear-gradient(to right, transparent 30%, blue 30%, blue 70%, transparent 70%) 0 0 / 100% 2px no-repeat,
    linear-gradient(to bottom, transparent 30%, brown 30%, brown 70%, transparent 70%) 0 0 / 3px 100% no-repeat,
    linear-gradient(to bottom, transparent 20%, orange 20%, orange 70%, transparent 70%) 100% 0 / 3px 100% no-repeat,
  #ccc
}
<div class="box1">
  Box1
</div>
<div class="box2">
  Box2
</div>
<div class="box3">
  Box3
</div>

Here is another syntax to achieve the same as above:

.box1 {
  width: 200px;
  padding: 20px;
  margin: 10px auto;
  text-align: center;
  background: 
   linear-gradient(#000, #000) top /40% 3px no-repeat, 
   #ccc
}

.box2 {
  width: 200px;
  padding: 20px;
  margin: 10px auto;
  text-align: center;
  background: 
    linear-gradient(red,red) bottom/ 60% 2px no-repeat, 
    #ccc;
}

.box3{
  width: 200px;
  padding: 20px;
  margin: 10px auto;
  text-align: center;
  background: 
   linear-gradient(red , red)bottom left/ 60% 2px,
   linear-gradient(blue, blue) 60% 0 / 40% 2px,
   linear-gradient(brown, brown) left/ 3px 30%,
   linear-gradient(orange, orange) right / 3px 40%,
   #ccc;
  background-repeat:no-repeat;
}
<div class="box1">
  Box1
</div>
<div class="box2">
  Box2
</div>
<div class="box3">
  Box3
</div>

I used a grid to build draw some of the borders.

See here.

Code:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Responsive partial borders</title>
    <style>
        /* ungrid without mobile */
        .row{width:100%;display:table;table-layout:fixed;}
        .col{display:table-cell;}

        /* things to change */
        .row{width: 70%; margin: auto;}
        .mid.row > .col{ height: 150px; }

        /* draw box and align text */
        .col{ text-align: center;}
        .top.left.col{
            border-top: 1px solid black;
            border-left: 1px solid black;
        }
        .top.right.col{
            border-top: 1px solid black;
            border-right: 1px solid black;
        }
        .bottom.left.col{
            border-bottom: 1px solid black;
            border-left: 1px solid black;
        }
        .bottom.right.col{
            border-bottom: 1px solid black;
            border-right: 1px solid black;
        }
        .mid.row > .col{
            border-left: 1px solid black;
            border-right: 1px solid black;
            vertical-align: middle;
        }
        .top.center.col{
            position: relative;
            top: -0.5em;
        }
        .bottom.center.col{
            position: relative;
            bottom: -0.5em;
        }
    </style>
</head>
<body>

    <div class="row">
        <div class="top left col"></div>
        <div class="top center col">Top</div>
        <div class="top right col"></div>
    </div>
    <div class="mid row">
        <div class="col">Mid</div>
    </div>
    <div class="row">
        <div class="bottom left col"></div>
        <div class="bottom center col">Bottom</div>
        <div class="bottom right col"></div>
    </div>  

</body>
</html>