Gerico
Gerico

Reputation: 5169

CSS — Negate additional space added to last letter by letter-spacing property

I'm just wondering if there is a nice clean way in which to negate the letter-spacing property slight problem when you need to center text. Note to best see the problem, make the jsfiddle preview window small enough so the text wraps on to two lines.

HTML

<div class="centered--element">
    <div class="center--line"></div>
    <h1>This is a example here</h1>
</div>

CSS

.centered--element{
    background: #f2f2f2;
    text-align: center;
    text-transform: uppercase;
}

/* problem property.. */
h1{ letter-spacing: 20px }

I've made this to demonstrate the problem: http://jsfiddle.net/tq3Gh/1/

Perhaps it's just me, but it's not looking 100% central. Please see: enter image description here

However, removing the letter-spacing and it sits as one would expect. So to me there is an issue..

Here is the same example, but without letter spacing set: enter image description here

Update

I've a better idea of the problem therefore I'm updating the question to make more sense and sum the problem up a whole lot better.

Ok so after much playing the problem is letter-spacing adds spacing to the right of each letter, INCLUDING the last letter, hence why I'm getting this issue. So, in order to negate this I'm going to try simply using margin-right: -(width of my letter spacing). I'm not sure if this will cause problems, but it beats another option where I could wrap spans around the elements I want to have letter-spacing — but that's far too ugly for me.

So my update CSS would look like:

h1{ letter-spacing: 20px; margin-right: -20px; }

Upvotes: 9

Views: 7429

Answers (4)

Pato
Pato

Reputation: 679

I've made a javascript function to correct this behaviour. It takes the last letter of the matched elements text and creates a span with no letter spacing, and then compensates the width adding an extra margin (equal to the original letter spacing). You may need to limit it's input to leaf nodes, but it works really well, specially if you need to underline the text.

var fixLetterSpacing = function(selector) {
    $(selector).each(function() {
        var that = $(this);
        var text = that.text();
        var last = text.substr(-1);

        that.text(text.substr(0, text.length-1))
            .append($('<span>').text(last).css({ letterSpacing: 0 }))
            .css({ marginRight: that.css('letter-spacing') });
    });
};

Upvotes: 0

4dgaurav
4dgaurav

Reputation: 11506

ok, so actually its not a problem. Your center--element is 100% wide so actually the texts goes behind the the 2 columns in the side.

to show that I tired reducing opacity of side elements here

and when you actually give margin to the center--element it solves your problem here

.centered--element{
    background: rgba(0, 0, 0, 0.1);
    text-align: center;
    text-transform: uppercase;
    margin-left:90px;
    margin-right:90px;
}

Final 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

.spacing2 {
  letter-spacing:0.9em;
  text-align: center;
  text-indent: 0.9em;
}

Final DEMO

Upvotes: 4

Assaf Lavie
Assaf Lavie

Reputation: 75983

The issue does indeed stem from using letter-spacing. According to the standard, when you increase the letter spacing the layout engine considers that extra space after the letter to be part of the letter's width. So that extra space you see on the right is, in a way, what you asked for.

What it seems you want is for the letter spacing to put the actual letter in the middle, and surround each letter on both sides with letter-spacing/2. But I'm not sure that's a feature of CSS. In fact, the letter spacing algorithms are user agent-dependent, so this may even work in different ways on different browsers.

So you're left with ways to hack around this problem, like adding a -1em right margin/padding, but probably without a "true" solution.

Upvotes: 2

Syed Shoaib Abidi
Syed Shoaib Abidi

Reputation: 2366

I have edited your css and added margin to left and right: CSS:

  .centered--element{
        background: #f2f2f2;
        text-align: center;
        text-transform: uppercase;
        margin-left:90px;
        margin-right:90px;
    }

Also I have mentioned in the DEMO , how to dynamically set letter spacing :

JS:

document.getElementById("myHeading").style.letterSpacing="15px";

Hope this helps.

Upvotes: 0

Related Questions