Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ordering span elements independent of text directionality

Say we have a number of span text elements (2 or more) with 'dir' specified as RTL:

<div dir="rtl">
<span>First-Element</span>
<span>Second-Element</span>
<span>Third-Element</span>
</div>

and we would like them to appear in order from right to left:

Third-Element Second-Element First-Element

This works fine if the text elements have RTL directionality (text from Arabic, Farsi, Hebrew etc.), or if they are interleaved with RTL elements:

<div dir="rtl">
<span>First-Element-RTL</span>
<span>Second-Element-RTL</span>
<span>Third Element-RTL</span>
</div>

or:

<div dir="rtl">
<span>First-Element-LTR</span>
<span>Second-Element-RTL</span>
<span>Third Element-LTR</span>
</div>

But if all the elements are of LTR directionality, then the order of the language is used, and we get the undesired ordering:

First-Element Second-Element Third-Element

How can we achieve a fixed order of the elements independent of the directionality of the text in the elements - that is, the technique (whether html or css) should be indifferent to the language of individual text elements.

This issue arises when the content of span elements is variable and provided by the user, for example user names that can be in an RTL language or English.

Edit

I have to emphasize that we are talking about ordering the text spans relative to each other, not changing the flow of the text itself, so 'English Text' should appear as is, not as 'txeT hsilgnE'.

Edit

This is a simple HTML segment to test the answer provided by Jukka. This presents as 'bar foo' aligned to the right. It shows (at least on my browser) that there is no need for { unicode-bidi: bidi-override; } at the container level to get the desired result.

<html>
<head>
    <style type="text/css">
        span { unicode-bidi: embed; }
    </style>
</head>
<body>
<div dir="rtl">
<span>foo</span>
<span>bar</span>
</div>
</body>
</html>
like image 580
Basel Shishani Avatar asked Sep 16 '25 21:09

Basel Shishani


1 Answers

div { unicode-bidi: bidi-override; }
span { unicode-bidi: embed; }

The first rule forces a specific direction, in this case RTL as set in HTML, overriding the inherent directionality of text (which depends on the directionality properties of characters).

The second rule makes each span element an “autonomous island” in directionality, i.e. text direction inside it is not affected by enclosing elements but only on properties set on the element itself and on the directionality properties of characters. So e.g. Latin letters run left to right, Hebrew and Arabic letters right to left.

There’s a problem, though. If a span contains, say, “foo (2)”, it will be rendered as “(foo (2”. The reason is that the element has RTL direction, as inherited from the parent. Although the dir attribute, as well as the direction property, sets weak directionality only (which does not affect e.g. a sequence of Latin letters, which have strong LTR directionality), it affects e.g. situations where parentheses are involved. Parentheses have ambiguous directionality, so they are treated according to the weak directionality settings.

I’m afraid there’s no simple way around this part of the use. You can of course set the directionality of span elements according to the what you expect to be the most common situation, like span { direction: ltr; } if you expect texts to be in English mostly. But for a real solution, you would need to control the weak directionality settings according to the language of the content.

like image 153
Jukka K. Korpela Avatar answered Sep 18 '25 18:09

Jukka K. Korpela