Reputation: 11543
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?
Upvotes: 45
Views: 37556
Reputation: 31
It probably depends on your use-case but using flexbox
and a CSS ::before
selector might be a viable solution if you still want to allow padding on the parent container without affecting the content.
.tracking-center {
letter-spacing: 0.25em;
display: flex;
justify-content:center;
text-align:center;
}
.tracking-center.inline-flex {
display: inline-flex;
}
.tracking-center::before {
width: 0.25em;
content: '';
flex: none;
}
<h3>Example</h3>
<div style="width:80px">
<p class="tracking-center">
Hello
</p>
<p class="tracking-center">
The quick brown fox jumps over the lazy dog
</p>
</div>
<h3>Example: Inline container with its own padding</h3>
<div style="width:200px">
<p class="tracking-center inline-flex" style="padding:0 2em;">
Hello
</p>
<p class="tracking-center inline-flex" style="padding:0 2em;">
The quick brown fox jumps over the lazy dog
</p>
</div>
<h3>Example: Container too narrow</h3>
<div style="width:20px; margin-left: 50px;">
<p class="tracking-center">
Hello
</p>
<p class="tracking-center">
The quick brown fox jumps over the lazy dog
</p>
</div>
<style>
<!-- example styles -->
div {
border:2px cyan dotted;
}
p {
border:2px pink dotted;
display: inline-block;
}
.tracking-center::before {
background:turquoise;
}
</style>
If you want to add a wrapper-container inside your element every time, you can simply specify a margin/padding on the inner-container like others have suggested
.tracking-center > * {
letter-spacing: 0.25em;
margin-left: 0.25em; //or negative margin-right;
text-align: center;
display: block;
}
<h3>Example</h3>
<div style="width:80px">
<p class="tracking-center">
<span>
Hello
</span>
</p>
<p class="tracking-center">
<span>
The quick brown fox jumps over the lazy dog
</span>
</p>
</div>
<h3>Example: Inline container with its own padding</h3>
<div style="width:200px">
<p class="tracking-center inline-flex" style="padding:0 2em;">
<span>
Hello
</span>
</p>
<p class="tracking-center inline-flex" style="padding:0 2em;">
<span>
The quick brown fox jumps over the lazy dog
</span>
</p>
</div>
<h3>Example: Container too narrow</h3>
<div style="width:20px; margin-left: 50px;">
<p class="tracking-center">
<span>
Hello
</span>
</p>
<p class="tracking-center">
<span>
The quick brown fox jumps over the lazy dog
</span>
</p>
</div>
<style>
<!-- example styles -->
div {
border:2px cyan dotted;
}
p {
border:2px pink dotted;
display: inline-block;
}
p > span {
background:white;
}
p {
background:turquoise;
}
</style>
Upvotes: 0
Reputation: 8054
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;
`
Upvotes: 1
Reputation: 1
The best answer I have found to solve a letter spacing word being off center is to simply put
in front of the word.
Upvotes: 0
Reputation: 71
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.
Upvotes: 0
Reputation: 41
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.
Upvotes: 2
Reputation: 16438
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.
Upvotes: 110
Reputation: 91
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;
}
Upvotes: 9
Reputation: 11330
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; }
Upvotes: 1