Visual vs. logical ordering of text

Visual ordering of text was a common way of representing Hebrew in HTML on old user agents that didn’t support the Unicode bidirectional algorithm. Relatively little persists today. Characters making up the text were stored in the source code in the same order you would see them displayed on screen when looking from left to right.

(Visual ordering less common for Arabic. Since the Arabic letters are all joined up there was a stronger motivation on the part of Arabic implementers to enable the logical ordering approach. Visually ordered Arabic text may use separate code points for each shaped glyph.)

With logical ordering, text is stored in memory in the order in which it would normally be typed (and usually pronounced). The Unicode bidirectional algorithm is then applied by the browser, at display time, to produce the correct visual display.

Visual ordering and its shortcomings

The following picture shows the bidirectional phrase פעילות הבינאום, W3C at the top in blue, as it would normally appear when displayed in a right-to-left paragraph. The numbered arrows show the reading direction. You read the sequences in the order of the numbers below the arrows.

The second and third lines (green text) show the order in which characters are stored in memory (from left to right in the visualization) for logical and visual encoded text, respectively. The logical order also reflects the order in which you would type the text as a content author. The same is true of the visual line, ie. you type the text backwards (unless you have an editing tool that automatically rearranges logical input to visual storage order for you).

The following image shows an example of visually ordered source code in HTML.

To make visual ordering work, in addition to writing the text backwards, you must also do such things as disable any line wrapping, explicitly right-align text in paragraphs and table cells, add explicit line breaks, and, when translating from a language that uses a left-to-right script, manually reverse the order of table columns. You also have to add and maintain separate spans of link or emphasis markup for any marked up text that wraps onto another line.

(This is actually a fairly clean implementation. For example you can also find such things as right-aligned paragraphs with <nobr>..</nobr> tags around each line. If your window is too narrow, the beginning of each line disappears off the right side of the browser.)

A key issue relates to maintenance. For example, apart from the difficulty of typing the Hebrew backwards, if you want to add a few words in the middle of a paragraph of visually ordered text, you would have to move text to and from every line that followed it in the paragraph in order to reset the line breaks. You would also have to manually rearrange any inline markup that spans more than one line (either before or after the change).

The result is very fragile code that is difficult to maintain.

In addition, all the extra tags needed to manage the text would bloat your code and impact not only authoring time, but also bandwidth.

Visual ordering can also cause problems at a higher level. For example, it requires the order of table columns to be manually reversed when translating into another language. Line breaks will also need to be manually re-flowed if the page geometry changes. Often the search dialog of browsers captures text in logical order, which causes the search key not to match the text stored in visual order, unless there is special logic in the browser to handle this issue. Etc.

Using logically ordered text, on the other hand, makes it almost trivial to create long paragraphs of flowing text that automatically wrap to the width of the block element. It also makes it much easier to address accessibility, using such things as screen readers. You simply type the text in the spoken order, and the Unicode Bidirectional Algorithm does all the heavy lifting for you.

Working with legacy systems

In modern systems where backend storage includes legacy data (created at some point using green screens) represented in visual order (such as mainframes or iSeries computers) it is necessary to support bidirectional flow of data between the back end (visual ordering) and web front end (logical ordering).

Various factors may be involved in this process, besides the order of the characters themselves.

Visual ordering and character encodings

We always recommend that you use UTF-8 as the character encoding of your page, which supports logical ordering of characters, but if, and only if, you choose to use an ISO 8859 encoding instead, you need to take some care in declaring the encoding. You declare the encoding of your content either in the HTTP header or in a meta element inside the document (or both).

There are special conventions with regard to the encoding declarations used for Hebrew text that relate to the visual vs. logical ordering question. A declaration of ISO-8859-8 would indicate that the text is visually encoded. For logically-ordered content using the ISO encodings you must label ISO-encoded text as ISO-8859-8-i.

Understanding inline markup and bidirectional text in HTML

If you know the direction of all the text involved, tightly wrap every opposite-direction phrase in markup. Add the CSS shim to your style sheet, and use the dir attribute on that markup. Be sure to nest markup to show the structure.

<p>the title is <cite dir="rtl">AN INTRODUCTION TO <span dir="ltr">c++</span></cite> in arabic.</p>

If you want to bullet-proof your code for browsers that don’t support the CSS shim where tightly-wrapped text is followed inline by a number or a logically separate opposite-direction phrase, add &rlm; or &lrm; immediately after the phrase.

<p>we find the phrase '<span dir="rtl">INTERNATIONALIZATION ACTIVITY</span>&lrm;' 5 times on the page.</p>

If you don’t know the direction of text that will be inserted at run time, add dir=auto to any markup that tightly wraps the location. If there is no markup, wrap the location with a bdi element.

foreach $restaurant
	echo "<p><bdi>$restaurant['name']</bdi> - $restaurant['count'] reviews</p>";

Tell me more

The article first describes basic principles underlying how the Unicode bidirectional algorithm works. Then it looks at some of the more common scenarios where the bidi algorithm requires assistance through the addition of markup or control codes. It is written in a tutorial style that helps the reader with little or no background in handling bidirectional text progress from one concept to the next.

How the bidi algorithm works

If you’re not really familiar with the Unicode Bidirectional Algorithm, then before reading further you should read the basic introduction to how the bidi algorithm works.

Where the bidi algorithm needs help

In the sections below, we will examine specific examples of what can go wrong, why it goes wrong, and what fixes it. Nevertheless, it is important to realize that, basically, the problems all occur when content in one direction includes an inline phrase in the opposite direction. We will call these opposite-direction phrases. An opposite-direction phrase may be a single directional run (such as a word), or may be a set of directional runs with an embedded change in base direction.

In the following example, the English sentence contains an opposite-direction phrase between the quotation marks. That phrase, itself, also contains an opposite-direction phrase: the word C++.

Displayed result of previous code

Common examples of such phrases include quotations, titles of books, articles or plays, formatted numbers (e.g. phone numbers and MAC addresses), street and email addresses, and various names, such as brand names, acronyms, part numbers, site names, place names, file names (and paths), etc.

The problem is worse in applications that drop text into a page, say from a database. The application often does not know a-priori whether such text is (or perhaps contains) an opposite-direction phrase, and has to estimate its direction at run-time by checking the Unicode ranges of its characters. HTML5 introduces a feature for doing so in the browser.

Whenever an opposite-direction phrase occurs, things can go wrong. That is, something will go wrong if the text includes, without any special “wrapping”, an inline opposite-direction phrase that:

  • begins or ends with neutral characters,
  • begins with a number,
  • is followed by a number,
  • is followed by another, but logically separate, opposite-direction phrase,
  • contains one or more nested phrases whose base direction is opposite to that of the phrase.

Although this list seems daunting, there is no need to determine which, if any, of these cases applies to a particular phrase. There is a simple, default way of “wrapping” opposite-direction phrases that will prevent problems in all of the cases above, and do no harm when none of them apply. We will describe how do such wrapping for HTML5-aware browsers and for others.

Useful markup and control codes

The dir attribute

The dir attribute sets the base direction for the content of an element.

To set the default direction of the whole HTML document to right-to-left, add dir="rtl" to the html tag. This will result in all elements in the document inheriting a base direction of RTL.

You can change the base direction for content within a page by surrounding that content with an element and adding a dir attribute to indicate the desired direction.

In principle, the right thing to do for every opposite-direction phrase is to set its base direction by using the dir attribute on an element tightly wrapping the phrase.

HTML5 changes the semantics of the dir attribute. In browsers that implement this change, the content of the element on which the dir attribute sits will be isolated, in terms of the bidi algorithm, from the content surrounding it. Wrapping the opposite-direction phrases in an element with a dir attribute, helps address some of the problems listed in the previous section; adding isolation helps resolve some more.

Check out the worked examples below to see how this works.

LRM/RLM

The visual order in which text is displayed can sometimes be modified using two invisible Unicode control characters: LRM (U+200E LEFT-TO-RIGHT MARK) which can be added to the source text using the character itself or the escapes or &lrm;, and RLM (U+200F RIGHT-TO-LEFT MARK), for which the escapes are or &rlm;). Each has the strong type indicated by its name, like an A or an א, but is invisible.

One use of LRM and RLM is to extend a directional run through neutral or weak characters at the start or end of an opposite-direction phrase, by putting a mark of the same direction as the phrase on the other side of those neutral or weak characters. You can see an example of how it works in the advanced usage notes for use case 1 below.

Another use is to separate an opposite-direction phrase from some neighboring but independent text that would otherwise be incorrectly treated as the same directional run (see use case 3 for a good example). To do this you can put between them a directional mark with the same directionality as the overall context.

In HTML5, where the dir attribute is isolating, both cases are better addressed by adding the dir attribute to an element wrapping the opposite-direction phrase, so there is really no need to use LRM/RLM. See below for details.

