a/20541563/1636522
HTML
<p>Click the boxes to justify the content (<a href="#">debug</a>).</p>
<div class="title"><span class="justifiable">hello world!</span></div>
<div class="subtitle"><span class="justifiable">How are you?</span></div>
CSS
div {
width: 490px;
line-height: 50px;
background: gray;
text-align: center;
}
.title
{
font-family: 'Muli', Arial, Helvetica, sans-serif;
font-size: .8em;
}
.subtitle
{
font-family: 'Muli', Arial, Helvetica, sans-serif;
font-size: .3em;
}
div > span {
color: black;
}
/* following rules are for demonstration purpose only */
body {
font: normal 1em Arial;
}
div {
float: left;
margin: 0 10px 10px 0;
/* following rules make the DIV unselectable */
/* http://stackoverflow.com/a/4407335/1636522 */
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
a {
color: #999;
}
a.debug {
color: red;
}
div.debug {
border: 10px solid lightblue;
}
span.debug {
background: yellow;
color: black;
}
JavaScript
// A "bit" is a portion of the free space.
// It's half the space between two characters :
//
// - "abc" : 4 bits ("a..b..c").
// - "ab cd" : 8 bits ("a..b.. ..c..d").
//
// The "gap" is the number of pixels remaining
// after splitting the free space into bits.
// Those pixels are assigned to each "bit"
// until no pixels remain. Let's say gap = 1 :
//
// bitWidth + (gap && (--gap, 1)) // gap = gap - 1 THEN bitWidth + 1
// // next bit
// bitWidth + (gap && (--gap, 1)) // bitWidth + 0
//
// Depending on your configuration, there is one
// pixel which remains free in the second demo.
// I haven't investigated about that yet.
jQuery.fn.justify = function () {
return this.each(function () {
var el = $(this),
ct = el.parent(),
chars = el.text().split(''),
bits = (chars.length - 1) * 2,
freeSpace = ct.width() - el.width(),
bitWidth = Math.floor(freeSpace / bits),
gap = freeSpace % bits;
el.html(jQuery.map(chars, function (char, i) {
var paddings = ['0', null, '0', null];
if (!i) {
paddings[1] = (bitWidth + (gap && (--gap, 1))) + 'px';
paddings[3] = '0';
} else if (i + 1 === chars.length) {
paddings[1] = '0';
paddings[3] = (bitWidth + (gap && (--gap, 1))) + 'px';
} else {
paddings[1] = (bitWidth + (gap && (--gap, 1))) + 'px';
paddings[3] = (bitWidth + (gap && (--gap, 1))) + 'px';
}
return '<span style="padding:' + paddings.join(' ') + '">' + char + '</span>';
}).join(''));
});
};
$('div').click(function () {
$(this).find('.justifiable').justify();
});
$('a').click(function (e) {
e.preventDefault();
$('div,.justifiable').add(this).toggleClass('debug');
});