jvinhit//lab

Search posts

Type to search across journal entries.

navigate open esc close

Tailwind, Radix & shadcn/ui · Part 2 — Core Utilities & Layout

The utilities you reach for every day: spacing, sizing, typography and color, then the two layout engines — Flexbox and Grid — the Tailwind way, plus the mobile-first responsive system. With a live flex/grid builder.

Part 1 gave you the mental model and a working v4 setup {Phần 1 đã cho bạn mô hình tư duy và một setup v4 chạy được}. Now we build vocabulary {Giờ ta xây vốn từ}. This is the 80% of Tailwind you’ll use 80% of the time — spacing, sizing, type, color, and the two layout engines {Đây là 80% Tailwind bạn dùng 80% thời gian — spacing, sizing, type, màu, và hai cỗ máy layout}. Learn these cold and you can build almost any static UI {Nắm chắc phần này là bạn dựng được gần như mọi UI tĩnh}.


1. The spacing scale — the heartbeat {Thang spacing — nhịp tim}

Almost every spacing utility shares one numeric scale where n means n × 0.25rem (4px at the default root size) {Gần như mọi utility spacing dùng chung một thang số với n nghĩa là n × 0.25rem (4px ở cỡ gốc mặc định)}.

ClassValueClassValue
p-10.25remp-61.5rem
p-20.5remp-82rem
p-41remp-123rem

The prefixes you’ll use constantly {Các tiền tố bạn dùng liên tục}:

  • Padding: p, px/py (axis), pt/pr/pb/pl (side) {Padding: p, px/py (trục), pt/pr/pb/pl (cạnh)}
  • Margin: m, mx/my, mt…, plus mx-auto to center {Margin: m, mx/my, mt…, và mx-auto để căn giữa}
  • Gap (flex/grid): gap, gap-x, gap-y {Gap (flex/grid): gap, gap-x, gap-y}
<div class="px-4 py-2">horizontal 1rem, vertical 0.5rem</div>
<div class="mt-6 mb-2">top 1.5rem, bottom 0.5rem</div>

space-x/space-y vs gap: space-y-4 adds margin between children (not the edges); gap-4 needs a flex/grid parent but is cleaner {space-x/space-y vs gap: space-y-4 thêm margin giữa các con (không tính rìa); gap-4 cần cha là flex/grid nhưng gọn hơn}. Prefer gap whenever the parent is already flex or grid {Ưu tiên gap khi cha đã là flex hoặc grid}.


2. Sizing — width, height, min/max {Kích thước — width, height, min/max}

Sizing mixes the spacing scale with fractions and keywords {Sizing trộn thang spacing với phân số và từ khóa}:

<div class="w-64">width: 16rem (64 × 0.25)</div>
<div class="w-1/2">width: 50%</div>
<div class="w-full h-screen">100% wide, 100vh tall</div>
<div class="max-w-sm">max-width: 24rem — great for cards & prose</div>
<div class="size-10">width AND height: 2.5rem (v4 shorthand)</div>

The max-w-* scale (max-w-smmax-w-7xl, max-w-prose) is how you keep content readable on wide screens {Thang max-w-* (max-w-smmax-w-7xl, max-w-prose) là cách giữ nội dung dễ đọc trên màn hình rộng}.


3. Typography & color {Typography & màu}

<p class="text-sm">0.875rem</p>
<p class="text-lg font-semibold tracking-tight leading-relaxed">
  size, weight, letter-spacing, line-height
</p>
<p class="text-slate-600">color from the palette</p>
<p class="text-indigo-500/70">indigo at 70% opacity (the /opacity modifier)</p>

Key families {Các nhóm chính}: text-{xs..9xl} (size), font-{normal,medium,semibold,bold} (weight), tracking-* (letter-spacing), leading-* (line-height), text-{color}-{50..950} (color) {kích thước, độ đậm, giãn chữ, giãn dòng, màu}. The /NN opacity modifier works on almost any color utility — bg-black/50, border-white/10 {Bộ chỉnh độ mờ /NN chạy với gần như mọi utility màu}.


4. Flexbox — the Tailwind way {Flexbox — kiểu Tailwind}

Every Flexbox concept is a utility {Mọi khái niệm Flexbox là một utility}:

CSSTailwind
display: flexflex
flex-direction: columnflex-col
justify-content: space-betweenjustify-between
align-items: centeritems-center
gap: 1remgap-4
flex: 1 1 0%flex-1

The single most common layout in all of UI — a centered row that pushes items apart {Layout phổ biến nhất trong mọi UI — một hàng căn giữa, đẩy các item ra hai bên}:

<header class="flex items-center justify-between gap-4">
  <span class="font-semibold">Logo</span>
  <nav class="flex gap-4">…</nav>
</header>

5. Grid — for two-dimensional layout {Grid — cho layout hai chiều}

