Example: Physical vs logical properties comparison
/* Physical properties (fixed to screen directions) */.physical { width: 300px; height: 200px; margin-top: 20px; margin-right: 10px; margin-bottom: 20px; margin-left: 10px; padding-left: 15px; border-right: 2px solid blue;}/* Logical properties (adapt to writing mode) */.logical { inline-size: 300px; /* Width in horizontal, height in vertical */ block-size: 200px; /* Height in horizontal, width in vertical */ margin-block-start: 20px; /* Top in horizontal */ margin-inline-end: 10px; /* Right in LTR, left in RTL */ margin-block-end: 20px; /* Bottom in horizontal */ margin-inline-start: 10px; /* Left in LTR, right in RTL */ padding-inline-start: 15px; /* Left padding in LTR */ border-inline-end: 2px solid blue; /* Right border in LTR */}/* Shorthand logical properties */.logical-shorthand { margin-block: 20px; /* margin-block-start and margin-block-end */ margin-inline: 10px; /* margin-inline-start and margin-inline-end */ padding-block: 15px 10px; /* start end */ padding-inline: 20px 15px; /* start end */ border-block: 2px solid red; /* Both block borders */ border-inline: 1px solid blue; /* Both inline borders */}/* Benefits: Works automatically with RTL/vertical */[dir="rtl"] .logical { /* No changes needed! margin-inline-start automatically becomes right */}.vertical { writing-mode: vertical-rl; /* Logical properties automatically adapt */}
Example: Migration from physical to logical
/* Old: Physical properties */.card-old { width: 100%; max-width: 600px; margin-left: auto; margin-right: auto; padding-left: 20px; padding-right: 20px; border-left: 4px solid blue; text-align: left;}/* New: Logical properties */.card-new { inline-size: 100%; max-inline-size: 600px; margin-inline: auto; /* Centers in both LTR and RTL */ padding-inline: 20px; /* Horizontal padding */ border-inline-start: 4px solid blue; /* Left in LTR, right in RTL */ text-align: start; /* Left in LTR, right in RTL */}/* Positioning with logical properties */.positioned-old { position: absolute; top: 0; right: 0;}.positioned-new { position: absolute; inset-block-start: 0; /* Top */ inset-inline-end: 0; /* Right in LTR, left in RTL */}/* Shorthand inset */.overlay { position: fixed; inset: 0; /* All four sides (works with any writing mode) */}/* Specific inset values */.positioned-complex { inset-block: 20px 10px; /* top bottom */ inset-inline: 30px 15px; /* left right (in LTR) */}
Note: Logical properties are essential for internationalization.
They automatically adapt to different writing modes and text directions. Use logical properties by default for
new projects. Browser support: all modern browsers (Chrome 87+, Firefox 66+, Safari 12.1+).
2. Block and Inline Directions
Axis
Description
Horizontal LTR/RTL
Vertical RL/LR
Block Axis
Direction that blocks stack (paragraphs, divs)
Top to bottom (vertical)
Right to left or left to right (horizontal)
Inline Axis
Direction text flows within a line
Left to right or right to left (horizontal)
Top to bottom (vertical)
Block Start
Beginning of block axis
Top edge
Right edge (vertical-rl) or left edge (vertical-lr)
Block End
End of block axis
Bottom edge
Left edge (vertical-rl) or right edge (vertical-lr)
Inline Start
Beginning of inline axis
Left (LTR) or right (RTL)
Top edge
Inline End
End of inline axis
Right (LTR) or left (RTL)
Bottom edge
Example: Understanding block and inline axes
/* Horizontal writing mode (default) */.horizontal { writing-mode: horizontal-tb; /* Block axis: top → bottom (paragraphs stack vertically) Inline axis: left → right (text flows horizontally) */}.horizontal-element { margin-block: 20px; /* Top and bottom margins */ margin-inline: 10px; /* Left and right margins (in LTR) */ padding-block: 15px; /* Top and bottom padding */ padding-inline: 20px; /* Left and right padding (in LTR) */}/* Vertical writing mode */.vertical-rl { writing-mode: vertical-rl; /* Block axis: right → left (paragraphs stack from right) Inline axis: top → bottom (text flows downward) */}.vertical-element { margin-block: 20px; /* Right and left margins (stacking direction) */ margin-inline: 10px; /* Top and bottom margins (text flow) */ inline-size: 200px; /* Height (inline = vertical) */ block-size: 300px; /* Width (block = horizontal) */}/* RTL (Right-to-Left) */.rtl { direction: rtl; /* Block axis: still top → bottom Inline axis: right → left (text flows from right) */}.rtl-element { margin-inline-start: 20px; /* Right margin in RTL */ margin-inline-end: 10px; /* Left margin in RTL */ text-align: start; /* Aligns right in RTL */}/* Practical example: Sidebar layout */.sidebar { inline-size: 250px; /* Width (adapts to writing mode) */ padding-inline-start: 20px; /* Left padding in LTR */ border-inline-end: 1px solid #ccc; /* Right border in LTR */}/* This automatically works in RTL */[dir="rtl"] .sidebar { /* No changes needed! Properties flip automatically */ /* padding-inline-start becomes right padding */ /* border-inline-end becomes left border */}
Example: Flexbox and Grid with logical properties
/* Flexbox with logical directions */.flex-container { display: flex; flex-direction: row; /* Inline direction */ gap: 1rem; padding-inline: 2rem; /* Horizontal padding */ padding-block: 1rem; /* Vertical padding */}.flex-item { margin-inline-end: 1rem; /* Space after each item */ padding-block: 0.5rem;}/* Grid with logical alignment */.grid-container { display: grid; grid-template-columns: repeat(3, 1fr); gap: 2rem; align-items: start; /* Block-start alignment */ justify-items: start; /* Inline-start alignment */}.grid-item { inline-size: 100%; margin-block-end: 1rem;}/* Text alignment with logical values */.text-content { text-align: start; /* Left in LTR, right in RTL */ margin-inline: auto; /* Center horizontally */ max-inline-size: 65ch; /* Max width for reading */}.text-end { text-align: end; /* Right in LTR, left in RTL */}/* Float with logical properties */.float-start { float: inline-start; /* float: left in LTR, right in RTL */ margin-inline-end: 1rem; /* Space after floated element */ margin-block-end: 0.5rem;}.float-end { float: inline-end; /* float: right in LTR, left in RTL */ margin-inline-start: 1rem; /* Space before floated element */}/* Clear with logical values */.clear-both { clear: both; /* Still works */}.clear-inline-start { clear: inline-start; /* Clear left in LTR */}
Note:Block axis = direction elements stack (usually vertical).
Inline axis = direction text flows (usually horizontal). In vertical writing
modes, these axes rotate. Logical properties use start/end instead of left/right/top/bottom.
Warning:direction: rtl should usually be set via HTML dir attribute,
not CSS, for better semantics and accessibility. Use unicode-bidi: isolate for embedding
opposite-direction text. text-orientation: sideways has limited browser support.
4. International Layout Support
Feature
Technique
Description
Example
HTML dir attribute
<html dir="rtl">
Set document text direction
Better than CSS direction for semantics
Logical properties
Use start/end instead of left/right
Automatic adaptation to text direction
margin-inline-start vs margin-left
CSS :dir() pseudo-class
:dir(rtl) or :dir(ltr)
Target elements by text direction
More semantic than [dir="rtl"]
lang attribute
<html lang="ar">
Specify content language
CSS can target: :lang(ar)
Font selection
Language-specific fonts
Different fonts for different scripts
Arabic, CJK, Latin fonts
Line breaking
word-break, line-break
Language-appropriate line breaks
Different rules for CJK vs Latin
Text spacing
letter-spacing, word-spacing
Avoid in Arabic (ligatures)
Can break connected scripts
Quotation marks
quotes property
Language-specific quote characters
Different for each language
Example: Multi-language support with logical properties
<!-- HTML structure for multi-language --><!-- <html lang="en" dir="ltr"> --><!-- <html lang="ar" dir="rtl"> -->/* Base styles with logical properties */body { margin: 0; padding-inline: 2rem; padding-block: 1rem;}.container { max-inline-size: 1200px; margin-inline: auto;}/* Navigation that works in any direction */.nav { display: flex; gap: 1rem; padding-inline: 2rem;}.nav-link { padding-inline: 1rem; padding-block: 0.5rem; border-inline-start: 3px solid transparent;}.nav-link:hover { border-inline-start-color: blue;}/* Cards with logical spacing */.card { padding-block: 1.5rem; padding-inline: 2rem; border-inline-start: 4px solid blue; margin-block-end: 2rem;}.card-title { margin-block-end: 0.5rem;}/* Sidebar positioning */.layout { display: grid; grid-template-columns: 250px 1fr; gap: 2rem;}/* Automatically flips in RTL */.sidebar { padding-inline-end: 2rem; border-inline-end: 1px solid #ccc;}/* Text alignment */.text-content { text-align: start; /* Left in LTR, right in RTL */}.text-end-align { text-align: end; /* Right in LTR, left in RTL */}/* Form inputs */.form-field { margin-block-end: 1rem;}.form-label { display: block; margin-block-end: 0.25rem; text-align: start;}.form-input { inline-size: 100%; padding-block: 0.5rem; padding-inline: 0.75rem; border: 1px solid #ccc; text-align: start;}
Example: Language-specific styling
/* Using :dir() pseudo-class (modern browsers) */:dir(ltr) .arrow { transform: rotate(0deg); /* → */}:dir(rtl) .arrow { transform: rotate(180deg); /* ← */}/* Using :lang() for language-specific styles */:lang(ar) { font-family: 'Arabic Font', sans-serif; font-size: 1.1em; /* Arabic often needs larger size */ line-height: 1.8; /* More line height for Arabic */}:lang(zh) { font-family: 'Noto Sans SC', sans-serif; /* Simplified Chinese */ word-break: break-all; /* CJK line breaking */}:lang(ja) { font-family: 'Noto Sans JP', sans-serif; line-break: strict; /* Japanese line breaking rules */}:lang(en) { font-family: -apple-system, BlinkMacSystemFont, sans-serif; hyphens: auto; /* English hyphenation */}/* Quotation marks by language */:lang(en) { quotes: '"' '"' ''' '''; /* "English" 'quotes' */}:lang(fr) { quotes: '«\00a0' '\00a0»' '"' '"'; /* « French » "quotes" */}:lang(de) { quotes: '„' '"' '‚' '''; /* „German" ‚quotes' */}/* Blockquote with auto quotes */blockquote::before { content: open-quote;}blockquote::after { content: close-quote;}/* Font stack for multi-script support */body { font-family: -apple-system, /* System font (Latin) */ 'Noto Sans Arabic', /* Arabic */ 'Noto Sans SC', /* Simplified Chinese */ 'Noto Sans JP', /* Japanese */ 'Noto Sans KR', /* Korean */ sans-serif;}/* Avoid letter-spacing in connected scripts */.text { letter-spacing: 0.02em;}:lang(ar) .text,:lang(fa) .text,:lang(ur) .text { letter-spacing: normal; /* Preserve ligatures */}/* Number formatting */.number { font-variant-numeric: tabular-nums;}:lang(ar) .number { /* Arabic numerals */ font-feature-settings: 'anum' 1;}
Note: Use dir attribute in HTML: <html dir="rtl">. Combine with
lang attribute: <html lang="ar" dir="rtl">. Test with actual native speakers.
Use logical properties exclusively for international support.