Modern CSS (2025–2026)Extra· 35 min read

Logical Properties & Modern Color

Write direction-aware spacing that works in any language, and reach for perceptual colour functions like color-mix() and oklch() that power modern design systems.

What you will learn

  • Use logical properties like margin-inline and padding-block
  • Understand why they help internationalisation
  • Mix and tweak colours with color-mix() and oklch()

The problem with top / right / bottom / left

Properties like margin-left and padding-right are physical — they always mean the same fixed side of the screen. That breaks for languages written right-to-left (like Arabic or Urdu), where “the start of the text” is on the right, not the left. You would have to rewrite every left/right value for those layouts.

Logical properties fix this by talking about start and end instead of left and right. They follow the reading direction automatically. The two key words are:

  • inline — the direction text flows (left-to-right in English; right-to-left in Arabic).
  • block — the direction lines stack (top to bottom).
Physical (old)Logical (new)Means
margin-left / margin-rightmargin-inlineSpace at the start and end of the text flow
margin-top / margin-bottommargin-blockSpace above and below
padding-leftpadding-inline-startInner space at the text’s starting edge
left / right / top / bottominset-inline / inset-blockPositioning offsets, direction-aware

Logical properties in action

Below, the same card is shown in a left-to-right and a right-to-left context. Because it uses padding-inline and a logical border, the “start edge” accent automatically flips to the correct side — with no extra CSS:

Logical properties flip with reading direction
<style>
  .note {
    padding-block: 10px;            /* top + bottom */
    padding-inline: 16px;           /* start + end (L/R, direction-aware) */
    border-inline-start: 4px solid #4338ca;  /* accent on the START edge */
    background: #eef2ff; border-radius: 8px; margin-block-end: 12px;
  }
</style>

<div class="note">Left-to-right: the indigo accent is on the left (the start).</div>
<div class="note" dir="rtl">دائیں سے بائیں: لہجہ اب دائیں طرف ہے۔</div>
Live preview

Both boxes use the exact same CSS, yet the accent bar appears on opposite sides. That is the whole point:

  • padding-block sets top + bottom; padding-inline sets the two text-flow sides at once.
  • border-inline-start draws the accent on the start edge. In the English box, “start” is the left; in the dir="rtl" box, “start” becomes the right — so the accent flips automatically.
  • With old physical properties you would have needed a second rule (border-right) just for the RTL version. Logical properties remove that duplication entirely.

Note: Output: The first note has its indigo accent bar on the left; the second note (set to right-to-left) shows the same accent on the right — without any extra CSS, because the border was defined on the logical “start” edge.

Modern colour: color-mix() and oklch()

You already know HEX, RGB and HSL. Modern CSS adds colour functions that design systems lean on. The two most useful:

  • color-mix(in oklch, A 70%, B)blends two colours. Great for generating a hover shade from a base colour without hard-coding a second value.
  • oklch(L C H) — a perceptual colour space: L is lightness, C is how vivid it is, H is the hue angle. Its big advantage is that equal lightness numbers actually *look* equally bright, which makes building consistent palettes far easier than with HSL.
Mixing and choosing colours the modern way
<style>
  :root { --brand: #4338ca; }
  .base  { background: var(--brand); }
  /* Auto-generate a darker hover shade by mixing in 25% black */
  .hover { background: color-mix(in oklch, var(--brand) 75%, black); }
  /* Pick a colour directly in the perceptual oklch space */
  .ok    { background: oklch(70% 0.15 250); }
  .swatch { color:#fff; padding:14px; border-radius:8px; margin-bottom:8px; font-family:sans-serif; }
</style>

<div class="swatch base">Base brand colour</div>
<div class="swatch hover">color-mix() → 25% darker (a ready hover shade)</div>
<div class="swatch ok">oklch(70% 0.15 250)</div>
Live preview

Each swatch shows a modern colour technique:

  • color-mix(in oklch, var(--brand) 75%, black) — takes the brand colour at 75% strength and blends in 25% black, producing a slightly darker version. This is the trick for deriving a hover shade from one source colour instead of maintaining two.
  • oklch(70% 0.15 250) — names a colour by lightness 70%, chroma 0.15, hue 250° (a blue). Because lightness is perceptual, you can build a whole palette by nudging just the lightness number and the colours stay visually balanced.

Tip: A powerful pattern for design systems: store one --brand variable, then derive hover, active and disabled shades with color-mix(). Change the single brand colour and the whole derived palette updates — no manual recolouring.

Q. What does margin-inline control in a normal English (left-to-right) page?

Answer: margin-inline sets the margins on the two edges along the text-flow direction — left and right in English — and flips automatically for right-to-left languages.

✍️ Practice

  1. Replace the physical margins/paddings on a card with margin-block, margin-inline, padding-block and padding-inline.
  2. Define one --brand colour and use color-mix() to create a darker hover shade for a button.

🏠 Homework

  1. Convert one component to logical properties, add dir="rtl" to its wrapper, and confirm it mirrors correctly with no extra CSS.
Want to learn this with a mentor?

CodingClave runs guided, project-based training (28-day, 45-day & 6-month batches).

Explore Training →