How do I horizontally center an emoji?

Viewed 4291

It appears that a unicode emoji character overflows it's bounding box on a non-retina display, but it remains within the character bounds on a retina display. So how do I horizontally center an emoji in a div on both a retina and a non-retina display?

Non-Retina:

enter image description here

Retina:

enter image description here

This works on a retina screen, but is off a few px on a non-retina display:

<div style="text-align: center; width: 3rem; border: 1px solid red;"></div>

Here is a CodePen to try things https://codepen.io/anon/pen/GmzoNP. You will need a retina and non-retina screen to observe the problem.

Here are some of my ideas that I tried. I have not had success with them yet but I think the last two are on the right track:

  • Text-align center (it is text after all)
  • width: 0, 50% left margin, transform: translateX(-50%)...
  • Changing character width
  • Using a monospace font

A little context about how others have solved this problem - Slack and Google both just use images of emojis. This is not ideal in my case because it increases bundle size and and requires some extra logic to handle copy/paste.

3 Answers

I know it's a while since this question was asked but I've had the same problem and maybe my answer can help someone.

I could center the emoji by raising the font size to minimum size of 26px. With a minimum font size of 26px the emojis are centred on retina and not retina screens. In my final solution I raised the font size to 4em and then scaled it back down with transform: scale(0.25);.

Here are the experiments I made, which leaded me to my solution: https://codepen.io/faessler/pen/aRNOEY

If someone has a better/less dirty way, I would be happy to hear about it. :)

.fontSize span {
  display: inline-block;
  font-size: 26px;
}


/*BOX*/
.gridGroup {display:flex; margin-bottom:10px;}
.grid {position:relative; width:100px; height:50px; margin:0 10px 10px 0; border:1px solid blue; text-align:center;}
.grid:before {content:""; position:absolute; top:0; left:50%; transform:translateX(-50%); width:2px; height:100%; background:red;}
<div class="gridGroup">
  <div class="grid fontSize"><span></span></div>
  <div class="grid fontSize">bla <span></span> bla</div>
</div>

In my case, a width a little bit greater than the font-size solved the problem. The parent div was centring with flex.

div.emojiIcons {
  display: flex;
  flex-direction: row;
  justify-content: center;
}

span.emoji {
  font-size: 24px;
  width: 26px;
}

Here's a more semantic approach to it.

.emoji {
  display: flex;
  padding: 1rem;
  border: 1px solid black;
  position: relative;
}

.emoji::after {
  content: "";
  width: 1px;
  height: 100%;
  background-color: red;
  position: absolute;
  top: 0;
  left: 50%;
  transform: translate(-50%)
}

.align-center {
  /* vertically center. */
  align-items: center;
}

.justify-center {
  /* horizontally center. */
  justify-content: center;
}
<div class="emoji align-center justify-center">
  
</div>

Related