dir=”auto”

HTML5 addresses another need: text dropped into a page, say from a database, when you don’t know its base direction. Before HTML5, you could only set the dir attribute to ltr or rtl, and had to somehow determine yourself which of them was appropriate.

HTML5 provides a new value for the dir attribute: auto. The auto value tells the browser to look at the first strongly typed character in the element. If it’s a right-to-left typed character such as a Hebrew or Arabic letter, the element will get a direction of rtl. If it’s, say, a Latin character, the direction will be ltr.

There are corner cases where this may not give the desired outcome, but it should usually produce the desired result.

Note that the browser ignores any neutral or weak characters at the beginning of the text when looking for the first strong character. It also ignores anything inside a bdi element or an element with a dir tag of its own, including auto.

Like any other use of the dir attribute in HTML5, dir="auto" also directionally isolates its content from its surroundings.

The bdi element

HTML5 also introduces a new element, bdi. It is just like a span except that, whether or not it is used with a dir attribute, it directionally isolates its content from the surrounding text; “bdi” stands for “bidirectional isolate”.

bdi comes with the dir attribute set to the new auto value by default (see above), however it is also possible to use an explicit dir attribute on bdi with values set to ltr or rtl, if you know the direction of the phrase and just want to isolate it.

The choice of whether to attach dir="auto" on an existing element or to wrap the phrase in a bdi depends on whether you already have an inline element tightly wrapping the potentially opposite-direction phrase, and whether you happen to know the phrase’s direction (or can guess at it better than the browser’s dir="auto" logic).

Steps for handling inline bidirectional text in HTML

Here we summarize default guidelines for working with bidirectional inline text. Often alternative approaches will work, but the approaches outlined here are simple to apply and should work for all cases.

Descriptions of the markup used can be found in the previous section. Following sections will provide worked examples. Some of the alternatives are also explored in the worked examples.

Tightly wrapping opposite-direction phrases

The easiest way to address bidi issues in your content is to tightly wrap every opposite-direction phrase in markup that sets its base direction.

By tightly wrapping, we mean that the element contains the entire opposite-direction phrase, and nothing but the opposite-direction phrase.

When none of the problematic use cases apply, this will not have any visible effect. But when one of them does apply, this provides a simple solution, that doesn’t require you to figure out specifically what the problem is.

HTML5 approach

The latest version of the HTML5 specification says that browsers should change their default style sheet so that the dir attribute isolates the text inside the element from that surrounding it. This means that more of the potential problems pointed out earlier simply melt away when you tightly wrap all opposite-direction phrases with elements containing dir.

The CSS Shim. Unfortunately, not all browsers yet apply isolation when dir is used. For this reason, during the transitional phase, we recommend that you provide some CSS yourself to produce the effect of the default style sheet. The following browser versions are known to support the necessary CSS:

  • Firefox 14+
  • Chrome 18+
  • Safari 6+
  • Opera 15+

Internet Explorer 8-10 doesn’t support the CSS, but does use a hack that produces a similar effect, and is usually good enough.

Browsers that don’t yet support the CSS will simply behave in the same way as before.

The CSS shim is as follows:

[dir='ltr'], [dir='rtl'] { 
	unicode-bidi: -webkit-isolate;
	unicode-bidi: -moz-isolate;
	unicode-bidi: -ms-isolate;
	unicode-bidi: isolate;
	} 
bdo[dir='ltr'], bdo[dir='rtl'] {
	unicode-bidi: bidi-override; 
	unicode-bidi: -webkit-isolate-override; 
	unicode-bidi: -moz-isolate-override; 
	unicode-bidi: -ms-isolate-override; 
	unicode-bidi: isolate-override;
  	}

At the time of writing, all browser versions that support isolation in CSS also support the bdi element.

To make sure that a phrase that contains any opposite-direction characters is displayed correctly, do the following.

If you know the phrase’s direction, or can work it out for injected text, wrap all opposite-direction phrases in an element with a dir attribute. This is not always necessary, but never does any harm. If the phrase is already tightly wrapped in an inline element, you can use the existing element for this purpose. If not, add a span element.

Examples for text in a left-to-right context
<p>ltr-text RTL-TEXT</p> <p>ltr-text <span dir=rtl>RTL-TEXT</span></p>
<p>ltr-text <cite>RTL-TEXT</cite></p> <p>ltr-text <cite dir=rtl>RTL-TEXT</cite></p>
<p>ltr-text <cite>RTL-TEXT ltr-text-in-rtl</cite></p> <p>ltr-text <cite dir=rtl>RTL-TEXT <span dir=ltr>ltr-text-in-rtl</span></cite></p>

If you don’t know the phrase’s direction, ie. unknown text that will be injected at run time, then either:

  1. wrap the phrase in <bdi>...</bdi>. (If already wrapped by a span element, you may replace the span with bdi.) Without an explicit dir value, dir="auto" is implied.
  2. or alternatively, if the phrase is tightly wrapped by an element already, you could just add dir="auto" to that element
Examples for text in a left-to-right context
<p>static-text injected-text</p> <p>static-text <bdi>injected-text</bdi></p>
<p>static-text <cite>injected-text</cite></p> <p>static-text <cite><bdi>injected-text</bdi></cite></p>or

<p>static-text <cite dir=auto>injected-text</cite></p>

Bullet-proofing for legacy browsers

If dir isolation or the CSS shim is not supported by a browser or browser version, it is not possible to isolate phrases from their surrounding content. It is often possible to achieve a similar effect, however, using an RLM or LRM Unicode control code, if you know the direction of the surrounding text.

To make sure that a phrase that contains any opposite-direction characters is displayed correctly, do the following:

If you know the direction of the text surrounding a phrase, or can work it out for injected text:

  1. tightly wrap opposite-direction phrases in an inline element that uses the dir attribute to set the direction of the phrase, as described above.
  2. if the tightly-wrapped phrase in the previous step is followed inline (possibly after some intervening neutral characters) by a number or a logically separate opposite-direction phrase, then add a directional mark (RLM or LRM) immediately after the markup of that phrase. Choose one that matches the direction of the surrounding context. If you do not want to or cannot check whether the phrase is followed by one of those things, you can add a directional mark matching the direction of the context after every tightly-wrapped phrase.
    Examples for text in a left-to-right context
    <p>ltr-text <span dir=rtl>RTL-TEXT</span> 1234</p> <p>ltr-text <span dir=rtl>RTL-TEXT</span>&lrm; 1234</p>
    <p>ltr-text <span dir=rtl>RTL-TEXT-1</span>, <span dir=rtl>RTL-TEXT-2</span></p> <p>ltr-text <span dir=rtl>RTL-TEXT-1</span>&lrm;, <span dir=rtl>RTL-TEXT-2</span></p>

If you don’t know the phrase’s direction, ie. unknown text that will be injected at run time, there isn’t really a good way to automatically apply the right base direction. However, if you know that one injected phrase may be followed inline by a number or a logically separate opposite-direction phrase, you can add a directional mark immediately after the phrase that matches the direction of the surrounding context in order to separate the phrase from what follows.

If the phrase is being injected at run-time and its overall direction is unknown, it can be estimated from the direction of its individual characters, e.g. by using the direction of its first strongly typed character. Open-source code for doing so is available, but HTML does not offer any features for easing this task. It is possible (but not necessary) to skip the steps above only if both the overall direction of the phrase and the direction of the last strongly typed character in the phrase is the same as the context direction.

Worked examples for static use cases

In this section we will look at how to write code that addresses various use cases where the content is written by the author. The section following this deals with use cases where content is injected into the page.

In all cases, the sections related to use of HTML5 features assume the availability of the CSS shim described above for browsers that support it but don’t support isolation with dir.

Use case 1

In this example a right-to-left book title is embedded in a left-to-right context, and the book title itself contains an embedded left-to-right phrase. Here is the code without any additional bidi markup:

 Bad code. Don’t copy!

<p>the title is "AN INTRODUCTION TO c++" in arabic.</p>

What one would expect to see is:

Displayed result of previous code

Unfortunately, the bidirectional algorithm cannot tell where the boundaries of the nested changes in base direction should be. The result, without help in the markup, is:

Displayed result of previous code

Fixing use case 1 in HTML5

To address this in HTML5, if there is no other markup around the opposite-direction phrases, wrap both in markup with the appropriate dir value. (Note, by the way, how the markup appears inside the quotation marks, which are part of the English text.)

<p>the title is "<span dir="rtl">AN INTRODUCTION TO <span dir="ltr">c++</span></span>" in arabic.</p>

It is important to note that each phrase is nested. Just wrapping the Arabic in one span followed by a span containing the C++ would result in no improvement at all.

