How to Make CSS Letter-Spacing: 0.5 Px

Is there a way to make css letter-spacing: 0.5 px?

This bug has been reported back in 2008 and is confirmed. So if someone feels like hacking into webkit that would make a lot of designers happy.

https://bugs.webkit.org/show_bug.cgi?id=20606

letter-spacing less than one pixel

Letter spacing can have negative value, so try that :)

I.E. letter-spacing: -4px;

Odd effect of letter-spacing on element width

The Behavior

I agree that the spec states this fairly explicitly. To quote this page:

Letter-spacing must not be applied at the beginning or at the end of a
line.

However, this fiddle on Win 7 is showing me that on Chrome, IE9, and Firefox, all are applying one less pixel after the last letter (Firefox is showing me to start out with one less pixel to begin with in the gap to the border), which seems to be in violation of it not being applied to the end of the line. The result being that all appear to be reducing total width by 1px per character in the string.

So it does not appear that it works as is should in any browser, nor does it matter if the letter-spacing is instead a positive number.

Probably the "Best" Workaround

Add padding-right: 1px to the span with letter-spacing: -1px to offset the problem as seen in this fiddle.

Optional Workaround: :after pseudo-element

On the span with letter-spacing: -1px put the following as seen in this fiddle:

span:after {content:''; display: inline-block; width: 1px;}

Final Thought

Either solution above may or may not help with differences in text-align: center calculations, as that appears to partially depend on the 1px rounding for center based on the display width, as seen when one stretches the width of this fiddle).

CSS letter-spacing SAFARI

Webkit browsers (Safari, Chrome) round differently than Gecko (Mozilla). Thus, use 1px instead of 0.5px, as Webkit will round down to 0 while Mozilla will round up.

CSS text justify with letter spacing

Here's a script which can do it. It isn't pretty, but maybe you can hack it to meet your needs. (Updated to handle resizing)

function SplitText(node) {

var text = node.nodeValue.replace(/^\s*|\s(?=\s)|\s*$/g, "");

for (var i = 0; i < text.length; i++) {

var letter = document.createElement("span");

letter.style.display = "inline-block";

letter.style.position = "absolute";

letter.appendChild(document.createTextNode(text.charAt(i)));

node.parentNode.insertBefore(letter, node);

var positionRatio = i / (text.length - 1);

var textWidth = letter.clientWidth;

var indent = 100 * positionRatio;

var offset = -textWidth * positionRatio;

letter.style.left = indent + "%";

letter.style.marginLeft = offset + "px";

//console.log("Letter ", text[i], ", Index ", i, ", Width ", textWidth, ", Indent ", indent, ", Offset ", offset);

}

node.parentNode.removeChild(node);

}

function Justify() {

var TEXT_NODE = 3;

var elem = document.getElementById("character_justify");

elem = elem.firstChild;

while (elem) {

var nextElem = elem.nextSibling;

if (elem.nodeType == TEXT_NODE)

SplitText(elem);

elem = nextElem;

}

}
#character_justify {

position: relative;

width: 40%;

border: 1px solid red;

font-size: 32pt;

margin: 0;

padding: 0;

}

#character_justify * {

margin: 0;

padding: 0;

border: none;

}
<body onload="Justify()">

<p id="character_justify">

Something<br/> Like

<br/> This

</p>

</body>

Can I have 12.5px font size?

A fractional px font size is perfectly valid.

Modern browsers perform layout with device-independent floating-point values, and there are few-to-no differences between running on a high resolution (2x, 1.25x, etc.) display and setting the zoom level in a browser.

You should be aware that certain values are rounded to whole pixels, such as borders, and this difference might manifest in subtle ways.

As an illustration, Firefox reports 1px for the computed border width of all these, while Chrome does not. A box made purely of border width might layout differently in Firefox and Chrome — there's a tradeoff at play here.

Also as an illustration, do a Find in Page for "px" and look at the ragged border of the highlight — it smoothly moves to the right rather than jumping at a certain point.

Edit: And Safari (on Mac) is indeed the odd one out, apparently rounding the font size to a whole number for display (but the computed value is still fractional).

document.querySelectorAll('span').forEach(span => {

const {width, height} = span.getBoundingClientRect();

span.textContent += `\t${width}x${height}`;

const {borderTopWidth} = getComputedStyle(span);

span.textContent += `\t${borderTopWidth}`;

});
span {

border: 0.08em solid silver;

white-space: pre-wrap;

}
<div style="font-size:12.0px"><span>font-size:12.0px</span></div>

<div style="font-size:12.1px"><span>font-size:12.1px</span></div>

<div style="font-size:12.2px"><span>font-size:12.2px</span></div>

<div style="font-size:12.3px"><span>font-size:12.3px</span></div>

<div style="font-size:12.4px"><span>font-size:12.4px</span></div>

<div style="font-size:12.5px"><span>font-size:12.5px</span></div>

<div style="font-size:12.6px"><span>font-size:12.6px</span></div>

<div style="font-size:12.7px"><span>font-size:12.7px</span></div>

<div style="font-size:12.8px"><span>font-size:12.8px</span></div>

<div style="font-size:12.9px"><span>font-size:12.9px</span></div>

<div style="font-size:13.0px"><span>font-size:13.0px</span></div>

<div> </div>

CSS letter-spacing parts of a word

Have you considered adding margin-right:-0.5em to your span.

e.g.

"<span style="letter-spacing: 0.5em; margin-right:-0.5em">Title</span>"

Tested in FF 3.5.7, Opera 10.10, Chrome 3.0.195.38, IE6, IE7, and IE8 standard and compatibility modes, it sort of works. In your exact example, it seems OK, though it wouldn't be right if the span had a background colour since that would leak onto the second quote mark.

Also, you'd need to be careful to not add any CSS to the span that caused hasLayout in IE6,IE7 to be set, as that would break it.

Commentary:

This is a very curious behaviour. CSS 2.1 and earlier is quite vague about what should happen after the last character. It talks about the spacing between characters but that's insufficient when the span is viewed as part of a larger string of text. It seems that Microsoft initially came to a different conclusion to the other browser makers as to what it meant. MS have then, in IE8, chosen to switch over and copy the other browsers.

CSS 3, on the other hand, is quite clear. It provides this example:

For example, given the markup

<P>a<LS>b<Z>cd</Z><Y>ef</Y></LS>g</P>

and the style sheet

LS { letter-spacing: 1em; }

Z { letter-spacing: 0.3em; }

Y { letter-spacing: 0.4em; }

the spacing would be

a[0]b[1em]c[0.3em]d[1em]e[0.4em]f[0]g

Note the distances after d, f, and g. This clearly seems to be specifying the IE6, IE7 behaviour.

It should be noted that that section of CSS 3 is a draft, and that the example was written long before IE8 was created. It's likely therefore, IMO, that the CSS 3 requirements may well change in the future.



Related Topics



Leave a reply



Submit