calebo
calebo

Reputation: 3442

CSS pseudo element underline on centered header

I have a heading which is centered in the container, and I'm using border bottom and pseudo element to draw the underline, however I'm not sure how I to make the underline stop at where the heading text ends.

enter image description here

My mark-up:

.headerWrap {
  background: #0a1633;
  position: relative;
}

/* Trying to use this to mask the overflow */
.headerWrap:after {
  position: absolute;
  display: block;
  content: "";
  bottom: 0;
  left: 65%;
  right: 0;
  border-bottom: 10px solid #0a1633;
}

.header {
  margin: 0 auto 24px;
  text-align: center;
  font-weight: bold;
  position: relative;
  padding-bottom: 10px;
  color: #ff6347;
  border-bottom: 2px solid #ff6347;
  position: relative;
}

.header:before {
  position: absolute;
  right: 0;
  bottom: 0;
  left: 0;
  display: block;
  margin-bottom: 2px;
  content: "";
  border-bottom: 6px solid #ff6347;
}
<div class="headerWrap">
  <h3 class="header">Header</h3>
</div>

Upvotes: 4

Views: 2133

Answers (5)

Temani Afif
Temani Afif

Reputation: 274200

Here is an idea without extra element that will work with any content. The trick is to rely on display:inline-block to have the shrink-to-fit behavior and be able to consider the right part of the text. Then we can simply rely on overflow on the left side.

I will consider multiple background to create the line to only use one pseudo element:

.headerWrap {
  background: #0a1633;
  text-align: center;
  overflow:hidden;
  margin:10px;
}

.header {
  margin: 5px 0 25px;
  font-weight: bold;
  position: relative;
  display:inline-block;
  color: #ff6347;
  position: relative;
}

