Voletcat
Voletcat

Reputation: 49

vertical align in pseudo-element with absolute position

I have a "button" element that must be horizontally centered, I did it with margin: 0 auto;
But right next to that button I have empty by default :after pseudo-element which will contain text depending on server response.

Right now it works like this:

.button {
  cursor: pointer;
  position: relative;
  background: gray;
  width: 200px;
  height: 36px;
  line-height: 36px;
  margin: 0 auto;
  text-align: center;
}
.button:after {
  cursor: default;
  text-align: left;
  content:'response text here';
  position: absolute;
  top: 0;
  right: -180px;
  height: 36px;
  width: 170px;
}
<div>
  <div class="button">click me!</div>
</div>

And works fine, but if that response text contains 2 lines (which may happen) the second line will not fit vertically because of line-height parameter.
So the question is: how do I vertically center response text in this situation?

If I make :after element display:table-cell it will not work because of position:absolute, flexbox to .button will also affect button text. Another solution that comes to my mind is made 2 <dv> in a row, but if so I don't know how to position them like that.

Upvotes: 0

Views: 1242

Answers (4)

Stickers
Stickers

Reputation: 78706

You can reset the line-height to normal or so on the absolute positioned pseudo element, and use top: 50% + transform: translateY(-50%) to center it vertically.

I also suggest to use left: 100% rather than right: -180px, so that it works with dynamic button width.

.button {
  position: relative;
  background: gray;
  width: 200px;
  height: 36px;
  margin: 10px auto;
  text-align: center;
  line-height: 36px;
  cursor: pointer;
}

.button:after {
  content: attr(data-text);
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  left: 100%;
  margin-left: 10px;
  width: 170px;
  text-align: left;
  line-height: normal;
  cursor: default;
  background: pink;
}
<div>
  <div class="button" data-text="response text here">click me!</div>
  <div class="button" data-text="response text response text here">click me!</div>
</div>

Upvotes: 3

Carnaru Valentin
Carnaru Valentin

Reputation: 1875

You can add a container div like this:

<div class="center">
  <div class="button">click me!</div>
</div>

and in CSS:

.center {
  margin: 50% auto;
  width: 370px;
}

Upvotes: -2

Paulie_D
Paulie_D

Reputation: 115278

Adjust the position of the pseudo-element with a transform to center it vertically.

Use flexbox to align the button text rather than line-height which would be inherited.

.button {
  cursor: pointer;
  position: relative;
  background: gray;
  width: 200px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 1em
}

.button:after {
  cursor: default;
  content: 'response text goes here and here here';
  position: absolute;
  top: 50%;
  left: 100%;
  transform: translate(0%, -50%);
  width: 100px;
  text-align: center;
  border: 1px solid red;
}
<div>
  <div class="button">click me!</div>
</div>

Upvotes: 0

Temani Afif
Temani Afif

Reputation: 273481

You can try flex and no need to specify line-height:

.button {
  cursor: pointer;
  position: relative;
  background: gray;
  width: 200px;
  height: 36px;
  margin:10px auto;
  text-align: center;
  display:flex;
  align-items:center;
  justify-content:center;
}
.button:after {
  cursor: default;
  text-align: left;
  content:attr(data-text);
  position: absolute;
  top: 0;
  right: -180px;
  bottom:0;
  width: 170px; 
  display:flex;
  align-items:center;
}
<div>
  <div class="button" data-text="response text here">click me!</div>
</div>

<div>
  <div class="button" data-text="response text here response text">click me!</div>
</div>

Upvotes: 2

Related Questions