Question

I have noticed a odd behavior in using letter-spacing and text-align: center together. Increasing the space, bring the text to be closer to the left margin of the element.

div {
  width: 400px;
  height: 200px;
  background-color: #3b0d3b;
  text-align: center;
  margin: auto;
}

p {
  color: #fff;
  margin-top: 40px;
  text-align: center;
  padding-top: 10px;
  font-size: 1.2em;
}

.spacing {
  letter-spacing:.4em; /* This property is the problem */
}

.spacing-large {
  letter-spacing:.9em; /* This property is the problem */
}
<div>
  <p>- Foo Bar Zan -</p>
  <p class="spacing">- Foo Bar Zan -</p>
  <p class="spacing-large">- Foo Bar Zan -</p>
</div>

I spot the same behavior on last Firefox and Chrome. Is there a way to fix this issue?

Was it helpful?

Solution

It seems you need to indent the text by the same amount as the letter-spacing. The first letter does not have the spacing applied to the left side

div {
  width: 400px;
  height: 400px;
  background-color: #3b0d3b;
  text-align: center;
  margin: auto;
}

p {
  color: #fff;
  background: black;
  text-align: center;
  font-size: 1.2em;
  padding: 0;
  margin: 0;
}

.spacing {
  letter-spacing: .4em;
}

.spacing-large {
  letter-spacing: 0.9em;
  text-align: center;
  text-indent: 0.9em;
}
<div>
  <p>- Foo Bar Zan -</p>
  <p class="spacing">- Foo Bar Zan -</p>
  <p class="spacing-large">- Foo Bar Zan -</p>
</div>

The logical explanation I came up with is - since it is the first letter, spacing on the left side will not apply.

OTHER TIPS

Using padding would be safer incase the text goes onto two lines. text-indent would only indent the first line of text.

p { 
  padding-left: 0.9em; 
}

If you look closely, the top one without letter spacing is not properly centered as well. The only thing I can think of is to monkey patch it with margin-left: 15px like so:

p { margin-left: 15px; }

Set a negative margin the same amount as the letter spacing. So if your letter spacing is 10px, set margin-right:-10px.

Using text-indent will leave that space in front of the first letter, even when the parent element is too small to fit the content, causing it to not look centered.

This behavior is because there is the extra space (as a result of increased letter spacing) added to the right side of the right most letter.

There is a simpler method to achieve center alignment in such cases. Just remove the letter spacing property from the last alphabet

Here is a solution.

div {
  width: 400px;
  height:400px;
  background-color: #3b0d3b;
  text-align:center;
  margin:auto;
}

p {
  color:#fff;
  margin-top: 40px;
  text-align:center;
  padding-top:30px;
  font-size: 1.2em;
}

.spacing {
  letter-spacing:.4em;
}

.spacing-large {
  letter-spacing:.9em;
}
<div>
  <p>- Foo Bar Zan -</p>
  <p class="spacing">- Foo Bar Zan <span style="letter-spacing:0">-</span></p>
  <p class="spacing-large">- Foo Bar Zan <span style="letter-spacing:0">-</span></p>
</div>

Notice the span element nesting the last character.

The best answer I have found to solve a letter spacing word being off center is to simply put &nbsp; in front of the word.

letter-spacing is inherently imbalanced, coming after each letter. You can compensate for it with a negative margin-right.

For example, in React with TypeScript and styled-components:

import React from 'react'
import styled from 'styled-components'

/**
 * Center text, accounting for letter-spacing.
 */
export const CenterText: React.FC<{
  className?: string
  letterSpacing: string
}> = ({ children, className, letterSpacing }) => {
  return <Body {...{ className, letterSpacing }}>{children}</Body>
}

/**
 * Negative right margin handles inherent imbalance in letter-spacing.
 * `justify-content: center` handles both narrow content and overflow.
 * `text-align: center` aligns multiple lines of text when text wraps.
 */
export const Body = styled.div<{ letterSpacing: string }>`
  display: flex;
  justify-content: center;
  letter-spacing: ${o => o.letterSpacing};
  margin-right: -${o => o.letterSpacing};
  text-align: center;
`
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top