Skip to content

Textareas and dynamic direction

Handle Arabic and English textarea paragraphs, preserve editing and direction choices, and render saved notes with matching paragraph behavior.

By , Founder of Ritla

Guide13 min read

A bilingual note can look correct in its textarea and wrong immediately after saving. The Arabic paragraph still reads normally, but the next English paragraph starts from the wrong edge or leaves its final punctuation at the other end. The text has not changed. The rendering context has.

Treat editing, storage and display as separate parts of the same feature. A textarea with automatic direction can handle paragraphs independently. An ordinary preview container with dir="auto" is not automatically an equivalent renderer. Saving one direction string also does not describe every paragraph in a bilingual note.

This guide uses a theatre's scenery handover notes. Staff write Arabic instructions and sometimes add an English instruction for a visiting crew. The interface remains Arabic while the note can contain either language, multiple paragraphs and blank lines.

Start with the direction policy for the note#

A field intended only for Arabic notes can use fixed RTL direction. A field for imported English instructions may have a fixed LTR requirement. For the handover composer, which accepts either language and bilingual notes, automatic direction is the appropriate starting point.

html
<form id="handover-form" lang="ar" dir="rtl" method="post">  <label for="handover-note">ملاحظات تسليم الديكور</label>  <textarea id="handover-note" name="handoverNote" dir="auto"            dirname="handoverDirection" rows="7" wrap="soft"            aria-describedby="handover-help"></textarea>  <p id="handover-help">اكتب التعليمات، وافصل بينها بأسطر جديدة عند الحاجة.</p>  <button type="submit">حفظ الملاحظات</button></form>

This form posts to its current route, which must implement saving and restoring the note. The label and help remain Arabic regardless of the note's direction. dirname adds direction information to submission; it is not a command that changes the textarea's direction.

Compare this with forcing every note to RTL because the surrounding interface is Arabic. English letters can still display within that base direction, but punctuation, paragraph alignment and editing expectations can differ from those of an LTR paragraph. Direction is more than whether the letters themselves are legible.

Likewise, a fixed LTR reset on the textarea conflicts with a field that expects Arabic content. Remove that reset before building JavaScript to compensate. lang="ar" describes language; it does not replace dir. MDN's dir reference explains the distinction and explicitly describes automatic direction for textarea paragraphs.

Automatic direction is not one language decision for the whole note#

Use this note as a fixture:

text
أعدت الستائر إلى المخزن.Keep the side entrance clear.

For a textarea with dir="auto", paragraph direction is determined separately. The Arabic paragraph and English paragraph need not share one base direction. HTML's rendering rules for bidirectional text specify unicode-bidi: plaintext for automatic-direction textareas. A global CSS reset that replaces that behavior can therefore break an otherwise suitable dir declaration.

Inspect both the attribute and computed unicode-bidi when debugging. Seeing dir="auto" in the markup is not proof that later styles have left the intended paragraph rendering intact. A rule forcing text-align: right can also conceal the difference between paragraph directions by aligning every line to one physical edge.

The element still has an overall direction used by other behavior. Do not interpret its computed direction as a list of the directions chosen for its paragraphs. One computed value cannot describe an Arabic paragraph followed by an English one.

Automatic direction is a first-strong-character heuristic, not language identification. A paragraph that begins with an English crew name and continues in Arabic can take an LTR base direction. Punctuation and digits before the first strong letter do not establish an Arabic or English language. Test the note shapes your staff actually write rather than treating the heuristic as an editor's understanding of their intent.

The supplied browser measurements used Chromium 151 on September 24, 2026; Firefox and Safari were not measured. Where this guide describes paragraph behavior from a standard, verify the corresponding editing and display behavior in the browsers you support.

Avoid replacing paragraph behavior with a whole-note detector#

A script that counts Arabic and Latin letters and sets one dir value on the textarea implements a different rule from native automatic direction. A mostly Arabic note can still contain a complete English instruction that needs its own paragraph direction. Winning the character count does not make that instruction an Arabic paragraph.

Checking whether the note contains any English letter has the same problem. One crew name can change the selected mode for the entire note. The defect becomes more apparent when staff paste an English instruction above an existing Arabic paragraph: the script changes every paragraph's policy in response to a local edit.

Use native automatic direction when its paragraph behavior matches the task. Add an explicit override for author intent rather than repeatedly setting a fixed direction inferred by application code. If an imported record includes an explicit direction choice, restore that choice instead of immediately replacing it with a fresh guess.