advanced usage notes: Note that two elements with dir are needed in this case. This is because there are two opposite-direction phrases. If only one was used, like this:

 Bad code. Don’t copy!

<p>the title is "<span dir="rtl">AN INTRODUCTION TO c++</span>"</p>

the displayed text would be as shown below. This moves the C++ to the left, as needed, but the + signs appear on the wrong side of the C.

Displayed result of previous code

This fails because the “C++” is an opposite-direction (LTR) phrase within the title, ending in neutral characters and the phrase is now being displayed with an RTL base direction. The bidi algorithm has no way of knowing that the plus signs are part of an LTR phrase, not of the RTL context, and thus displays them to the left of the “C” instead of to its right.

To solve this problem, wrap the overall RTL phrase in a <span dir="rtl">, and the LTR phrase nested inside it in its own <span dir="ltr">, as shown.

If there is already suitable markup to surround the book title, such as a cite element, add the dir attribute to that.

<p>the title is <cite dir="rtl">AN INTRODUCTION TO <span dir="ltr">c++</span></cite> in arabic.</p>

advanced usage notes: If the “C++” in this example was an ordinary Latin-script word, such as “Python” you wouldn’t actually need to mark it up to get the right display. The bidi algorithm would take care of it. However marking up text in this way avoids you having to understand why these two cases are different, and having to work out which case applies for your content.

Similarly, if the title contained no embedded left-to-right text, you wouldn’t actually need directional markup at all, but adding it avoids possible issues related to following inline text, such as where the text is edited to add a following number or another title, like this:

<p>the titles are <cite dir="rtl">AN INTRODUCTION TO ARABIC</cite>, <cite dir="rtl">FIRST STEPS IN URDU</cite>, and <cite dir="rtl">MASTERING HEBREW</cite>.</p>

Fixing use case 1 in browsers that don’t support HTML5

The solution outlined for HTML5 aware browsers will work equally well for browsers that don’t support HTML5 features.

advanced usage notes: As noted earlier, one use of LRM and RLM is to extend a directional run through neutral or weak characters at the start or end of an opposite-direction phrase, by putting a mark of the same direction as the phrase on the other side of those neutral or weak characters. For this example, instead of wrapping the “C++” in a <span dir="ltr">, we could add &lrm; after the second plus:

<p>the title is <cite dir="rtl">AN INTRODUCTION TO c++&lrm;</cite></p>

The result is what we need:

Displayed result of previous code

Because the LRM is a strongly left-to-right character, the neutral pluses are now between two strong left-to-right characters (the C and the LRM). They therefore also become left-to-right in direction, making a single directional run of the four characters.

Used this way, however, LRM and RLM are a bit like gotos in programming languages: a quick hack that, unlike the dir attribute, says nothing about the structure of the text. And they simply cannot be used to deal with an opposite-direction phrase that happens to contain a nested phrase in the original direction, like our complete “Introduction to C++” example above. That may seem like an esoteric case, but it is surprisingly common when displaying right-to-left data in a left-to-right page, because the use of left-to-right words (like “C++”) is not uncommon in right-to-left text.

So, if you don’t want to analyze whether LRM and RLM can replace the use of the dir attribute in your case, just use the dir attribute.

Use case 2

In the next example, the opposite-direction phrase is followed by a logically separate number. This is the code without any bidi markup:

 Bad code. Don’t copy!

<p>we find the phrase 'INTERNATIONALIZATION ACTIVITY' 5 times on the page.</p>

You would expect to see:

Displayed result of previous code

You would actually see:

Displayed result of previous code

This happens because the bidi algorithm tells the browser to treat the “5″ as part of the Hebrew text. This is not appropriate here though. We need to find a way to say that the name and the number are separate things, ie. to isolate the inserted name from the number.

Fixing use case 2 in HTML5

In a browser that supports isolating dir or the CSS shim, wrap the opposite-direction phrase (the title) in markup and add the appropriate dir value. There is no need to add anything else, since the dir attribute automatically isolates its content.

<p>we find the phrase '<span dir="rtl">INTERNATIONALIZATION ACTIVITY</span>' 5 times on the page.</p>

If there is already suitable markup to surround the book title, such as an a element, add the dir attribute to it.

<p>we find the phrase '<a href="..." dir="rtl">INTERNATIONALIZATION ACTIVITY</a>' 5 times on the page.</p>

Fixing use case 2 in browsers that don’t support HTML5

For browsers where dir doesn’t isolate, you would fix this by not only adding the markup around the opposite direction, Hebrew text, but adding also an LRM character after it. That would prevent the number being associated with the right-to-left text.

<p>we find the phrase '<span dir="rtl">INTERNATIONALIZATION ACTIVITY</span>&lrm;' 5 times on the page.</p>

If the search string was already tightly wrapped by an element, use that element tag to add the dir attribute, and add the LRM character after it.

Of course, if the overall context is right-to-left, eg. Arabic/Hebrew/etc. text, and the book title was in English, you would need to add an RLM character rather than an LRM character.

Use case 3

Neutrals between same directional runs can sometimes be misinterpreted by the bidi algorithm. In this use case we have several country names in Arabic listed in a LTR paragraph. This is an example of an opposite-direction phrase followed by another, but logically separate, opposite-direction phrase. Here is the source code without any bidi markup:

 Bad code. Don’t copy!

<p>the names of these states in arabic are EGYPT, BAHRAIN and KUWAIT respectively.</p>

We expect to see the following:

Egypt appears to the left of Bahrain.

In the actual result, the first two Arabic words are reversed and the intervening comma is moved to the right side of the space between the words.

Bahrain appears to the left of Egypt.

The reason for the failure is that, with a strongly typed right-to-left (RTL) character on either side, the bidirectional algorithm sees the neutral comma as part of the Arabic text. It is interpreting the first two Arabic words and the comma as a single directional run in Arabic. In fact it is part of the English text, and should mark the boundary between the two separate right-to-left directional runs in Arabic.

The solution for this use case is similar to that for the previous use case, so we will keep the notes below brief, and assume that you have read the solutions for use cases 1 and 2. We will present just the default markup approach.

Fixing use case 3 in HTML5

Simply wrap each Arabic word with markup and add the appropriate dir value.

<p>the names of these states in arabic are <span dir="rtl">EGYPT</span>, <span dir="rtl">BAHRAIN</span> and <span dir="rtl">KUWAIT</span> respectively.</p>

If there is already markup surrounding the Arabic text, such as an a element, add the dir attribute to it.

<p>the names of these states in arabic are <a href="..." dir="rtl">EGYPT</a>, <a href="..." dir="rtl">BAHRAIN</a> and <a href="..." dir="rtl">KUWAIT</a> respectively.</p>

Fixing use case 3 in browsers that don’t support HTML5 features

In HTML4 add markup around the Arabic text, but add also an LRM character after it whenever that text is followed by another opposite-direction phrase. Use an RLM character if the surrounding context is right-to-left.

<p>the names of these states in arabic are <span dir="rtl">EGYPT</span>&lrm;, <span dir="rtl">BAHRAIN</span> and <span dir="rtl">KUWAIT</span> respectively.</p>

As before, if the Arabic text was already tightly wrapped by an element, use that element tag to add the dir attribute.

Using language information in XHTML, HTML and CSS

Presentation styles are commonly used to control changes in fonts, font sizes and line heights when language changes occur in the document. This can be particularly useful when dealing with Simplified versus Traditional Chinese, where users tend to prefer different fonts, even though they may be using many of the same characters. It can also be useful to better harmonize the look of mixed, script-specific fonts, such as when mixing Arabic and Latin fonts.

This page looks at available options for doing this most effectively.

The best way to style content by language in HTML is to use the :lang selector in your CSS style sheet. For example:

:lang(ta) 	{
    font-family: Latha, "Tamil MN", serif;
    font-size: 120%;
    }

The rest of the article adds some detail about :lang, and compares with two other approaches. It also considers implications for documents served as application/xhtml+xml.

There are four ways to apply different styles to different languages in a multilingual document using CSS. They are listed here in order of preference.

  1. the :lang() pseudo-class selector
  2. a [lang |= "..."] selector that matches the beginning of the value of a language attribute
  3. a [lang = "..."] selector that exactly matches the value of a language attribute
  4. a generic class or id selector

The remainder of this page explains and provides examples of ways in which the use of these selectors differ.

Inheritance of language values

A significant difference between :lang and the other methods is that it recognizes the language of the content of an element even if the language is declared outside the element in question.

Suppose, for example, that in a future English document containing Japanese text you wanted to style emphasized Japanese text using special Asian CSS3 properties, rather than italicization (which doesn’t always work well with the complex characters of Japanese). You might have the following rules in your style sheet:

em { font-style: italic; }
em:lang(ja) { font-style: normal; text‑emphasis: dot; text‑emphasis‑position: over right; }

