Search code examples
cssemoji

How do I horizontally center an emoji?


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.


Solution

  • 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>