Keep any inference needed for another purpose separate. Search indexing, language identification or selecting a spelling dictionary may need additional processing, but their output is not automatically a direction instruction for the editor. A language detector reporting Arabic does not establish the intended base direction of every paragraph in the record.

Distinguish a new paragraph from a wrapped line#

A textarea can show several visual lines without containing several bidi paragraphs. Narrowing the control causes soft wrapping; it does not insert a new direction boundary into the stored note.

For the fixture above, the actual newline separates the two instructions. If the Arabic instruction merely wraps because the textarea becomes narrow, the wrapped continuation remains part of its paragraph. Do not run direction detection on each line of a screenshot or on the width-dependent lines produced by a measurement helper.

Keep the note's logical line breaks separate from its visual wrapping. MDN's textarea reference distinguishes wrap="soft" from hard wrapping for submission. The example uses soft wrapping so the control does not add line breaks merely to fit its visible width. Transport line-ending normalization still needs to be distinguished from preserving the same visible paragraph structure.

This difference becomes visible when saved notes are reopened on a wider screen. If application code stored its calculated visual lines as newlines, the note can acquire artificial paragraphs and different direction boundaries. A responsive layout change has then changed the content.

Blank lines deserve a fixture too. An empty paragraph has no strong letter from which to infer direction. CSS Text's rules for plaintext alignment describe how line alignment can use preceding context or the containing block for lines without strong directionality. Do not insert invisible direction characters merely to make a blank line's caret resemble the previous screenshot. Test the intended typing transition by adding Arabic and English text after that line.

Reproduce paragraph behavior in the preview#

This preview looks like a reasonable equivalent to the textarea:

html
<!-- Incomplete for a note whose paragraphs need independent direction. --><div id="handover-preview" dir="auto"></div>

If the application inserts the complete note into that ordinary container, automatic element direction alone does not promise the textarea's per-paragraph behavior. Collapsed whitespace can also hide the original newlines, making two instructions look like one paragraph.

Keep the container and apply an explicit plain-text rendering policy:

css
#handover-preview {  white-space: pre-wrap;  unicode-bidi: plaintext;  text-align: start;  overflow-wrap: anywhere;}
js
const noteEditor = document.querySelector("#handover-note");const notePreview = document.querySelector("#handover-preview"); function updateHandoverPreview() {  notePreview.textContent = noteEditor.value;} noteEditor.addEventListener("input", updateHandoverPreview);updateHandoverPreview();

white-space: pre-wrap preserves the note's line breaks while permitting wrapping. unicode-bidi: plaintext lets bidi paragraphs establish their own base directions. text-align: start avoids forcing every paragraph to one physical side. These are separate responsibilities; preserving newlines does not by itself establish paragraph direction. MDN documents white-space and unicode-bidi.

The script inserts the note through textContent, so typed markup remains text. Do not switch to innerHTML to preserve newlines. That changes how user content is interpreted and still does not define the intended bidi paragraph policy.

This preview is for the automatic mode. If the product offers an explicit whole-note direction, the preview must follow that mode too. Leaving plaintext enabled while promising that a manual direction controls every paragraph would implement a different policy from the one the user chose.

Do not insert the note's label or a translated status into the same text node to save a wrapper. The preview represents authored content; the label belongs outside it. Mixing interface text with the first note paragraph changes the content from which automatic direction is determined and makes copying the note include text the author never entered.

For a renderer that already creates separate paragraph elements, apply the direction policy to those content blocks deliberately. Automatic direction on each paragraph can express an automatic per-block policy, while explicit whole-note modes should reach the blocks without contradictory local overrides. Preserve blank-line meaning according to the renderer's data model rather than assuming that dropping empty strings during splitting is harmless.

Do not treat a textarea as interchangeable with a rich-text editor. A rich editor can store paragraph nodes, language spans and explicit formatting; the textarea stores a string plus any separate metadata you define. If another screen converts between those models, test that conversion with both paragraph orders and a manual direction choice. The display can be correct before conversion and still lose the author's choice when converted back to plain text.

Store the note, its chosen mode and any resolved direction separately#

There are three different values to consider: the note text, a user's selected direction mode and the element direction resolved at submission time. Do not use one database field to stand for all three.

The example textarea's dirname="handoverDirection" causes a direction entry to accompany handoverNote in ordinary form submission. MDN's dirname reference describes this extra field and its ltr or rtl value.