The text-emphasis and text-emphasis-position properties are specified as per the current Editor’s Draft of CSS3 Text Decoration, and may change before the draft moves to recommendation.

Now assume that you have the following content, that the user agent supports :lang, and that the html tag states that this is an English document.

<p>This is <em>English</em>, but <span lang="ja">これは<em>日本語</em>です。</span></p>

You would expect to see the emphasized English word italicized, but the emphasized Japanese word in regular text with small dots above each character, something like this:

Picture of what was just described.

The important point to be made in this section is that this would not be possible using the [lang|="..."] or [lang="..."] selectors. For those to work you would have to declare the language explicitly on each Japanese em tag.

This is a significant difference between the usefulness of these different selectors.

Which language attribute?

The lang attribute is used to identify the language of text served as HTML. Text served as XML should use the xml:lang attribute.

For XHTML that is served as text/html, it is recommended that you use both attributes, since the HTML parser will pick up on the lang attribute, whereas if you parse the content as XML the xml:lang attribute will be used by your XML parser.

The article will first discuss the various options for styling by language in HTML, using the lang attribute. There then follows a section about how to style XML documents based on xml:lang.

The :lang(...) pseudo-class selector

The HTML fragment:

<p>It is polite to welcome people in their own language:</p>
<ul>
    <li lang="zh-Hans">欢迎</li>
    <li lang="zh-Hant">歡迎</li>
    <li lang="el">Καλοσωρίσατε</li>
    <li lang="ar">اهلا وسهلا</li>
    <li lang="ru">Добро пожаловать</li>
    <li lang="din">Kudual</li>
</ul>

could have the following styling:

body 		{font-family: "Times New Roman", serif;}
:lang(ar) 	{font-family: "Traditional Arabic", serif; font-size: 120%;}
:lang(zh-Hant) 	{font-family: PMingLiU,MingLiU, serif;}
:lang(zh-Hans) 	{font-family: SimSum-18030,SimHei, serif;}
:lang(din) 	{font-family: "Doulos SIL", serif;}

The Greek and Russian use the styling set for the body element.

This is the ideal way to style language fragments, because it is the only selector that can apply styling to the content of an element when the language of that content is declared earlier in a page.

A rule for :lang(zh) would match elements with a language value of zh. It would also match more specific language specifications such as zh-Hant, zh-Hans and zh-TW.

The selector :lang(zh-Hant) will only match elements that have a language value of zh-Hant or have inherited that language value. If the CSS rule specified :lang(zh-TW), the rule would not match our sample paragraph.

A [lang|="..."] selector that matches the beginning of a value of an attribute

For markup example we saw in the previous section, the style sheet could be written as:

body 		   {font-family: "Times New Roman", serif;}
*[lang|="ar"] 	   {font-family: "Traditional Arabic", serif; font-size: 120%;}
*[lang|="zh-Hant"] {font-family: PMingLiU,MingLiU, serif;}
*[lang|="zh-Hans"] {font-family: SimSum-18030,SimHei, serif;}
*[lang|="din"]     {font-family: "Doulos SIL", serif;}

Unlike :lang, this selector will only work for elements which carry a lang attribute.

There is a significant difference between this selector and [lang="..."]. Whereas [lang="..."] will only match elements when the selector value and the attribute value are identical, this selector value will match a language attribute value that has additional hyphen-separated values. Therefore the selector [lang|="sl"] would match sl-IT, sl-nedis or sl-IT-nedis, and the selector [lang|="zh-Hans"] would also match zh-Hans-CN.

A [lang="..."] selector that matches the value of an attribute

The third method of specifying rules is to use an attribute selector that exactly matches the attribute value.

Unlike :lang, this selector will only work for elements which carry a lang attribute.

For the earlier example of markup, the style sheet could be written as:

body                {font-family: "Times New Roman", serif; }
*[lang="ar"] 	    {font-family: "Traditional Arabic", serif; font-size: 120%;}
*[lang="zh-Hant"]   {font-family: PMingLiU,MingLiU, serif;}
*[lang="zh-Hans"]   {font-family: SimSum-18030,SimHei, serif;}
*[lang="din"] 	    {font-family: "Doulos SIL", serif;}

Note that using this approach en will not match en-AU. The match has to be exact.

Generic class or id selectors

This method avoids the need to match the language declarations at all, and relies on class or id attribute markup. Using an ordinary CSS class or id selector works with most browsers that support CSS. The disadvantage is that adding the attributes takes up time and bandwidth.

For the markup example above, this would require us to change the HTML code by adding class attributes as follows:

<p>It is polite to welcome people in their own language:</p>
<ul>
    <li class="zhs" lang="zh-Hans">欢迎</li>
    <li class="zht" lang="zh-Hant">歡迎</li>
    <li class="el" lang="el">Καλοσωρίσατε</li>
    <li class="ar" lang="ar">اهلا وسهلا</li>
    <li class="ru" lang="ru">Добро пожаловать</li>
    <li class="din" lang="din">Kudual</li>
</ul>

We could then have the following styling:

body 	{font-family: "Times New Roman", serif; }
.ar 	{font-family: "Traditional Arabic", serif; font-size: 120%;}
.zht 	{font-family: PMingLiU, MingLiU, serif;}
.zhs 	{font-family: SimSum-18030, SimHei, serif;}
.din	{font-family: "Doulos SIL", serif;}

Using CSS selectors in XML with xml:lang

As mentioned earlier, in a document that is parsed as XML you need to use the xml:lang attribute (rather than the lang attribute) to express language information.

Using :lang

Use of :lang is straightforward. If the document is parsed as HTML, the :lang selector will match content where the language was defined using a lang attribute value. However, if the document is parsed as XML, the :lang selector will match content labeled with an xml:lang attribute value and ignore any lang attribute value.

Using attr= and attr|=

Use of these selectors involves some additional considerations.

The xml: part of the xml:lang attribute indicates that this is the lang attribute used in the XML namespace. CSS3 Namespaces describes how to handle xml:lang as an attribute in a namespace. Basically you need to declare the namespace and then replace the colon with a vertical bar. For example:

@namespace xml "http://www.w3.org/XML/1998/namespace" 
*[xml|lang |= 'ar'] { ... }

or:

@namespace xml "http://www.w3.org/XML/1998/namespace" 
*[xml|lang = 'ar'] { ... }

Any @namespace rules must follow all @charset and @import rules and precede all other non-ignored at-rules and rule sets in a style sheet. Note, also, that the URI for the namespace declaration must be exactly correct.

Fallbacks

For browsers that are not namespace aware, you can fall back to escaped characters. For this you need no @namespace declaration, just one of the following:

*[xml\:lang |= '..'] { ... }

or:

*[xml\:lang = '..'] { ... }

Note, however, that if you try to use this approach with a namespace-aware browser (ie. most recent, major browsers), it will not work, so if you feel it is needed, you should use this approach in addition to the namespace-based selectors.

XHTML – Understanding Bi-directional Text Module

The Bi-directional Text module defines an element that can be used to declare the bi-directional rules for the element’s content.

Elements Attributes Minimal Content Model
bdo Core, dir* (“ltr” | “rtl”) (PCDATA | Inline)*

When this module is used, the bdo element is added to the Inline content set of the Text Module. Selecting this module also adds the attribute dir* ("ltr" | "rtl") to the I18N attribute collection.

The bdo element

The bidirectional algorithm and the dir attribute generally suffice to manage embedded direction changes. However, some situations may arise when the bidirectional algorithm results in incorrect presentation. The bdo element allows authors to turn off the bidirectional algorithm for selected fragments of text.

Attributes

The Core collection
A collection of basic attributes used on all elements, including class, id, title.
dir = “ltr|rtl”
This mandatory attribute specifies the base direction of the element’s text content. This direction overrides the inherent directionality of characters as defined in [UNICODE]. Possible values:

  • ltr: Left-to-right text.
  • rtl: Right-to-left text.

Consider a document containing the same text as before:

english1 HEBREW2 english3 HEBREW4 english5 HEBREW6

but assume that this text has already been put in visual order. One reason for this may be that the MIME standard ([RFC2045], [RFC1556]) favors visual order, i.e., that right-to-left character sequences are inserted right-to-left in the byte stream. In an email, the above might be formatted, including line breaks, as:

english1 2WERBEH english3
4WERBEH english5 6WERBEH

This conflicts with the [UNICODE] bidirectional algorithm, because that algorithm would invert 2WERBEH, 4WERBEH, and 6WERBEH a second time, displaying the Hebrew words left-to-right instead of right-to-left.

The solution in this case is to override the bidirectional algorithm by putting the Email excerpt in a pre element (to conserve line breaks) and each line in a bdo element, whose dir attribute is set to ltr:

