I recently came across a horizontal navigational menu with right-aligned links. As you might expect, it was a list element with float:right and the list items with float:left. Even though there is nothing wrong with this approach, it inspired me to take this opportunity to discuss directionality for layout.
Floats have no concept of directionality; they do not work like inline elements or table columns (for which the dir attribute is a magic bullet). With floats, authors must implement a mechanism to "swap" values whenever the interface changes (ltr vs. rtl).
So instead of using float, authors may favor inline-block. Here is a simple example:
ul {
text-align: end;
text-align: right\9;
*text-align: right;
}
li {
display: inline;
}
a {
display: inline-block;
padding: 5px 15px;
margin: 0 5px;
}
Note that using "\ 0" (with no space) instead of "\9" would take care of Opera, but may not be as future proof as "\9" (IE only).
As this demo page shows, in Chrome, Safari and Firefox, the inline-block technique makes the layout writing-mode dependent (the direction of the flow matches the value of the dir attribute, or the initial value if no direction is specified). For other UAs, and because of IE’s lack of support for the attribute selector (i.e. html[dir="rtl"]), authors need to add a hook in the markup to cater to the change of direction. For example, for full A-grade compatibility:
.rtl ul { float: left; }
.rtl ul li { float: right; }
.rtl ul {
text-align: left\9; /* IE8/9 */
*text-align: left; /* IE5/6/7 */
}
text-align: start | endUnlike left and right, start and end are writing-mode dependent keywords. In English, start maps to left and end maps to right. Relying on start and end rather than left and right allows some browsers to do the swapping (ltr/rtl) automatically.
start/end" (IE, Opera)start/end" (Chrome, Safari, Firefox)That’s it! Next time you have to style elements horizontally, remember to give display:inline-block or display:table a try.
April 26, 2011 at 5:10 am
Thierry,
This statement is partly incorrect:
Please see this test series for floats and bidirection and this test showing floated menus in ‘rtl’ direction. Currently Opera and WebKit handles overflow wrong in ‘rtl’ directional layouts.
I will say that your approach (hacking the CSS) is like coding to make IE7- happy. This doesn’t help the 100s of millions of people who read and write scripts (ie. Hebrew or Arabic) that has ‘rtl’ direction. In IE7-, web developers have had to hack greatly to make IE7- behave in ‘rtl’ direction. One common thing to see in the CSS for such pages with ‘rtl’ direction is the use of
text-align: rightandtext-align: rightto achieve the correct placement of text. I will state that IE is not the only browser that has handled ‘rtl’ direction poorly.Now this maybe a surprise to you but IE8 supports rtl direction correctly. The only browser that did it right before IE8 was is Gecko. I suggest that you float both the ul and li right and not hack IE8 or IE9 since this very article adds to this whole misinformation about bidirection.
I had some influence on the spec on writing mode and direction. This was concerning logical properties, float and overflow for rtl and overflow and bidi.
April 26, 2011 at 11:31 am
@Alan
You’re confusing me. You mention in your pages “float:right or float:start for rtl”, but as far as I know there is no such thing as “start” in the spec [1] which only lists
left,right,noneandinherit.It seems that’s what you’re using in your test cases. i.e. “Visible Overflow and Containing Block for rtl” even though I think
text-align:rightin there is redundant and thattext-align:startwould have been more appropriate anyway.Also, please note that in this article I “demonstrate” the use of
text-align: start|end.right|leftvalues are only used as a fall back.Actually, you may have missed the whole point of this article which is to avoid having to style things differently depending on context. Your demo page that shows dropdown menus in RTL and LTR contexts swaps float values and left/right properties, which is nothing new :-(
Thanks for your feedback!
[1] http://www.w3.org/TR/CSS21/visuren.html#float-position
April 26, 2011 at 1:25 pm
Oh the fun. Testing.
floats and bidirection
October 10, 2011 at 7:22 am
Great! Many thanks Thierry!
I was dealing with a similar problem and your advice in the last sentence solved my issue.
I had this code:
<- direction: rtl;
<- position: absolute; direction: ltr;
1 <- float: left;
2 <- float: left;
3 <- float: left;
CONTENT
All browsers except IE9 displayed the buttons in a row. But IE9 displayed them bellow each other (as if “float: left” didn’t exist)
Finally I got it working after I added to the “Handle” div the attribute “display: table”.
Thanks a lot,
Radek.