Dynamically aligning pseudo element according to parent height

Here is a solution using clip-path. The idea is to use % values in the polygon to only show the needed shape and it will always work whatever the height is:

.one-line {
  font-size: 2em;
  width: 150px;
  min-height: 50px;
  height: auto;
  background: blue;
  margin: 5px;
  position: relative;
  color: #fff;
}

.one-line:after {
  content: '';
  display: block;
  position: absolute;
  top: 0;
  bottom: 0;
  width: 25px;
  right: -25px;
  background: red;
  -webkit-clip-path: polygon(100% 50%, 0 0, 0 100%);
  clip-path: polygon(100% 50%, 0 0, 0 100%);
}
<div class="one-line">text<br>text<br></div>
<div class="one-line">text<br>text<br>text<br></div>

<div class="one-line">text</div>

<div class="one-line">text<br>text<br>text<br>text<br>text<br>text<br>text<br></div>

Here is another solution that rely on both pseudo elements and some skew transformation to create the arrow. You will notice that this one will keep ratio of the arrow.

.one-line {
  font-size: 2em;
  width: 150px;
  min-height: 50px;
  height: auto;
  background: blue;
  margin: 5px;
  position: relative;
  color: #fff;
}

.one-line:after {
  content: '';
  display: block;
  position: absolute;
  top: 0;
  height: 50%;
  width: 50%;
  right: -25px;
  background: red;
  transform: skewX(20deg) translateX(-33%);
  transform-origin: top;
  z-index: -1;
}

.one-line:before {
  content: '';
  display: block;
  position: absolute;
  bottom: 0;
  height: 50%;
  width: 50%;
  right: -25px;
  background: red;
  transform: skewX(-20deg) translateX(-33%);
  transform-origin: bottom;
  z-index: -1;
}
<div class="one-line">text<br>text<br></div>
<div class="one-line">text<br>text<br>text<br></div>

<div class="one-line">text</div>

<div class="one-line">text<br>text<br>text<br>text<br>text<br>text<br>text<br></div>

Another way with only one pseudo element and linear-gradient.

.one-line {
  font-size: 2em;
  width: 150px;
  min-height: 50px;
  height: auto;
  background: blue;
  margin: 5px;
  position: relative;
  color: #fff;
}

.one-line:after {
  content: '';
  display: block;
  position: absolute;
  top: 0;
  height: 100%;
  width: 50px;
  right: -50px;
  background: 
   linear-gradient(to bottom left, transparent 49.4%, red 50%) top, 
   linear-gradient(to top left,    transparent 49.4%, red 50%) bottom;
  background-size:100% 50.2%;
  background-repeat:no-repeat;
}
<div class="one-line">text<br>text<br></div>
<div class="one-line">text<br>text<br>text<br></div>

<div class="one-line">text</div>

<div class="one-line">text<br>text<br>text<br>text<br>text<br>text<br>text<br></div>

And finally without any pseudo element and only background on the main element:

.one-line {
  font-size: 2em;
  width: 200px;
  padding-left:50px;
  min-height: 50px;
  height: auto;
  background: 
   linear-gradient(blue,blue) left/calc(100% - 50px) 100%,
   linear-gradient(to bottom left, transparent 49.4%, red 50%) top right/50px 50.2%, 
   linear-gradient(to top left, transparent 49.4%, red 50%) bottom right/50px 50.2%;
  background-repeat:no-repeat;
  margin: 5px;
  position: relative;
  color: #fff;
}
<div class="one-line">text<br>text<br></div>
<div class="one-line">text<br>text<br>text<br></div>

<div class="one-line">text</div>

<div class="one-line">text<br>text<br>text<br>text<br>text<br>text<br>text<br></div>

Leave a Comment