<pre>
<bdo dir="ltr">english1 2WERBEH english3</bdo>
<bdo dir="ltr">4WERBEH english5 6WERBEH</bdo>
</pre>

This tells the bidirectional algorithm “Leave me left-to-right!” and would produce the desired presentation:

english1 2WERBEH english3
4WERBEH english5 6WERBEH

The bdo element should be used in scenarios where absolute control over sequence order is required (e.g., multi-language part numbers). The dir attribute is mandatory for this element.

Authors may also use special Unicode characters to override the bidirectional algorithm — LEFT-TO-RIGHT OVERRIDE (202D) or RIGHT-TO-LEFT OVERRIDE (hexadecimal 202E). The POP DIRECTIONAL FORMATTING (hexadecimal 202C) character ends either bidirectional override.

Character references for directionality and joining control

Since ambiguities sometimes arise as to the directionality of certain characters (e.g., punctuation), the [UNICODE] specification includes characters to enable their proper resolution. Also, Unicode includes some characters to control joining behavior where this is necessary (e.g., some situations with Arabic letters). XHTML includes character references for these characters.

The following DTD excerpt presents some of the directional entities:

   <!ENTITY zwnj CDATA "‌"--=zero width non-joiner-->
   <!ENTITY zwj  CDATA "‍"--=zero width joiner-->
   <!ENTITY lrm  CDATA "‎"--=left-to-right mark-->
   <!ENTITY rlm  CDATA "‏"--=right-to-left mark-->

The zwnj entity is used to block joining behavior in contexts where joining will occur but shouldn’t. The zwj entity does the opposite; it forces joining when it wouldn’t occur but should. For example, the Arabic letter “HEH” is used to abbreviate “Hijri”, the name of the Islamic calendar system. Since the isolated form of “HEH” looks like the digit five as employed in Arabic script (based on Indic digits), in order to prevent confusing “HEH” as a final digit five in a year, the initial form of “HEH” is used. However, there is no following context (i.e., a joining letter) to which the “HEH” can join. The zwj character provides that context.

Similarly, in Persian texts, there are cases where a letter that normally would join a subsequent letter in a cursive connection should not. The character zwnj is used to block joining in such cases.

The other characters, lrm and rlm, are used to force directionality of directionally neutral characters. For example, if a double quotation mark comes between an Arabic (right-to-left) and a Latin (left-to-right) letter, the direction of the quotation mark is not clear (is it quoting the Arabic text or the Latin text?). The lrm and rlm characters have a directional property but no width and no word/line break property.

The effect of style sheets on bidirectionality

In general, using style sheets to change an element’s visual rendering from block-level to inline or vice-versa is straightforward. However, because the bidirectional algorithm relies on the inline/block-level distinction, special care must be taken during the transformation.

When an inline element that does not have a dir attribute is transformed to the style of a block-level element by a style sheet, it inherits the dir attribute from its closest parent block element to define the base direction of the block.

When a block element that does not have a dir attribute is transformed to the style of an inline element by a style sheet, the resulting presentation should be equivalent, in terms of bidirectional formatting, to the formatting obtained by explicitly adding a dir attribute (assigned the inherited value) to the transformed element.


JQuery: Adding event handlers

One of the beauties of jQuery is the ability to easily add event handlers, which are methods that are called only upon a specific event or action taking place. For example, the method of adding a class to an element can be set to only occur upon that element being clicked on.

Below is a standard selector, grabbing all of the list items. The .click() event method is bound to the list item selector, setting up an action to take place upon clicking any list item. Inside the .click() event method is a function, which ensures any actions inside the event method are to be executed. The parentheses directly after the function are available to pass in parameters for the function, in which the event object is used in this example.

Inside of the function is another selector with the .addClass() method bound to it. Now, when a list item is clicked on that list item, via the this keyword, receives the class of saved-item.

$('li').click(function(event){
  $(this).addClass('saved-item');
});

Event Flexibility

The .click() event method, along with a handful of other event methods, is actually a shorthand method which uses the .on() method introduced in jQuery 1.7. The .on() method provides quite a bit of flexibility, using automatic delegation for elements that get added to the page dynamically.

Making use of the .on() method the first argument should be the native event name while the second argument should be the event handler function. Looking at the example from before, the .on() method is called in place of the .click() method. Now the click event name is passed in as the first argument inside the .on() method with the event handler function staying the same as before.

$('li').on('click', function(event){
  $(this).addClass('saved-item');
});

Nesting Events

It is possible to have multiple event handlers and triggers, nesting one inside another. As an example, below the .on() event method is passed the hover argument, thus being called when hovering over any element with the class of pagination. Upon calling the .on() event the .click() event is called on the anchor with the up ID.

$('.pagination').on('hover', function(event){
  $('a#up').click();
});

Event Demo

Using an alert message as a demo, the following code snippets show how to create an alert message and then removing that message based upon clicking the close icon.

HTML
<div class="notice-warning">
  <div class="notice-close">×</div>
  <strong>Warning!</strong> Im about to lose my cool.
</div>
JavaScript
$('.notice-close').on('click', function(event){
  $('.notice-warning').remove();
});

Event Methods

jQuery provides quite a few methods, all of which are based around registering user behaviors as they interact with the browser. These methods register quite a few events, most popularly, but not limited to, browser, form, keyboard, and mouse events. The most popular of these methods include:

Browser Events

  • .resize()
  • .scroll()

Document Loading

  • .ready()

Event Handler Attachment

  • .off()
  • .on()
  • .one()
  • jQuery.proxy()
  • .trigger()
  • .triggerHandler()
  • .unbind()
  • .undelegate()

Event Object

  • event.currentTarget
  • event.preventDefault()
  • event.stopPropagation()
  • event.target
  • event.type

Form Events

  • .blur()
  • .change()
  • .focus()
  • .select()
  • .submit()

Keyboard Events

  • .focusin()
  • .focusout()
  • .keydown()
  • .keypress()
  • .keyup()

Mouse Events

  • .click()
  • .dblclick()
  • .focusin()
  • .focusout()
  • .hover()
  • .mousedown()
  • .mouseenter()
  • .mouseleave()
  • .mousemove()
  • .mouseout()
  • .mouseover()
  • .mouseup()

Effects

Next to events, jQuery also provides a handful of customizable effects. These effects come by the way of different methods, including event methods for showing and hiding content, fading content in and out, or sliding content up and down. All of these are ready to use methods and may be customized as best see fit.

Each effect method has it’s own syntax so it is best to reference the jQuery effects documentation for specific syntax around each method. Most commonly though, effects generally accept a duration, easing, and the ability to specify a callback function.

jQuery CSS Animations

Custom animations of different CSS properties can be accomplished in jQuery, although this is a little less relevant as CSS can now handle animations itself. CSS animations offer better performance from a browser processing standpoint and are preferred where possible. jQuery animation effects, with the help of Modernizr, make for a perfect backup solution to any browser not supporting CSS animations.

Effect Duration

Using the .show() method as an example, the first parameter available to optionally pass in to the method is the duration, which can be accomplished using a keyword or milliseconds value. The keyword slow defaults to 600 milliseconds, while the keyword fast defaults to 200 milliseconds. Using a keyword value is fine, but millisecond values may also be passed in directly. Keyword values must be quoted while millisecond values do not.

$('.error').show();
$('.error').show('slow');
$('.error').show(500);

Effect Easing

In addition to setting the duration in which an effect takes place the easing, or speed at which an animation progresses at during different times within the animation, may also be set. By default jQuery has two keyword values for easing, the default value is swing with the additional value being linear. The default swing value starts the animation at a slow pace, picking up speed during the animation, and then slows down again before completion. The linear value runs the animation at one constant pace for the entire duration.

1
2
$('.error').show('slow', 'linear');
$('.error').show(500, 'linear');

jQuery UI

The two easing values that come with jQuery may be extend with the use of different plug-ins, of which may offer additional values. One of the most popular plug-ins is the jQuery UI suite.

On top of new easing values jQuery UI also provides a handful other interactions, effects, widgets, and other helpful resources worth taking a look at.

Effect Callback

When an animation is completed it is possible to run another function, called a callback function. The callback function should be placed after the duration or easing, if either exist. Inside this function new events or effects may be placed, each following their own required syntax.

$('.error').show('slow', 'linear', function(event){
  $('.error .status').text('Continue');
});

Effect Syntax

As previously mentioned, each effect method has it’s own syntax which can be found in the jQuery effects documentation. The duration, easing, and callback parameters outlined here are common, but not available on every method. It is best to review the syntax of a method should you have any questions around it.

Effects Demo

Taking the same events demo from above, the .remove() method is now used as part of a callback function on the .fadeOut() method. Using the .fadeOut() method allows for the alert message to gradually fade out rather than quickly disappearing, then be removed from the DOM after the animation is complete.

