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

CssBorder

Css Problem Overview


Any way to declare a size/partial border to a box in CSS? For example a box with 350px that only shows a border-bottom in its firsts 60px. I think that might be very useful.

Examples:

enter image description here enter image description here

Css Solutions


Solution 1 - Css

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>

Solution 2 - Css

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>

Solution 3 - Css

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>

Solution 4 - Css

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>

Solution 5 - Css

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

Solution 6 - Css

Been playing a bit around with your solutions and came up with that.

I'd appreciate your comments and thoughts.

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>test file</title>
  <style>
    #box {
      background-color: gray;
      position: relative;
      left: 10px;
      top: 10px;
      height: 180px;
      width: 380px;
    }
    
    #grad1 {
      position: absolute;
      left: -10px;
      top: -10px;
      height: 40px;
      width: 2px;
      background-image: linear-gradient(red, red);
    }
    
    #grad2 {
      position: absolute;
      left: -10px;
      top: -10px;
      height: 2px;
      width: 40px;
      background-image: linear-gradient(red, red);
    }
  </style>
</head>

<body>
  <div id="box">
    <div id="grad1"></div>
    <div id="grad2"></div>
  </div>
</body>

</html>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiondavidmatasView Question on Stackoverflow
Solution 1 - CssbookcaseyView Answer on Stackoverflow
Solution 2 - CssyckartView Answer on Stackoverflow
Solution 3 - CssTemani AfifView Answer on Stackoverflow
Solution 4 - CsssitesView Answer on Stackoverflow
Solution 5 - CssDiodeus - James MacFarlaneView Answer on Stackoverflow
Solution 6 - Cssuser14998540View Answer on Stackoverflow