.header:before {
  content:"";
  position: absolute;
  right: 0;
  top:100%;
  left: -100vw;
  height:10px;
  background:
    linear-gradient(#ff6347,#ff6347) top,
    linear-gradient(#ff6347,#ff6347) bottom;
  background-size:100% 6px,100% 2px;
  background-repeat:no-repeat;
}
<div class="headerWrap">
  <h3 class="header">Header</h3>
</div>

<div class="headerWrap">
  <h3 class="header">Another Header</h3>
</div>

Upvotes: 2

Kaiido
Kaiido

Reputation: 137161

Let's use a bit of flex.

By setting your container (.headerWrap) with a display: flex, you can have its own pseudo-elements to always shrink your content (.header) in the middle like you wish.
From then, you just have to style the ::before pseudo element so that it gets both lines, and to style your content so that it also gets the same two lines, leaving the ::after unstyled.

.headerWrap {
  background: #0a1633;
  position: relative;
  display: flex;
  justify-content: center;
}

.header {
  text-align: center;
  font-weight: bold;
  position: relative;
  color: #ff6347;
  border-bottom: 6px solid #ff6347;
  position: relative;
  white-space: nowrap;
  flex: 0 1 0;
  height: 25px;
  padding: 0;
}
.headerWrap:before, .headerWrap::after {
  display: inline-block;
  content: "";
  flex: 1 0 0;
}
/* left lines */
.headerWrap:before {
  margin-top: 44px;
  border-top: 6px solid #ff6347;
  border-bottom: 2px solid #ff6347;
  height: 3px;
}
/* small horizontal line under text */
.header::before {
  content: '';
  position: absolute;
  display: inline-block;
  width: 100%;
  margin-top: 34px;
  border-bottom: 2px solid #ff6347;
}

/* just to show you can change the content dynamically */
.hidden {
  display: none;
}
.headerWrap:hover .hidden{
  display: inline;
}
<div class="headerWrap">
  <h3 class="header"><span class="hidden">This is an </span>Header</h3>
</div>

And here is a version a bit more dynamic, but using one more wrapping element, so that we can align the ::before on the content's baseLine (above version is using hard-coded height and margin-top rules).

.headerContainer {
  display: flex;
  align-items: center;
  background: #0a1633;
}
.headerWrap {
  position: relative;
  display: flex;
  align-items: flex-end;
  height: 3em;
  color: #ff6347;
  flex: 1 0 0;
  padding: 1em 0;
}

.header {
  text-align: center;
  font-weight: bold;
  position: relative;
  position: relative;
  white-space: nowrap;
  flex: 0 1 0;
  margin: 0;
  padding: 0 0 12px;
  border-bottom: 2px solid;
}
.headerWrap:before, .headerWrap::after {
  display: inline-block;
  content: "";
  flex: 1 0 0;
}
/* left lines */
.headerWrap:before {
  border-top: 6px solid;
  border-bottom: 2px solid;
  height: 3px;
}
/* small horizontal line under text */
.header::before {
  content: '';
  position: absolute;
  display: inline-block;
  width: 100%;
  bottom: 3px;
  left: 0;
  border-bottom: 6px solid #ff6347;
}

/* just to show you can change the content dynamically */
.hidden {
  display: none;
}
.headerWrap:hover .hidden{
  display: inline;
}
<div class="headerContainer">
  <div class="headerWrap">
    <h3 class="header"><span class="hidden">This is an </span>Header</h3>
  </div>
</div>

Upvotes: 1

Bathri Nathan
Bathri Nathan

Reputation: 1267

i have created a empty div with same background color with padding bottom and so we can adjust the with of as such u need right now

i have changed property of h3, instead of h3 you can even use div with custom css as u need.

check the below code.

 .headerWrap {
      background: #0a1633;
      position: relative;
    }

    .header {
      margin-top:0;
      font-weight: bold;
      position: relative;
      color: #ff6347;
      text-align: center;
    }
  
  
  .inner {
    background-color: #ff6347;
    width: 54%;
    height: 0px;
    background-color: ff6347;
    padding-bottom: 5px;
}

h3{
    margin-block-start: 0em;
    margin-block-end: 0em;
}
  
    <div class="headerWrap">
      <h3 class="header">Header</h3>
      <div class="inner">&nbsp;</div>
    </div>

Upvotes: 0

Ibra
Ibra

Reputation: 1054

If you know(calculate) the width of text "Header", you can do it like this: (and you don't need to use the mask.)

.headerWrap {
  background: #0a1633;
  position: relative;
}

.header {
  margin-top:0;
  margin-bottom:24px;
  text-align: right;
  font-weight: bold;
  position: relative;
  padding-bottom: 10px;
  color: #ff6347;
  border-bottom: 2px solid #ff6347;

  right:-webkit-calc(50% - 30px);
  right:-moz-calc(50% - 30px);
  right:calc(50% - 30px);
}

.header:before {
  position: absolute;
  right: 0;
  bottom: 0;
  left: 0;
  display: block;
  margin-bottom: 2px;
  content: "";
  border-bottom: 6px solid #ff6347;
}
<div class="headerWrap">
  <h3 class="header">Header</h3>
</div>

Upvotes: 0

Mukyuu
Mukyuu

Reputation: 6779

If you don't mind using jQuery you could do the following:

var height= $('#test').height();
var width= $('#test').width();
var position= $('#test').position().left
var set= position+width + 'px';
$('<style>div.headerWrap:after{left:'+set+'}</style>').appendTo('body');

.position().left is used to get the x coordinate, .width() to get the element width. And add them altogether to make the underline stop at where the heading text ends.

Then add $(window).on('resize', function(){} to detect window resize.

Snippet:

function count(){
  var height= $('#test').height();
  var width= $('#test').width();
  var position= $('#test').position().left
  var set= position+width + 'px';
  $('<style>div.headerWrap:after{left:'+set+'}</style>').appendTo('body');
}
count();

$(window).on('resize', function(){
      count();
});
.headerWrap {
  background: #0a1633;
  position: relative;
}

/* Trying to use this to mask the overflow */
.headerWrap:after {
  position: absolute;
  display: block;
  content: "";
  bottom: 0;
  left: 65%;
  right: 0;
  border-bottom: 10px solid #0a1633;
}

.header {
  margin: 0 auto 24px;
  text-align: center;
  font-weight: bold;
  position: relative;
  padding-bottom: 10px;
  color: #ff6347;
  border-bottom: 2px solid #ff6347;
  position: relative;
}

.header:before {
  position: absolute;
  right: 0;
  bottom: 0;
  left: 0;
  display: block;
  margin-bottom: 2px;
  content: "";
  border-bottom: 6px solid #ff6347;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="headerWrap">
  <h3 class="header"><label id="test">Header</label></h3>
</div>

Upvotes: 0

Related Questions