HTML
<div class="notice-warning">
  <div class="notice-close">×</div>
  <strong>Warning!</strong> Im about to lose my cool.
</div>
JavaScript
$('.notice-close').on('click', function(event){
  $('.notice-warning').fadeOut('slow', function(event){
    $(this).remove();
  });
});

Basic Effects

  • .hide()
  • .show()
  • .toggle()

Custom Effects

  • .animate()
  • .clearQueue()
  • .delay()
  • .dequeue()
  • jQuery.fx.interval
  • jQuery.fx.off
  • .queue()
  • .stop()

Fading Effects

  • .fadeIn()
  • .fadeOut()
  • .fadeTo()
  • .fadeToggle()

Sliding Effects

  • .slideDown()
  • .slideToggle()
  • .slideUp()

Slide Demo

HTML
<div class="panel">
  <div class="panel-stage"></div>
  <a href="#" class="panel-tab">Open <span></span></a>
</div>
JavaScript
$('.panel-tab').on('click', function(event){
  event.preventDefault();
  $('.panel-stage').slideToggle('slow', function(event){
    if($(this).is(':visible')){
      $('.panel-tab').html('Close <span>▲</span>');
    } else {
      $('.panel-tab').html('Open <span>▼</span>');
    }
  });
});

HTML

<ul class="tabs-nav">
  <li><a href="#tab-1">Features</a></li>
  <li><a href="#tab-2">Details</a></li>
</ul>
<div class="tabs-stage">
  <div id="tab-1">...</div>
  <div id="tab-2">...</div>
</div>
JavaScript
// Show the first tab by default
$('.tabs-stage div').hide();
$('.tabs-stage div:first').show();
$('.tabs-nav li:first').addClass('tab-active');

// Change tab class and display content
$('.tabs-nav a').on('click', function(event){
  event.preventDefault();
  $('.tabs-nav li').removeClass('tab-active');
  $(this).parent().addClass('tab-active');
  $('.tabs-stage div').hide();
  $($(this).attr('href')).show();
});

JQuery: Selecting and traversing elements in the DOM

Selecting and traversing elements in the DOM is only part of what jQuery offers, one other major part is what is possible with those elements once found. One possibility is to manipulate these elements, by either reading, adding, or changing attributes or styles. Additionally, elements may be altered in the DOM, changing their placement, removing them, adding new elements, and so forth. Overall the options to manipulate elements are fairly vast.

Getting & Setting

The manipulation methods to follow are most commonly used in one of two directives, that being getting or setting information. Getting information revolves around using a selector in addition with a method to determine what piece of information is to be retrieved. Additionally, the same selector and method may also be used to set a piece of information.

// Gets the value of the alt attribute
$('img').attr('alt');

// Sets the value of the alt attribute
$('img').attr('alt', 'Wild kangaroo');

In the examples and snippets to follow methods will primarily be used in a setting mode, however they may also be able to be used in a getting mode as well.

Attribute Manipulation

One part of elements able to be inspected and manipulated are attributes. A few options include the ability to add, remove, or change an attribute or its value. In the examples below the .addClass() method is used to add a class to all even list items, the .removeClass() method is used to remove all classes from any paragraphs, and lastly the .attr() method is used to find the value of the title attribute of any abbr element and set it to Hello World.

$('li:even').addClass('even-item');
$('p').removeClass();
$('abbr').attr('title', 'Hello World');

Attribute Manipulation Methods

  • .addClass()
  • .attr()
  • .hasClass()
  • .prop()
  • .removeAttr()
  • .removeClass()
  • .removeProp()
  • .toggleClass()
  • .val()

Style Manipulation

On top of manipulating attributes, the style of an element may also be manipulated using a variety of methods. When reading or setting the height, width, or position of an element there are a handful of special methods available, and for all other style manipulations the .css() method can handle any CSS alterations.

The .css() method in particular may be used to set one property, or many, and the syntax for each varies. To set one property, the property name and value should each be in quotations and comma separated. To set multiple properties, the properties should be nested inside of curly brackets with the property name in camel case, removing any hyphens where necessary, followed by a colon and then the quoted value. Each of the property and value pairs need to be comma separated.

The height, width, or position methods all default to using pixel values, however other units of measurement may be used. As seen below, to change the unit of measurement identify the value then use a plus sign followed by the quoted unit of measurement.

$('h1 span').css('font-size', 'normal');
$('div').css({
  fontSize: '13px', 
  background: '#f60'
});
$('header').height(200);
$('.extend').height(30 + 'em');

Style Manipulation Methods

  • .css()
  • .height()
  • .innerHeight()
  • .innerWidth()
  • .offset()
  • .outerHeight()
  • .outerWidth()
  • .position()
  • .scrollLeft()
  • .scrollTop()
  • .width()

DOM Manipulation

Lastly, we are able to inspect and manipulate the DOM, changing the placement of elements, adding and removing elements, as well as flat out altering elements. The options here are deep and varied, allowing for any potential changes to be made inside the DOM.

Each individual DOM manipulation method has it’s own syntax but a few of them are outlined below. The .prepend() method is adding a new h3 element just inside any section, the .after() method is adding a new em element just after the link, and the .text() method is replacing the text of any h1 elements with the text Hello World.

1
2
3
$('section').prepend('<h3>Featured</h3>');
$('a[target="_blank"]').after('<em>New window.</em>');
$('h1').text('Hello World');

DOM Manipulation Methods

  • .after()
  • .append()
  • .appendTo()
  • .before()
  • .clone()
  • .detach()
  • .empty()
  • .html()
  • .insertAfter()
  • .insertBefore()
  • .prepend()
  • .prependTo()
  • .remove()
  • .replaceAll()
  • .replaceWith()
  • .text()
  • .unwrap()
  • .wrap()
  • .wrapAll()
  • .wrapInner()

JQuery: Working with Selectors

As previously mentioned, one of the core concepts of jQuery is to select elements and perform an action. jQuery has done a great job of making the task of selecting and element, or elements, extremely easy by mimicking that of CSS. On top of the general CSS selectors, jQuery has support for all of the unique CSS3 selectors, which work regardless of which browser is being used.

Invoking the jQuery object, $(), containing a selector will return that DOM node to manipulate it. The selector falls within the parentheses, ('...'), and may select elements just like that of CSS.

1
2
3
4
5
$('.feature');           // Class selector
$('li strong');          // Descendant selector
$('em, i');              // Multiple selector
$('a[target="_blank"]'); // Attribute selector
$('p:nth-child(2)');     // Pseudo-class selector

This Selection Keyword

When working inside of a jQuery function you may want to select the element in which was referenced inside of the original selector. In this event the this keyword may be used to refer to the element selected in the current handler.

1
2
3
$('div').click(function(event){ 
  $(this);
});

jQuery Selection Filters

Should CSS selectors not be enough there are also custom filters built into jQuery to help out. These filters are an extension to CSS3 and provide more control over selecting an element or its relatives.

1
$('div:has(strong)');

As they stand these filters may be used inside of the selector, however not being native to the DOM they are a bit slow. The best results with using these filters is accomplished by using the :filter() method, which is part of the traversing feature in jQuery.

Traversing

At times the general CSS selectors alone don’t cut it and a little more detailed control is desired. Fortunately jQuery provides a handful of methods for traversing up and down the DOM tree, filtering and selecting elements as necessary.

To get started with filtering elements inside the DOM a general selection needs to be made, from which will be traversed from relatively. In the example below the original selection finds all of the div elements in the DOM, which are then filtered using the .not() method. With this specific method all of the div elements without a class of type or collection will be selected.

1
$('div').not('.type, .collection');

Chaining Methods

For even more control as to which elements are selected different traversing methods may be chained together simply by using a dot in-between them.

The code sample below uses both the .not() method and the .parent() method. Combined together this will only select the parent elements of div elements without a class of type or collection.

1
$('div').not('.type, .collection').parent();

Traversing Methods

jQuery has quite a few traversing methods available to use. In general, they all fall into three categories, filtering, miscellaneous traversing, and DOM tree traversing. The specific methods within each category may be seen below.

Filtering

  • .eq()
  • .filter()
  • .first()
  • .has()
  • .is()
  • .last()
  • .map()
  • .not()
  • .slice()

Miscellaneous Traversing

  • .add()
  • .andSelf()
  • .contents()
  • .end()

DOM Tree Traversal

  • .children()
  • .closest()
  • .find()
  • .next()
  • .nextAll()
  • .nextUntil()
  • .offsetParent()
  • .parent()
  • .parents()

Creating Different CSS3 Box Shadows Effects

In this tutorial we are going to be creating box shadow effects with just CSS. Below is an image created in photoshop of different box shadows effects. These used to be the only way of creating this effect but thanks to CSS3 we can now do all this with just CSS.