<div class="grid grid-cols-3 gap-4">
  <div>…</div><div>…</div><div>…</div>
</div>

grid-cols-3 → three equal columns (repeat(3, minmax(0, 1fr))) {grid-cols-3 → ba cột bằng nhau}. Span items with col-span-2, set rows with grid-rows-*, place with col-start-* {Cho item chiếm nhiều cột bằng col-span-2, đặt hàng với grid-rows-*, định vị với col-start-*}.

Build both layouts hands-on below — toggle utilities, then switch the viewport to watch the md: override activate {Dựng cả hai layout ngay bên dưới — bật utility, rồi đổi viewport để xem override md: kích hoạt}:


6. Responsive design — mobile-first {Responsive — mobile-first}

This is the concept that trips up beginners, so internalize it {Đây là khái niệm làm người mới vấp, nên hãy thấm nó}:

Unprefixed utilities apply at all sizes. A prefix like md: means “at this breakpoint and larger.” {Utility không tiền tố áp ở mọi cỡ. Tiền tố như md: nghĩa là “từ breakpoint này trở lên.”}

The default breakpoints {Các breakpoint mặc định}: sm 640px, md 768px, lg 1024px, xl 1280px, 2xl 1536px {…}.

<!-- 1 column on phones, 2 from md, 3 from lg -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">…</div>

You design the smallest screen first (the unprefixed classes), then add overrides that only kick in upward {Bạn thiết kế màn hình nhỏ nhất trước (class không tiền tố), rồi thêm override chỉ áp khi to lên}. This reads top-down like a story: “stack on mobile, side-by-side on tablet, three-up on desktop” {Đọc từ trên xuống như một câu chuyện: “xếp chồng trên mobile, cạnh nhau trên tablet, ba cột trên desktop”}.

A common mistake {Lỗi thường gặp}: writing md:flex and expecting it to also affect mobile {viết md:flex rồi mong nó cũng ảnh hưởng mobile}. It won’t — md: starts at 768px {Không đâu — md: bắt đầu từ 768px}. For “flex everywhere, column on mobile, row on desktop” you write flex flex-col md:flex-row {Muốn “flex mọi nơi, cột trên mobile, hàng trên desktop” bạn viết flex flex-col md:flex-row}.


7. Exercises {Bài tập}

1. Build a navbar: full width, items vertically centered, logo on the left and a link group on the right, 1rem gap {Dựng navbar: full width, item căn giữa dọc, logo bên trái và nhóm link bên phải, gap 1rem}.

Solution {Lời giải}
<header class="flex items-center justify-between gap-4 px-6 py-4">
  <span class="font-semibold">Logo</span>
  <nav class="flex gap-4"><a>Home</a><a>Docs</a><a>About</a></nav>
</header>

2. A responsive card grid: 1 column on mobile, 2 from sm, 3 from lg, with 1.5rem gaps {Lưới card responsive: 1 cột mobile, 2 từ sm, 3 từ lg, gap 1.5rem}.

Solution {Lời giải}
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">…</div>

3. Center a box both horizontally and vertically inside a full-height section {Căn giữa một box cả ngang và dọc trong một section cao full màn hình}.

Solution {Lời giải}
<section class="flex items-center justify-center h-screen">
  <div class="max-w-sm">Centered</div>
</section>

Stretch {Nâng cao}: in the builder above, make a layout that is a stacked column on narrow and a row on wide using a md: override, and read the generated @media block {trong builder ở trên, tạo layout cột xếp chồng khi hẹphàng khi rộng bằng override md:, rồi đọc khối @media sinh ra}.


Key takeaways {Điểm chính}

  • One spacing scale (n × 0.25rem) drives padding, margin, and gap — that’s why Tailwind UIs feel rhythmically consistent {Một thang spacing chi phối padding, margin, gap — nên UI Tailwind có nhịp nhất quán}.
  • Flexbox for one-dimensional rows/columns; Grid for two-dimensional layouts — each CSS property has a direct utility {Flexbox cho hàng/cột một chiều; Grid cho layout hai chiều — mỗi thuộc tính CSS có utility tương ứng}.
  • Responsive is mobile-first: unprefixed = all sizes, md:/lg: = that breakpoint and up {Responsive là mobile-first: không tiền tố = mọi cỡ, md:/lg: = breakpoint đó trở lên}.

Next up {Tiếp theo}

Part 3 — Design tokens & theming in v4: the @theme directive, defining your own colors/fonts/spacing as CSS variables, the v4 way to do dark mode, and how every token becomes a utility automatically {Phần 3 — Design token & theming ở v4: directive @theme, tự định nghĩa màu/font/spacing dưới dạng biến CSS, cách làm dark mode kiểu v4, và cách mỗi token tự trở thành một utility}.