DR01D
DR01D

Reputation: 1365

CSS - Vertical centering object and text creates unexpected result

Vertical centering in CSS is relatively straight forward. This is the code I'm using.

position:relative;
top:50%;
transform:translateY(-50%);

1) This works great for centering multiple shapes next to each other.

2) It works great for centering multiple words next to each other.

However oddly enough when I place a centered shape next to a centered word it goes haywire. Is there an obvious, or not so obvious reason for this? How do I fix it?

I created a fiddle so you can see the result. https://jsfiddle.net/9h1pfpns/

Here is my code:

.container {
  height: 200px;
  margin: 10px;
  border: 4px solid #754419;
}
.shape {
  display: inline-block;
  position: relative;
  top: 50%;
  transform: translateY(-50%);
  width: 250px;
  height: 100px;
  margin-left: 10px;
  background-color: aquamarine;
}
.text {
  display: inline-block;
  position: relative;
  top: 50%;
  transform: translateY(-50%);
  font: bold 1.25em Arial, Helvetica, sans-serif;
  margin-left: 10px;
  border: 1px solid #754419;
}
<div class="container">
  <div class="shape"></div>
  <div class="text">first</div>
</div>

Upvotes: 0

Views: 34

Answers (2)

Oriol
Oriol

Reputation: 288480

It doesn't work because, before offsetting with relative positioning and transforms, the elements are not aligned to the top. The default is vertical-align: baseline.

Just add vertical-align: top.

.container {
  height: 200px;
  margin: 10px;
  border: 4px solid #754419;
}
.item, .text {
  display: inline-block;
  position: relative;
  top: 50%;
  transform: translateY(-50%);
  margin-left: 10px;
  vertical-align: top;
}
.item {
  width: 250px;
  height: 100px;
  background-color: aquamarine;
}
.text {
  font: bold 1.25em Arial, Helvetica, sans-serif;
  border: 1px solid #754419;
}
<div class="container">
  <div class="item"></div>
  <div class="text">first</div>
</div>

Anyways, I recommend against this approach because in case the container is shorter than the contents, they will overflow above and below. But you won't be able to scroll to see the above overflow.

Instead, I recommend flexbox with auto margins.

.container {
  height: 200px;
  margin: 10px;
  border: 4px solid #754419;
  display: flex;
}
.item, .text {
  margin: auto 0 auto 10px;
}
.item {
  width: 250px;
  height: 100px;
  background-color: aquamarine;
}
.text {
  font: bold 1.25em Arial, Helvetica, sans-serif;
  border: 1px solid #754419;
}
<div class="container">
  <div class="item"></div>
  <div class="text">first</div>
</div>

Upvotes: 2

Tony Hensler
Tony Hensler

Reputation: 1492

You can change the CSS for text to:-

.text {
  display: inline-block;
  position: relative;
  margin: 0 auto;
  font: bold 1.25em Arial, Helvetica, sans-serif;
  margin-left: 10px;
  border: 1px solid #754419;
}

Just to clarify I removed the following CSS:-

top: 50%;
transform: translateY(-50%);

And added:-

margin: 0 auto;

Check out the jsFiddle https://jsfiddle.net/01kkavf4/

* Update *

You can also replace:-

top: 50%;
transform: translateY(-50%);

With:-

top: 10%;
transform: translateY(-50%);

jsFiddle of both:-

https://jsfiddle.net/01kkavf4/

The second resolutions fits better with your box.

Just a few different ways.

Upvotes: 3

Related Questions