Web Shadows Package

CSS Box Shadow

We are going to be using the CSS box shadow property which is one my favourite CSS properties which you will see in this tutorial how easy you can use it.

The box-shadow property allows you to easily create multiple drop shadows on box elements by specifying values for colour, size, blur and offset.

The box-shadow property accepts 2-6 options, the required options are horizontal offset and vertical offset, the two optional options are spread distance and colour.

box-shadow: inset horizontal vertical blur spread colour;

Examples

box-shadow: 10px 10px;
box-shadow: 10px 10px 5px #888;
box-shadow: inset 2px 2px 2px 2px black;
box-shadow: 10px 10px #888, -10px -10px #f4f4f4, 0px 0px 5px 5px #cc6600;

Browser Support

All of the major newest browsers support box-shadow property.

  • Internet Explorer 9.0 and higher
  • Firefox 3.5 and higher
  • Chrome 1 and higher
  • Safari 3 and higher
  • Opera 10.5 and higher

With many new CSS3 properties you need to prefix the property with browser specific tags.

For firefox you need to use -moz-, for chrome/safari you need to use -webkit.

The box-shadow property is no different.

For Firefox 3.5 you need to prefix with -moz-boz-shadow, but for Firefox 4.0 and higher you don’t need to use the prefix anymore.

For Chrome/safari you still need to use the -webkit-box-shadow.

For opera you don’t need to prefix the property and can just use box-shadow.

CSS Box Shadow Effect 1

CSS Box Shadow Effects1

This will create a standard box shadow effect with the shadow moved into the element to create a raised box look.

The HTML

<div class="box effect1">
	<h3>Effect 1</h3>
</div>

The CSS

.box h3{
	text-align:center;
	position:relative;
	top:80px;
}
.box {
	width:70%;
	height:200px;
	background:#FFF;
	margin:40px auto;
}


/*==================================================
 * Effect 1
 * ===============================================*/
.effect1{
	-webkit-box-shadow: 0 10px 6px -6px #777;
	   -moz-box-shadow: 0 10px 6px -6px #777;
	        box-shadow: 0 10px 6px -6px #777;
}

CSS Box Shadow Effect 2

CSS Box Shadow Effects2

This effect will add shadows to the bottom corners of the boxes to create a lifted corner look on the boxes. This effect uses both the :before and :after properties to create new elements used for the corners.

The HTML

<div class="box effect2">
	<h3>Effect 2</h3>
</div>

The CSS

.box h3{
	text-align:center;
	position:relative;
	top:80px;
}
.box {
	width:70%;
	height:200px;
	background:#FFF;
	margin:40px auto;
}

/*==================================================
 * Effect 2
 * ===============================================*/
.effect2
{
  position: relative;
}
.effect2:before, .effect2:after
{
  z-index: -1;
  position: absolute;
  content: "";
  bottom: 15px;
  left: 10px;
  width: 50%;
  top: 80%;
  max-width:300px;
  background: #777;
  -webkit-box-shadow: 0 15px 10px #777;
  -moz-box-shadow: 0 15px 10px #777;
  box-shadow: 0 15px 10px #777;
  -webkit-transform: rotate(-3deg);
  -moz-transform: rotate(-3deg);
  -o-transform: rotate(-3deg);
  -ms-transform: rotate(-3deg);
  transform: rotate(-3deg);
}
.effect2:after
{
  -webkit-transform: rotate(3deg);
  -moz-transform: rotate(3deg);
  -o-transform: rotate(3deg);
  -ms-transform: rotate(3deg);
  transform: rotate(3deg);
  right: 10px;
  left: auto;
}

CSS Box Shadow Effect 3

CSS Box Shadow Effects3

This uses half of the effect approve and will add a lifted corner to the bottom left of the box.

The HTML

<div class="box effect3">
	<h3>Effect 3</h3>
</div>

The CSS

.box h3{
	text-align:center;
	position:relative;
	top:80px;
}
.box {
	width:70%;
	height:200px;
	background:#FFF;
	margin:40px auto;
}

/*==================================================
 * Effect 3
 * ===============================================*/
.effect3
{
  position: relative;
}
.effect3:before
{
  z-index: -1;
  position: absolute;
  content: "";
  bottom: 15px;
  left: 10px;
  width: 50%;
  top: 80%;
  max-width:300px;
  background: #777;
  -webkit-box-shadow: 0 15px 10px #777;
  -moz-box-shadow: 0 15px 10px #777;
  box-shadow: 0 15px 10px #777;
  -webkit-transform: rotate(-3deg);
  -moz-transform: rotate(-3deg);
  -o-transform: rotate(-3deg);
  -ms-transform: rotate(-3deg);
  transform: rotate(-3deg);
}

CSS Box Shadow Effect 4

CSS Box Shadow Effects4

Effect 4 will lift the corner on the bottom right of the box.

The HTML

<div class="box effect4">
	<h3>Effect 4</h3>
</div>

The CSS

.box h3{
	text-align:center;
	position:relative;
	top:80px;
}
.box {
	width:70%;
	height:200px;
	background:#FFF;
	margin:40px auto;
}

/*==================================================
 * Effect 4
 * ===============================================*/
.effect4
{
  position: relative;
}
.effect4:after
{
  z-index: -1;
  position: absolute;
  content: "";
  bottom: 15px;
  right: 10px;
  left: auto;
  width: 50%;
  top: 80%;
  max-width:300px;
  background: #777;
  -webkit-box-shadow: 0 15px 10px #777;
  -moz-box-shadow: 0 15px 10px #777;
  box-shadow: 0 15px 10px #777;
  -webkit-transform: rotate(3deg);
  -moz-transform: rotate(3deg);
  -o-transform: rotate(3deg);
  -ms-transform: rotate(3deg);
  transform: rotate(3deg);
}

CSS Box Shadow Effect 5

CSS Box Shadow Effects5

This is expands on the effect 2 and will increase the angle of the shadows.

The HTML

<div class="box effect5">
	<h3>Effect 5</h3>
</div>

The CSS

.box h3{
	text-align:center;
	position:relative;
	top:80px;
}
.box {
	width:70%;
	height:200px;
	background:#FFF;
	margin:40px auto;
}

/*==================================================
 * Effect 5
 * ===============================================*/
.effect5
{
  position: relative;
}
.effect5:before, .effect5:after
{
  z-index: -1;
  position: absolute;
  content: "";
  bottom: 25px;
  left: 10px;
  width: 50%;
  top: 80%;
  max-width:300px;
  background: #777;
  -webkit-box-shadow: 0 35px 20px #777;
  -moz-box-shadow: 0 35px 20px #777;
  box-shadow: 0 35px 20px #777;
  -webkit-transform: rotate(-8deg);
  -moz-transform: rotate(-8deg);
  -o-transform: rotate(-8deg);
  -ms-transform: rotate(-8deg);
  transform: rotate(-8deg);
}
.effect5:after
{
  -webkit-transform: rotate(8deg);
  -moz-transform: rotate(8deg);
  -o-transform: rotate(8deg);
  -ms-transform: rotate(8deg);
  transform: rotate(8deg);
  right: 10px;
  left: auto;
}

CSS Box Shadow Effect 6

CSS Box Shadow Effects6

This effect will create a curved shadow at the bottom of the box.

The HTML

<div class="box effect6">
	<h3>Effect 6</h3>
</div>

The CSS

.box h3{
	text-align:center;
	position:relative;
	top:80px;
}
.box {
	width:70%;
	height:200px;
	background:#FFF;
	margin:40px auto;
}

/*==================================================
 * Effect 6
 * ===============================================*/
.effect6
{
  	position:relative;       
    -webkit-box-shadow:0 1px 4px rgba(0, 0, 0, 0.3), 0 0 40px rgba(0, 0, 0, 0.1) inset;
       -moz-box-shadow:0 1px 4px rgba(0, 0, 0, 0.3), 0 0 40px rgba(0, 0, 0, 0.1) inset;
            box-shadow:0 1px 4px rgba(0, 0, 0, 0.3), 0 0 40px rgba(0, 0, 0, 0.1) inset;
}
.effect6:before, .effect6:after
{
	content:"";
    position:absolute; 
    z-index:-1;
    -webkit-box-shadow:0 0 20px rgba(0,0,0,0.8);
    -moz-box-shadow:0 0 20px rgba(0,0,0,0.8);
    box-shadow:0 0 20px rgba(0,0,0,0.8);
    top:50%;
    bottom:0;
    left:10px;
    right:10px;
    -moz-border-radius:100px / 10px;
    border-radius:100px / 10px;
}

CSS Box Shadow Effect 7

CSS Box Shadow Effects7

This effect uses the previous effect and adds another shadow to the top of the box.

The HTML