That value is not a per-paragraph map. It also does not tell the server whether the person selected automatic direction or explicitly chose the same resolved direction. If the product needs to restore that choice, submit and persist the mode separately, using a defined set such as auto, ltr and rtl.

For a note that begins in Arabic and continues in English, storing only rtl and replaying the whole saved text with fixed RTL direction can lose the composer's paragraph behavior. Persisting the original mode lets the renderer reproduce the agreed policy rather than guessing from a resolved snapshot.

Validate submitted direction values against the accepted set. An unknown value should fall back to the product's documented default, not become arbitrary style or markup. If a JavaScript request replaces native form submission, explicitly include the metadata your save contract requires; adding dirname to the HTML does not automatically populate an independently constructed JSON object.

Keep direction metadata out of the text string itself. Prefixing hidden marks to saved notes makes copy, export, search and length handling operate on characters the author did not type. Use the field's direction or display policy for the presentation problem you actually need to solve.

Offer an explicit override when the heuristic is insufficient#

Automatic direction can be suitable for the default without being suitable for every paragraph an author intends. A note starting with an English title and then continuing mainly in Arabic can warrant an explicit choice.

For a product that supports a whole-note override, add this selector inside the form:

html
<label for="handover-mode">اتجاه الملاحظات</label><select id="handover-mode" name="handoverMode">  <option value="auto">تلقائي</option>  <option value="rtl">من اليمين إلى اليسار</option>  <option value="ltr">من اليسار إلى اليمين</option></select>

With the preview script above installed, this additional script updates both surfaces:

js
const modeSelector = document.querySelector("#handover-mode"); function applyHandoverMode() {  const allowedModes = new Set(["auto", "ltr", "rtl"]);  const mode = allowedModes.has(modeSelector.value)    ? modeSelector.value    : "auto";   noteEditor.dir = mode;  notePreview.dir = mode;  notePreview.style.unicodeBidi = mode === "auto" ? "plaintext" : "isolate";  updateHandoverPreview();} modeSelector.addEventListener("change", applyHandoverMode);applyHandoverMode();

The first script defines noteEditor, notePreview and updateHandoverPreview. This script changes the direction policy, not the characters. In automatic mode the preview uses paragraph-sensitive plaintext behavior; in an explicit mode it uses the selected base direction with isolation. Strong Arabic and Latin runs still retain their intrinsic behavior. This is not a bidi override that forces every character into one direction.

Describe the scope of this setting. A whole-note selector is not a per-paragraph formatting toolbar. If authors need independent manual choices for individual paragraphs, the product needs a structured editing model rather than pretending a single textarea direction value stores that structure.

Preserve editing state when direction changes#

Do not implement dynamic direction by reversing the string, inserting markup into the textarea value or replacing the editor node on every input event. The native control already maintains editable text. The application should not destroy its editing state merely to change presentation.

Test the override while a selection spans Arabic and English content. Confirm that the selected logical text remains the intended text, then continue typing in the middle of a paragraph. Also check undo, redo and scrolling through a note longer than the visible control. A direction toggle that only works with the caret at the end has not passed an editing test.

For diagnostics, selectionStart and the corresponding selection end describe positions in the control's text, not a pair of screen coordinates. Do not infer those positions by counting visually reordered glyphs. If the application has text-insertion tools, use the editing APIs it supports; setRangeText() provides a native way to replace a selected range with an explicit selection policy.

Respect composition sessions. InputEvent.isComposing identifies input events during composition, which matters for any logic that would rewrite or finalize content. Arabic keyboard input does not imply one universal composition sequence. Test the keyboards in your support scope, including touch input and mixed-script pasting.

Enter belongs to multiline editing unless the composer deliberately documents another shortcut. Do not copy a single-line search field's unconditional submit-on-Enter handler into the handover textarea. Authors need a way to create the paragraphs on which this direction policy depends.

Restore drafts through the same rendering policy#

A draft restored from storage is another entry path. It should receive the same mode and preview policy as a newly typed note. Testing only typing can miss a draft that reopens with fixed direction or a preview that stays empty until the next keystroke.

Set the saved text on the existing control, restore the saved mode and refresh the preview. Programmatic assignment to .value does not dispatch the user-editing input event. Call the relevant application update function instead of waiting for an event that will not arrive.

