Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to simulate \hfill with HTML and CSS?

Tags:

html

css

Consider a simple webpage like this one:

<!DOCTYPE html>
<html><head><title>Test!</title></head>
<body>
<p>a b c</p>
</body></html>

I'd like to have the a b c formatted as if I wrote a\hfill b\hfill c in TeX. This is: a on the left, then b centered, then c on right; all on the same line. How can I do this?

like image 980
fuz Avatar asked Feb 17 '13 11:02

fuz


1 Answers

How you would go about this greatly depends on how you want the spacing to be when there's actually content here. These techniques will work with any tags, I chose a list here for simplicity. If you're using p and span, then replace ul with p and li with span.

<ul>
    <li>a</li>
    <li>b</li>
    <li>c</li>
</ul>

All 3 of these techniques work without modifying the source order. Floats could do the job, but you would have to place c before b for it to work properly.


This technique uses flexbox and assumes that the elements containing a, b, and c are just large enough to contain them and the space between them is equal (if a is larger than b, then b will not be centered). Flexbox has a lot of options to determine behavior regarding wrapping, but the default is to not wrap at all.

http://jsfiddle.net/4g8NY/1/ (prefixes not included)

ul {
    display: flex;
    justify-content: space-between;
}

Flexbox does not have very widespread support at the moment, due to the fact that IE10 is the first IE version to support it. http://caniuse.com/#search=flexbox


You could use the display: table family along with text-alignment to give the illusion that the elements are distributed in the desired way, but their containers take up 33% of their parent's width. In this example, b should remain perfectly centered regardless of the actual content. Your elements are also equal height and will be forced to appear on the same line no matter what.

Unlike the other techniques, this assumes there will only ever be 3 elements. You'll need to modify the column widths and tinker with which columns should have which alignment each time you add an element.

http://jsfiddle.net/4g8NY/2/

ul {
    display: table;
    width: 100%;
}

li {
    display: table-cell;
    width: 33%;
}

li:nth-child(2) {
    text-align: center;
}

li:last-child {
    text-align: right;
}

Support for this technique is very good, since all of our properties are available in IE8 (IE8 is my official cutoff, IE7 and older are not considered "supported browsers").


The third technique involves using a pseudo element as the last line of the parent element so that we can justify a, b, and c. There is no way to prevent wrapping with this technique if the elements do not fit on the same line.

Unlike the other techniques, additional markup is not necessary. It could just be a p tag like you already have in your example code.

http://jsfiddle.net/4g8NY/3/

ul {
    text-align: justify;
}

ul:after {
    content: " ";
    display: inline-block;
    width: 100%;
}

li {
    display: inline; /* if you're using an element that's already `inline` like a span, you don't need this */
}

Similar to the above technique, it works in IE8 or better.

like image 142
cimmanon Avatar answered Oct 15 '22 08:10

cimmanon