<div class="box effect7">
	<h3>Effect 7</h3>
</div>

The CSS

.box h3{
	text-align:center;
	position:relative;
	top:80px;
}
.box {
	width:70%;
	height:200px;
	background:#FFF;
	margin:40px auto;
}

/*==================================================
 * Effect 7
 * ===============================================*/
.effect7
{
  	position:relative;       
    -webkit-box-shadow:0 1px 4px rgba(0, 0, 0, 0.3), 0 0 40px rgba(0, 0, 0, 0.1) inset;
       -moz-box-shadow:0 1px 4px rgba(0, 0, 0, 0.3), 0 0 40px rgba(0, 0, 0, 0.1) inset;
            box-shadow:0 1px 4px rgba(0, 0, 0, 0.3), 0 0 40px rgba(0, 0, 0, 0.1) inset;
}
.effect7:before, .effect7:after
{
	content:"";
    position:absolute; 
    z-index:-1;
    -webkit-box-shadow:0 0 20px rgba(0,0,0,0.8);
    -moz-box-shadow:0 0 20px rgba(0,0,0,0.8);
    box-shadow:0 0 20px rgba(0,0,0,0.8);
    top:0;
    bottom:0;
    left:10px;
    right:10px;
    -moz-border-radius:100px / 10px;
    border-radius:100px / 10px;
} 
.effect7:after
{
	right:10px; 
    left:auto;
    -webkit-transform:skew(8deg) rotate(3deg); 
       -moz-transform:skew(8deg) rotate(3deg);     
        -ms-transform:skew(8deg) rotate(3deg);     
         -o-transform:skew(8deg) rotate(3deg); 
            transform:skew(8deg) rotate(3deg);
}

CSS Box Shadow Effect 8

CSS Box Shadow Effects8

The final effect will add rounded shadows to either side of the box.

The HTML

<div class="box effect8">
	<h3>Effect 8</h3>
</div>

The CSS

.box h3{
	text-align:center;
	position:relative;
	top:80px;
}
.box {
	width:70%;
	height:200px;
	background:#FFF;
	margin:40px auto;
}

/*==================================================
 * Effect 8
 * ===============================================*/
.effect8
{
  	position:relative;       
    -webkit-box-shadow:0 1px 4px rgba(0, 0, 0, 0.3), 0 0 40px rgba(0, 0, 0, 0.1) inset;
       -moz-box-shadow:0 1px 4px rgba(0, 0, 0, 0.3), 0 0 40px rgba(0, 0, 0, 0.1) inset;
            box-shadow:0 1px 4px rgba(0, 0, 0, 0.3), 0 0 40px rgba(0, 0, 0, 0.1) inset;
}
.effect8:before, .effect8:after
{
	content:"";
    position:absolute; 
    z-index:-1;
    -webkit-box-shadow:0 0 20px rgba(0,0,0,0.8);
    -moz-box-shadow:0 0 20px rgba(0,0,0,0.8);
    box-shadow:0 0 20px rgba(0,0,0,0.8);
    top:10px;
    bottom:10px;
    left:0;
    right:0;
    -moz-border-radius:100px / 10px;
    border-radius:100px / 10px;
} 
.effect8:after
{
	right:10px; 
    left:auto;
    -webkit-transform:skew(8deg) rotate(3deg); 
       -moz-transform:skew(8deg) rotate(3deg);     
        -ms-transform:skew(8deg) rotate(3deg);     
         -o-transform:skew(8deg) rotate(3deg); 
            transform:skew(8deg) rotate(3deg);
}

CSS Box Shadow GeneratorTo help people understand how these box shadows work, I’ve created a box shadow generator over at Coveloping. This has all the 8 different effects you see on this post and will allow you click on any of these effects to get the CSS code. Using the slider interface you can customise the look of these effects to anything you want.

Create your own CSS box shadows with this box shadow generator.

CSS Box Shadow Generator

Unix and Linux operating systems – Understanding user identifier or UID

software developer

A user identifier or UID identifies a user on Unix and Linux operating systems. This technique is exercised primarily for access to resources and thus to system security rights.

Technical specifications

The Unix-like operating systems identify users by an unsigned integer called user identifier. The range of this UID is not the same on all operating systems, most often, it is a 15-bit integer in the range of 0 to 32767, with the following restrictions:

The root user has UID 0.

Traditionally no user gets the largest possible value: 32767. More recently, operating systems have assigned other values ​​in the 1-100 range or in the 65530-65535 range (double-byte value, instead of only 15 bits).

For some operating systems, a portion of the UID range is restricted to particular uses of the system. For Debian, it is the UID of 500 to 9991, Red Hat applies the range 101-499.

UIDs are referenced in the / etc / passwd file that lists users and / etc / shadow (which lists in encrypted form passwords of users). More rarely, computers exploit the Network Information Service (NIS) which is also based on the UID.

Comparison with Windows

RID (Relative ID) of a user on Windows is equivalent to UID in Unix.

In Unix- like operating systems, users are identified by user IDs (UID).

Operating system distinguishes users precisely on UID (and not, for example, login). In many systems, it is possible to create two accounts with different user names , but the same UID; due to both the login will have the same rights from a system perspective, they are indistinguishable ( as they have the same UID).

It can be used by hackers: penetrating into the system and getting the right root, an attacker can create a user account with UID = 0, and returns to the system for login, not to attract attention but getting the right root.

Set of allowed values ​​depend on the UID system, in general, it permits the use of UID values ​​from 0 to 65535, with some caveats:

  •     Superuser should always have UID, zero (0).
  •    Normally no user is assigned the largest possible UID (as opposed to the superuser.
  •    UIDs from 1 to 100 are reserved by convention for system usage and some guidelines recommend for reserving UIDs 101 to 499 (Red Hat) or 999 (in Debian).

UID value is assigned to the user in the file / etc / passwd. Shadow password files and Network Information Service also use numeric UIDs . The user ID of the owner is a necessary attribute of the file Unix file system and processes.

Some operating systems can support 16-bit UIDs , which makes it possible to create 65,536 unique identifiers , although modern systems that support 32-bit UIDs can be 4,294,967,296 ( 232) different values ​​of the identifiers.

Characteristics of a web form

facebook-autoplay-video-commercials

A web form on a web page is a form for collecting data to be sent for processing by a web server. They can be found for example in webmail applications, account registration pages, search input fields, in social networks or on login pages. The sending of the data runs via the Hypertext Transfer Protocol via HTTP GET, HTTP POST, or the XMLHttpRequest (Ajax).

In computing, a web form is a term used to describe the interface of the client application that allows the user to enter and send to the web server data or that may be useful to describe the metaphor of form to fill in for data entry.

Possible selection fields

The following input fields are provided in the HTML 4 standard:

  • Single-line text input field
  • Password field (input is masked on the screen)
  • Multi-line text input field (text area)
  • Select lists (drop down list)
  • Radio buttons (select one option from several)
  • Checkboxes (multiple selections)
  • Fields for file upload
  • Hidden form fields (for example, session IDs)
  • Click buttons, this includes the confirmation button (submit) or a button to reset all entries

HTML5 allows other types of input fields, which often differ from the single-line input field only by their semantics:

  • phone numbers
  • E -mail addresses
  • Range selection (range slider )
  • date Picker
  • Combo boxes
  • Advanced widgets

By using client-side technologies such as JavaScript, many web frameworks include advanced input options. These include widgets such as sliders, calendar boxes, combo boxes, or drag and drop fields.

The following web frameworks and standards are available for this purpose:

  • FormEngine – specialized form framework for easy implementation on an application server
  • Dojo Toolkit – JavaScript framework for developing applications JavaScript-/Ajax.
  • jQuery UI – JavaScript framework for expanding functions of the user interface based on jQuery
  • Apache Wicket – web framework as a basis for the development of Web applications on an application server
  • JavaServer Faces – web framework as a basis for the development of Web applications on an application server

Use

In addition to search engines and webmail there are the online shops that offer forms for the correction of address and account information. Also, web forms for subscription to newsletters, for the personalization or uploading files can be used.

Forms can be used to perform communication without an indication of an e-mail address. This spam can be barred, for example, by CAPTCHAs. In principle, any page that displays a radio, checkbox or button element, a web form.

In most cases, the term refers to the form contained in a web page, for example the text boxes and drop down to a registration page or login constitute a form.

Description

More specifically, the HTML element <FORM> is used to create forms on a web page. Usually the form is used to send data to a database server, or to send e-mail.

It is an element that fits interactive content for the user in a web page or web application then inserting in the context of dynamic web. All form data once sent from the web client’s browser to the web server should be handled / processed specially by a dynamic web page server side.

The term is used in the broadest sense , in the Visual Basic to indicate the main application window , which can be inserted visual elements such as buttons and text boxes.