In this example, restoring the textarea and mode selector before calling applyHandoverMode() refreshes the policy and preview together. In a controlled framework component, restore the framework's state rather than assigning the DOM value behind its back. Keep the editor's state model as the source of truth for saving.

Check reset separately from restore. A form reset can restore initial text and selector values, but application-owned previews and stored metadata still need synchronization. Decide whether reset means returning to the original note or starting a blank note; do not let browser defaults and application state silently implement different meanings.

Also guard against delayed draft responses. If a saved draft finishes loading after the author has begun a new note, blindly applying it can overwrite their work and change direction mid-edit. Tie the restore operation to the draft and editing state it was requested for.

Keep the editor usable beyond its first line#

Direction should not change the Arabic label, save button or surrounding help into the note's language or order. Put automatic direction on the content boundary rather than on the whole form. A note beginning in English does not make the interface English.

Keep the placeholder supplementary. An empty field has no strong content with which to select paragraph direction, so test the empty textarea directly rather than borrowing the alignment you observed after typing. Do not apply a permanent physical alignment solely to make a placeholder screenshot look right; it can force English paragraphs to the wrong edge later.

Give the textarea enough block size for reviewing several instructions, and preserve a usable resize or scrolling path. Test Arabic marks at the chosen font size and line height, particularly after a CSS reset. For clipping and line-box problems, Arabic text getting cut off in CSS provides a focused debugging path.

Avoid auto-growing implementations that measure a hidden LTR clone with different fonts, padding or whitespace rules. If the composer calculates its own height, compare its measurement context with the real textarea and test mixed paragraphs, blank lines and a long unbroken reference. A correct direction attribute cannot repair an incorrect height calculation.

A textarea is not an inline markup editor#

Paragraph direction does not solve every mixed token inside a paragraph. An instruction can contain an English equipment name or an identifier whose grouping matters. Plain textarea content cannot include a real bdi element around that token; typing those tags creates characters in the note.

Keep the raw note as raw text. If the saved display recognizes structured references, create the corresponding value nodes during rendering, with their own boundaries. Do not modify the author's stored string just because a display renderer supports richer markup. Bidi isolation covers those inline boundaries.

Likewise, unicode-bidi: plaintext does not mean the content is sanitized, translated or language-labelled. It sets a paragraph-direction behavior. The preview still needs text insertion rather than HTML interpretation, and known language runs may need language information in a richer display model. Keep those responsibilities separate from the direction toggle.

The form's Arabic language declaration also does not prove that an English instruction should be spell-checked or pronounced as Arabic. Where the product knows a note's language, handle that language information separately from dir. Do not set lang="en" merely because automatic direction resolved LTR: other languages use that direction too. For bilingual content whose individual language runs are not known, avoid pretending the direction heuristic supplied that missing metadata.

Test the edit-save-reopen cycle#

Use notes that distinguish policies, not just a short Arabic sentence. Start with the two-instruction fixture, then reverse the paragraph order. Add a blank line, insert an English name before the Arabic instruction and narrow the editor until a paragraph wraps.

State or transitionWhat to verify
Arabic followed by English paragraphsEach paragraph receives the intended base direction
English followed by Arabic paragraphsThe first paragraph does not dictate every later paragraph
Soft wrapping at a narrow widthStored text gains no artificial paragraph breaks
Empty line between instructionsTyping the next paragraph works without inserted control characters
Change direction with text selectedThe text remains unchanged and editing continues
Save, reopen and restore a draftText, mode and preview policy agree
Reset after editingThe editor and preview return to the defined state together
Late draft response during a new editExisting work is not silently overwritten

Inspect attributes and computed styles, but judge paragraph behavior with the actual content on screen. A single computed direction does not establish that every paragraph aligns correctly. Compare the preview with the textarea and then reopen the saved record to exercise the full path.

Check the payload too: note text, selected mode and any resolved direction must have the meanings the receiving service expects. Copying text can confirm logical content preservation, but it cannot by itself prove visual order or punctuation placement. Include keyboard editing and your supported touch browsers in the same review.

A free Ritla scan can report R023: Text inputs rendered LTR where Arabic input is expected. Review bilingual paragraphs and the saved preview directly as well; CSS unicode-bidi explained is the next step when the textarea and display disagree about paragraph boundaries.

Checks in this guide

See what your Arabic pages are hiding

Paste a URL. Ritla renders the page on desktop and mobile, runs every check, and shows the top issues with screenshot evidence.

Scan a page freeBrowse the checks