On my first flight on a UAE-based carrier, I spent all fourteen hours totally engrossed in the beautifully symmetrical, bilingual English/Arabic signage and media that surrounded me. I had worked on projects in English and Arabic before, but had not seen them used together so seamlessly. The airline’s designers deeply embraced the potential for complementary layouts and took full advantage of the directionality of each language.
With a mandate to have consistently co-present Arabic and English, FIND presents us, as a web implementation team, with a unique challenge. In a world full of tablets and phones, our job is to bring that beautiful, complementary, bidirectional, bilingual design aesthetic to many different browsing devices in a usable way.
Fortunately, HTML and CSS have come a long way recently, both in supporting right-to-left languages and in offering the responsive tools to handle many different device sizes. We could not have built the FIND website in its current form using the prevalent technologies of just five years ago.
The basic building block of any bilingual English/Arabic site is the CSS property
This property influences a number of other layout properties to cause a block of HTML to be readable in Arabic or another right-to-left language. Instead of being default aligned left and flowed to the right, text is default aligned right and flowed to the left. This reversal applies to inline elements and floats, causing anything within a block so marked to facilitate a right-to-left reading order. All modern browsers have good support for this property. So, I'll start with it as a simple example of how FIND's bilingual markup works.
In implementing the views for FIND, we use a language called
Slim. It allows us to use a shorthand for classes and other markup, which corresponds more closely to the CSS and reduces the amount of angle-bracket markup required. I'll show it throughout as an intermediate step.
So, given the CSS:
we can write the simple, readable Slim code:
Which generates this (longer) HTML to be sent to the browser:
<div class="ar">
العربية
</div>
<div class="en">
English
</div>
That gives us an acceptable layout for long strings of text, where we want an Arabic sentence or paragraph, presented right-to-left, followed by its English translation, presented left-to-right.
For shorter strings, we often want to take advantage of symmetry on the same line. Tools we can use include tables, floats, and absolute positioning. The old HTML <table> element is strongly deprecated as a layout tool; for accessibility reasons and clean markup, among other reasons, it should only be used to represent actual tables of data.
FIND uses floats in most places, and absolute positioning in a few others. Floats can be challenging to work with directly. The fundamentals work like this:
/* CSS */
.float_right {
float: right;
}
/ Slim
.ar.float_right العربية
.en English
<!-- HTML -->
<div class="at float_right">
العربية
</div>
<div class="en">
English
</div>
This yields the desired layout for this example, but it won't handle it well if the English and Arabic texts collide, either because the window is resized, or because the text is too long. They'll simply overlap each other once they get too close. We can fix this by floating both the Arabic and the English, and setting some sizes:
/* CSS */
.float_left {
float: left;
width: 50%;
}
.float_right {
float: right;
width: 50%;
}
/ Slim
.ar.float_right العربية
.en.float_left English
<!-- HTML -->
<div class="ar float_right">
العربية
</div>
<div class="en float_left">
English
</div>
Unfortunately, now that all our content is in floats, we have to acknowledge some more complex details of the CSS box model: reserving vertical space for the floats, making sure that subsequent content clears the floats, etc. And really, when the browser is resized to a small size, say on a phone or small tablet, we'd prefer to fall back to the top-and-bottom layout we started with.
This is where a CSS grid framework comes in handy, to reliably take care of these implementation details and provide responsive behaviors for different screen sizes. FIND uses
Twitter Bootstrap 3, which provides a CSS vocabulary for a 12-column grid.
/ Slim
.container
.row
.ar.pull-right.col-sm-6 العربية
.en.col-sm-6 English
<!-- HTML -->
<div class="container">
<div class="row">
<div class="ar pull-right col-sm-6">
العربية
</div>
<div class="en col-sm-6">
English
</div>
</div>
</div>
This does a lot of work for us. We lay out the Arabic in a grid column consuming half the available space, the English in a grid column consuming the other half. This corresponds to the "6" in "col-sm-6" - 6 is half of the 12 columns available in the grid.
The "sm" in the CSS style stands for "small" and tells Bootstrap to use the columnar layout on small devices and up, but fall back to a stacked, non-columnar layout on others. In Bootstrap parlance, "small" is a screen size that corresponds roughly to an iPad in vertical orientation. Even smaller devices, like phones, are labeled as "extra small" and use "xs" in the CSS style. So, we have created a layout that will stack the English and the Arabic on a phone, but put it in symmetrical columns on a larger device.
Normally Bootstrap would put whatever comes first in the HTML in the leftmost column, but we don't want that, so we change the behavior by adding the Bootstrap-defined CSS class "pull-right" to the Arabic part. That makes it appear in the right column and the top of the stack.
Absolute positioning is useful in certain cases where we need to overlay existing content.
To do this, we attach the CSS property "position: relative" to the parent element, such as a div holding the image to be overlaid. Then we express where we want our overlay content in terms relative to the top, left, right or bottom of the parent element.
/* CSS */
.parent {
position: relative;
}
.child_left {
position: absolute;
left: 10px;
bottom: 10px;
}
.child_right {
position: absolute;
right: 10px;
bottom: 10px;
}
/ Slim
.parent
img src="example.jpg"
.ar.child_right العربية
.en.child_left English
<!-- HTML -->
<div class="parent">
<img src="example.jpg">
<div class="ar child_right">
العربية
</div>
<div class="en child_left">
English
</div>
</div>
Like the manual float example above, we have to exercise some additional care to avoid overly long text colliding, by setting explicit widths and overflow properties. But since absolute positioning is only useful in cases where the dimensions are well known, this problem is manageable.
By following consistent and simple patterns for identifying Arabic and English texts in FIND using CSS, we have found it easy to make small tweaks to the CSS to achieve better balance and symmetry in our layouts. Most importantly, because we use different fonts for Arabic and English, sometimes font-size and line-height properties need adjustment so that multiline texts lay out neatly.
We also found that the more consistent and simple we make our CSS markup to identify Arabic and English texts, the easier it is for our bilingual content management system to do its job. I'll talk more about content management for FIND in my next post.
We're learning and improving as we go along. I feel that FIND has embraced bilingual co-presence to a degree that I have seldom seen elsewhere on the web, so we're breaking some new ground with each feature we produce. Please let us know if you have any ideas or suggestions as to how to make FIND more readable for you on your favorite device.