Tablo ve Print Stilleri: border-collapse, table-layout, Sticky Başlık, Sayısal Hizalama, @media print ve @page
Veri tablosunda border-collapse: collapse, table-layout: fixed ve para kolonu için text-align: end ile tabular-nums yeterli; sticky başlığın çizgisini box-shadow ile çiz, yazdırma için @media print, @page ve print-color-adjust kullan. Yazı Bookstore'un My orders tablosunu ve faturasını Chromium ile WebKit'te ölçer, Chromium'un page.pdf() çıktısını pdf.js ile okur ve seriyi kapatır.
Sürüm notu: Bu yazı CSS 2.2 (tablolar), CSS Fonts Level 4 (font-variant-numeric), CSS Fragmentation Level 3, CSS Paged Media Level 3 ve CSS Color Adjustment Level 1 spesifikasyonlarına ve Baseline'ın Kasım 2026 durumuna (web-features 3.46.0) göre yazıldı; örnekler Chromium 158 ve WebKit 27.2 (Playwright 1.65) ile denenmiştir, PDF çıktısı Chromium'un page.pdf()'si ile üretilip pdf.js 6.5 ile okunmuştur, Firefox desteği web-features ve MDN'in (Mozilla'nın web dokümantasyon projesi) browser-compat-data 8.1.9 verisinden alınmıştır.
Önce Tahmin Et
Sitedeki serilerin ortak örnek uygulaması Bookstore (bir online kitapçı) için serinin son iki ekranını yapıyoruz: 40 siparişlik bir "My orders" tablosu ve yazdırılabilir bir fatura. Önce lab'deki iki kutu. İkisinde de tablo başlığı sticky ve altında 3 piksellik kırmızı bir çizgi var; tek fark, ikincisinde border-collapse: collapse:
/* 4) kayan bir kutunun içinde sticky başlık */
.box { block-size: 150px; overflow: auto; }
.box table { inline-size: 300px; border-spacing: 0; }
.box th { position: sticky; inset-block-start: 0; background: #ffffff; border: 0; border-block-end: 3px solid #b91c1c; }
.box td { block-size: 40px; border: 0; }
#sticky-collapse table { border-collapse: collapse; }
İki kutu da 120 piksel aşağı kaydırılınca başlık en üstte kalır mı, kırmızı çizgi onunla birlikte gelir mi?
border-collapse ve border-spacing
Tablonun kenarlıkları iki modelden biriyle çizilir. Varsayılan separate'te her hücrenin kendi kenarlığı vardır ve hücreler arasında border-spacing kadar boşluk kalır. collapse'ta komşu hücreler tek bir kenarlığı paylaşır:
td, th { padding: 4px 8px; border: 1px solid #9ca3af; }
/* 1) separate (varsayılan) ve collapse */
#separate { border-spacing: 4px; }
#collapse { border-collapse: collapse; }
node scripts/13-table.mjs
--- chromium
separate gap between cells 4px, table 147.765625px
collapse gap between cells 0px, table 134.765625px
--- webkit
separate gap between cells 4px, table 147.765625px
collapse gap between cells 0px, table 134.765625px
separate tabloda hücreler arasında 4 piksel boşluk var ve tablo 147.77 piksel. collapse'ta boşluk 0 ve tablo 13 piksel daha dar: üç boşluk (iki kenarda ve ortada 4'er piksel) ve paylaşılan bir kenarlık (1 piksel) gitti. İki motorda ölçüm aynı. Veri tablolarında çoğu zaman collapse ve yalnız yatay çizgiler istenir; tablonun köşelerini yuvarlamak istersen collapse'ta border-radius çalışmaz, o zaman separate ve border-spacing: 0 kullanılır. Tablonun HTML tarafı (caption, thead, th scope, colgroup) sitedeki HTML serisinin (HTML5 ve Semantic HTML) 10. yazısında; burada yalnız görünüşüne bakıyoruz.
table-layout: fixed ve Kolon Genişlikleri
Varsayılan table-layout: auto'da tarayıcı kolon genişliklerini bütün hücrelerin içeriğine bakarak hesaplar. fixed'de genişlikler tablonun genişliğinden, col element'lerinden ve ilk satırdan gelir; sonraki satırların içeriği hesaba girmez:
/* 2) table-layout: ya içerik karar verir ya ilk satır */
.layout { inline-size: 480px; border-collapse: collapse; }
.layout td { overflow-wrap: break-word; }
.layout col:first-child { inline-size: 120px; }
#fixed { table-layout: fixed; }
<table class="layout" id="auto">
<colgroup><col><col></colgroup>
<tr><td>Gift code</td><td>SPRINGREADERS2026FORTHEWHOLECLASSANDTHEIRTEACHERS</td></tr>
</table>
--- chromium
table-layout: auto table 564px, columns 53 + 510, row height 57px
table-layout: fixed table 480px, columns 120 + 359, row height 57px
--- webkit
table-layout: auto table 564px, columns 53 + 510, row height 57px
table-layout: fixed table 480px, columns 120 + 359, row height 57px
İki tablo da 480 piksel genişliğinde tanımlı ve ilk kolon 120 piksel isteniyor. auto tablo, 49 karakterlik kesintisiz hediye kodu yüzünden 564 piksele genişledi, verilen genişliği aştı ve ilk kolonu 53 piksele sıkıştırdı ("Gift code" iki satıra indi). fixed tablo 480 pikselde ve ilk kolon 120'de kaldı; uzun kod overflow-wrap: break-word ile kendi kolonunda kırıldı. break-word, anywhere'den farklı olarak içeriğin minimum genişliğini küçültmez; auto tabloyu bu yüzden durduramadı (ikisinin farkı serinin satır kırma yazısında). fixed'in bir yan faydası daha var: tarayıcı ilk satırı görünce bütün tabloyu yerleştirebilir, 40 satırlık bir tabloda kolonlar yükleme sırasında oynamaz.
Para Kolonu: text-align: end ve tabular-nums
Tutarlar sağa hizalanır ki basamaklar alt alta gelsin. Ama sağa hizalamak tek başına yetmez: font'ların çoğunda "1" rakamı "8"den dardır (orantılı rakamlar). font-variant-numeric: tabular-nums, font'tan bütün rakamları aynı genişlikte çizmesini ister:
/* 3) rakamlar: varsayılan olarak orantılı, istenirse eşit genişlikte */
.amount { font-family: system-ui, sans-serif; }
.amount.serif { font-family: Georgia, serif; }
.tabular { font-variant-numeric: tabular-nums; }
--- chromium
system-ui: ₺1,111.10 62.23px, ₺8,888.80 75.75px
system-ui tabular-nums: ₺1,111.10 77.23px, ₺8,888.80 77.23px
Georgia tabular-nums: ₺1,111.10 61.72px, ₺8,888.80 75.05px
--- webkit
system-ui: ₺1,111.10 62.23px, ₺8,888.80 75.75px
system-ui tabular-nums: ₺1,111.10 77.23px, ₺8,888.80 77.23px
Georgia tabular-nums: ₺1,111.10 61.72px, ₺8,888.80 75.04px
Bu makinenin system-ui'ında "₺1,111.10" 62.23, "₺8,888.80" 75.75 piksel; tabular-nums ile ikisi de 77.23 piksel. Georgia'da ise tabular-nums hiçbir şey değiştirmiyor: property yalnız font'un içindeki bir özelliği (OpenType tnum) açar, font'ta bu özellik yoksa etkisizdir. Windows'ta system-ui başka bir font'a (Segoe UI) çözülür ve sonuç farklı olabilir; para kolonu için seçtiğin font'u kontrol et. Bu kararın tipografi tarafı UI/UX Tasarım İlkeleri serisinin 03. yazısında. Bookstore'un sipariş tablosunda ölçüm:
node scripts/13-pages.mjs
--- chromium
columns 104 + 120 + 751 + 120 + 120px, caption below the rows, row 2 background rgb(243, 244, 246)
amount starts at x, tabular-nums: ₺420.00 1165, ₺553.00 1165, ₺1,115.50 1150.8, ₺240.00 1165, ₺520.00 1165, ₺2,118.50 1150.8
amount starts at x, proportional: ₺420.00 1166.4, ₺553.00 1166.6, ₺1,115.50 1161, ₺240.00 1166.7, ₺520.00 1166.8, ₺2,118.50 1158.3
--- webkit
columns 104 + 120 + 766 + 120 + 120px, caption below the rows, row 2 background rgb(243, 244, 246)
amount starts at x, tabular-nums: ₺420.00 1180, ₺553.00 1180, ₺1,115.50 1165.8, ₺240.00 1180, ₺520.00 1180, ₺2,118.50 1165.8
amount starts at x, proportional: ₺420.00 1181.4, ₺553.00 1181.6, ₺1,115.50 1176, ₺240.00 1181.7, ₺520.00 1181.8, ₺2,118.50 1173.3
Kolonlar col'larda verdiğimiz genişliklerde (104, 120, 120, 120 piksel) ve kalan yer kitaplar kolonunda. tabular-nums ile aynı uzunluktaki tutarlar ("₺420.00", "₺553.00", "₺240.00") aynı x'te başlıyor, dört basamaklı iki tutar da (1150.8) aynı yerde. Rakamlar orantılı olunca dört basamaklılar 1161 ve 1158.3'te başlıyor: 2.7 piksellik fark, gözün alt alta okurken fark ettiği türden bir kayma.
"My orders" Tablosu: Zebra, caption-side ve Sticky Başlık
Bookstore'un sipariş tablosu, HTML5 serisindeki gibi odaklanabilir bir scroll kutusunun içinde:
<div class="table-scroll" tabindex="0" role="region" aria-labelledby="orders-caption">
<table class="data-table orders">
<caption id="orders-caption">Orders in 2026 (cancelled and returned orders are not counted)</caption>
<colgroup>
<col class="col-order">
<col class="col-date">
<col>
<col class="col-status">
<col class="col-total">
</colgroup>
<thead>
<tr><th scope="col">Order</th><th scope="col">Date</th><th scope="col">Books</th><th scope="col">Status</th><th scope="col" class="num">Total</th></tr>
</thead>
<tbody>
<tr><td>BK-1042</td><td>2026-11-14</td><td>Dune</td><td><span class="status status-delivered">Delivered</span></td><td class="num">₺420.00</td></tr>
/* veri tabloları: ortak kenarlıklar, col element'leriyle belirlenen kolonlar, sağda sayılar */
.data-table {
inline-size: 100%;
border-collapse: collapse;
/* kolon genişlikleri en uzun içerikten değil, col element'lerinden ve ilk satırdan gelir */
table-layout: fixed;
background: var(--color-surface);
}
.data-table caption {
caption-side: bottom;
padding-block: 0.5rem;
color: var(--color-muted);
text-align: start;
}
.data-table th,
.data-table td {
padding: 0.5rem 0.75rem;
border-block-end: 1px solid var(--color-border);
text-align: start;
vertical-align: top;
overflow-wrap: break-word;
}
.data-table tbody tr:nth-child(even) { background: #f3f4f6; }
/* para: sağa hizalı, her rakam aynı genişlikte, böylece basamaklar alt alta gelir */
.data-table .num {
text-align: end;
font-variant-numeric: tabular-nums;
white-space: nowrap;
}
.data-table tfoot { font-weight: 700; }
.col-order { inline-size: 6.5rem; }
.col-date { inline-size: 7.5rem; }
.col-status { inline-size: 7.5rem; }
.col-total { inline-size: 7.5rem; }
/* tablo kendi kutusunda (iki eksende) kayar, böylece sticky başlığın yapışacağı bir yer olur */
.table-scroll {
max-block-size: 70vh;
overflow: auto;
border: 1px solid var(--color-border);
}
.data-table thead th {
position: sticky;
inset-block-start: 0;
background: var(--color-surface);
/* başlık yapışınca collapse edilmiş kenarlık geride kalır; gölge onunla gider */
border-block-end: 0;
box-shadow: inset 0 -2px 0 var(--color-border);
}
.status {
display: inline-block;
padding-inline: 0.5rem;
border-radius: 999px;
font-size: 0.875rem;
}
.status-delivered, .status-paid { background: #dcfce7; color: #166534; }
.status-shipped { background: #dbeafe; color: #1e40af; }
.status-cancelled, .status-returned { background: #f3f4f6; color: #4b5563; }
Ölçümün ilk satırına göre caption satırların altında (caption-side: bottom) ve ikinci satırın arka planı zebra rengi; :nth-child(even)'in selector tarafı sitedeki CSS serisinin (CSS3: Flexbox, Grid ve Modern CSS) 02. yazısında. Şimdi giriş sorusunun cevabı:
--- chromium
sticky-separate header 0px from the top of the box, red line pixels in the top 60px: 900
sticky-collapse header 0px from the top of the box, red line pixels in the top 60px: 0
--- webkit
sticky-separate header 0px from the top of the box, red line pixels in the top 60px: 900
sticky-collapse header 0px from the top of the box, red line pixels in the top 60px: 0
İki kutuda da başlık en üstte kaldı, ama kırmızı çizgi yalnız separate tabloda başlıkla geldi (900 piksel); collapse'ta 0. Collapse modunda kenarlık hücreye değil, iki hücre arasındaki çizgiye ait sayılır ve hücre yapışınca yerinde kalır. Bookstore tablosu collapse kullandığı için başlığın alt çizgisini bir inset box-shadow ile çiziyoruz; gölge hücrenin kendisine ait olduğu için onunla gidiyor:
--- chromium
table box scrolled 400px: header 0px from the box top, line under the header 2430 px
overflow-x: auto box, page scrolled 600px: header top -435px in the viewport, computed overflow-y auto
--- webkit
table box scrolled 400px: header 0px from the box top, line under the header 2460 px
overflow-x: auto box, page scrolled 600px: header top -435px in the viewport, computed overflow-y auto
Tablonun kutusu 400 piksel kaydırılınca başlık kutunun tepesinde ve altındaki çizgi duruyor. İkinci satır, HTML5 serisinin 10. yazısındaki gibi yalnız overflow-x: auto olan bir kutuyu deniyor: overflow-y'ye visible yazsak da computed değer auto (bir eksen visible dışında olunca öbürü de öyle olur), yani kutu bir scroll container. Ama kutunun yüksekliği sınırlı olmadığı için kendisi dikey olarak hiç kaymıyor; sayfa 600 piksel kayınca başlık sayfayla birlikte -435 piksele gidiyor. Sticky, en yakın scroll container'a yapışır; o container hiç kaymıyorsa başlık da yapışmaz. Bu yüzden Bookstore'da kutuya max-block-size: 70vh verip tabloyu iki eksende de kendi kutusunda kaydırıyoruz. Sticky'nin genel mekaniği CSS3 serisinin 04. yazısında, kutunun tabindex ve role="region"'ı HTML5 10'da.
Yazdırma: @media print, @page, break-inside ve print-color-adjust
Faturayı yazdırılabilir yapmak için ayrı bir sayfa gerekmez; aynı HTML'e bir print stylesheet'i yeter:
/* yazdırma: her basılan sayfa için kâğıt boyutu ve kenar boşlukları */
@page {
size: A4;
margin: 15mm;
}
@media print {
/* navigasyon ve butonların kâğıtta anlamı yok */
.site-header,
.print-button { display: none; }
body { background: none; color: #000000; font-size: 11pt; }
/* linkler: metnin ardından adresi yazdır */
a[href^="http"]::after { content: " (" attr(href) ")"; }
/* scroll kutusu kâğıtta tabloyu keserdi */
.table-scroll { max-block-size: none; overflow: visible; border: 0; }
.data-table thead th { position: static; }
/* bir satır iki sayfaya bölünmez; başlıklar ardından geleni bırakmaz */
.data-table tr { break-inside: avoid; }
h1, h2 { break-after: avoid; }
/* durum renkleri anlam taşır: "Background graphics" kapalıyken de yazdır */
.status { print-color-adjust: exact; }
}
<button type="button" class="print-button" onclick="window.print()">Print</button>
<dt>Payment</dt><dd><span class="status status-paid">Paid</span></dd>
<p class="invoice-note">Returns within 14 days, see <a href="https://bookstore.test/help/returns">our returns page</a>.</p>
Ölçüm iki kısım. Önce iki motorda da emulateMedia({ media: 'print' }) ile computed değerler; sonra yalnız Chromium'da gerçek bir PDF. Playwright'ın page.pdf()'si yalnız Chromium'da var; WebKit ve Firefox için yazdırma çıktısı üretemedim. PDF'i aynı Chromium sayfasında pdf.js ile açıp sayfa sayısını, sayfa boyutunu, her sayfanın metnini ve faturanın ilk sayfasındaki açık yeşil pikselleri okuyoruz:
// printBackground false kalır: yazdırma penceresinin varsayılanı ("Background graphics" kapalı)
const pdf = await p.pdf({ preferCSSPageSize: true });
node scripts/13-print.mjs
--- chromium (print media)
header display none, print button none, link ::after " (https://bookstore.test/help/returns)", .status print-color-adjust exact
--- webkit (print media)
header display none, print button none, link ::after " (" "https://bookstore.test/help/returns" ")", .status print-color-adjust exact
--- chromium, page.pdf()
invoice: 1 page, 594.96 x 841.92 pt
"Bookstore My orders" header printed: false, "Print" button printed: false
link printed as: "see our returns page (https://bookstore.test/help/returns)"
"Paid" badge background pixels: 1543
with print-color-adjust: economy: 0
orders: 3 pages
page 1: header row yes, rows BK-1042 … BK-1029 (14)
page 2: header row yes, rows BK-1028 … BK-1012 (17)
page 3: header row yes, rows BK-1011 … BK-1003 (9)
tall rows, break-inside: auto → 10 pages, rows cut in two: BK-1038, BK-1031, BK-1022, BK-1013, BK-1004
tall rows, break-inside: avoid → 11 pages, rows cut in two: none
Print media'da header ve "Print" butonu display: none, link'in ::after'ı adresi taşıyor, durum rozeti print-color-adjust: exact. İki motorda computed değerler aynı; WebKit attr()'ı computed değerde çözmeden bırakıyor. PDF'te fatura tek sayfa ve sayfa 594.96 × 841.92 pt, yani @page { size: A4; } uygulanmış (preferCSSPageSize: true; bunu vermezsen Playwright varsayılan Letter boyutunu kullanır). Header ve buton kâğıtta yok, link "our returns page (https://bookstore.test/help/returns)" olarak basılmış: kâğıtta tıklanamayan bir linkin adresi okunabiliyor.
"Paid" rozetinin açık yeşil arka planı PDF'te 1543 piksel. print-color-adjust: economy (varsayılan değer) ile 0: tarayıcılar mürekkep tasarrufu için arka plan renklerini ve görsellerini varsayılan olarak basmaz (yazdırma penceresindeki "Background graphics" kutusu). Rengin bilgi taşıdığı yerde exact yaz. browser-compat-data'ya göre Chrome ve Safari body'nin arka planını exact ile de basmıyor; property yalnız alt element'lere işliyor. Aynı uyarı tersinden de geçerli: bilgiyi yalnız arka plan rengine bırakma; rozetin içindeki "Paid" metni renksiz kâğıtta da okunuyor.
Sipariş tablosu üç sayfa. Chromium thead'i her sayfanın başında tekrar basıyor ("header row yes"), çünkü thead'in varsayılan display'i table-header-group. 40 satırın hepsi bir kere basılmış (14 + 17 + 9). break-inside: avoid'in etkisini görmek için kitaplar kolonunu 36pt yapıp satırları birkaç satırlık hâle getirdim. break-inside: auto ile on sayfalık çıktıdaki dokuz sayfa geçişinin beşinde bir satır ikiye bölündü (BK-1038, BK-1031…); avoid ile hiçbiri bölünmedi ve tablo bir sayfa uzadı (11 sayfa). Başlıklar için break-after: avoid, bir başlığın sayfanın en altında tek başına kalmasını önler. Bir paragrafın sayfanın altında ya da üstünde en az kaç satırının kalacağını belirleyen orphans ve widows ise Firefox'ta olmadığı için Baseline değil.
@page'in kendisi Aralık 2024'ten beri newly available (Safari 18.2 ile size); browser-compat-data'ya göre Safari size'ın landscape ve portrait anahtar kelimelerini desteklemiyor. Sayfa kenar kutuları (@top-center gibi, sayfa numarası yazmak için) Chrome 131'den beri var ama Baseline değil.
Üretimde Dikkat
Yazdırma çıktısını gerçek yazdırma penceresiyle de kontrol et: kullanıcı kâğıt boyutunu, kenar boşluklarını ve "Background graphics" kutusunu değiştirebilir; @page bir öneridir. Faturanın PDF'i sunucuda üretilecekse (e-posta eki, muhasebe arşivi) aynı print stylesheet'i headless Chromium'la PDF'e çevirmek, ayrı bir PDF template'inin bakımından ucuzdur; bu yazıdaki page.pdf() çağrısı bunun en küçük hâli.
Uzun tablolarda table-layout: fixed ile yazdırma da öngörülebilir olur: A4'ün (210 × 297 mm'lik standart kâğıt) dar genişliğinde auto tablo uzun bir hücre yüzünden kâğıttan taşabilir. Dar ekranda tabloyu display: block ya da grid'e çevirip kartlara dönüştürmek tablo semantiğini bozar; HTML5 serisinin 10. yazısı bunun neden ve nasıl düzeltileceğini anlatıyor. Kaydırılan kutu çoğu zaman daha doğru çözüm.
Sticky başlığı olan bir tabloyu kendi kutusunda kaydırırken iki scrollbar (sayfa ve kutu) ortaya çıkar. max-block-size: 70vh kutuyu ekrandan küçük tuttuğu için sayfa scrollbar'ı ile çakışmaz; bir önceki yazının scrollbar-gutter'ı kutuda da kullanılabilir.
Sık Düşülen Tuzaklar
Birincisi, border-collapse: collapse'lı bir tabloda sticky başlığın kenarlığına güvenmek. Başlık yapışınca kenarlık geride kalır; çizgiyi box-shadow ile çiz.
İkincisi, table-layout: auto ile uzun ve kesintisiz bir içeriğin bütün tabloyu genişletmesi. fixed ve col genişlikleri kolonları sabitler.
Üçüncüsü, para kolonunu sağa hizalayıp tabular-nums'ı unutmak ya da tnum özelliği olmayan bir font'ta işe yaramasını beklemek.
Dördüncüsü, bilgiyi yalnız arka plan rengiyle vermek. Yazdırmada arka planlar varsayılan olarak basılmaz; metin de olsun ve gerekiyorsa print-color-adjust: exact yaz.
Beşincisi, sticky başlık için yalnız overflow-x: auto'lu bir kutu kullanmak. Kutu dikey olarak kaymıyorsa başlık hiçbir yere yapışmaz.
Baseline Durumu
node scripts/baseline.mjs table font-variant-numeric sticky-positioning print-color-adjust page-setup page-breaks widows-orphans
table widely 2018-01-29 Chrome 1, Firefox 1, Safari 1, iOS 1
font-variant-numeric widely 2022-07-15 Chrome 52, Firefox 34, Safari 9.1, iOS 9.3
sticky-positioning widely 2022-03-19 Chrome 56, Firefox 59, Safari 13, iOS 13
print-color-adjust newly 2025-05-01 Chrome 136, Firefox 97, Safari 15.4, iOS 15.4
page-setup newly 2024-12-11 Chrome 15, Firefox 95, Safari 18.2, iOS 18.2
page-breaks widely 2021-07-29 Chrome 50, Firefox 65, Safari 10, iOS 10
widows-orphans not Baseline Chrome 25, Firefox -, Safari 1.3, iOS 1
| Özellik | Durum | Not |
|---|---|---|
Tablo property'leri (border-collapse, table-layout, caption-side) | Widely available | caption-side: top-outside gibi değerler standart dışı |
font-variant-numeric | Widely available | Font'ta tnum yoksa etkisiz |
Sticky th | Widely available | Collapse kenarlığı yapışmaz |
@page ve size | Newly available (2024-12) | Safari'de landscape/portrait yok |
break-inside, break-after | Widely available | avoid-page gibi değerler değil |
print-color-adjust | Newly available (2025-05) | Chrome 136 öncesi -webkit- prefix'i |
orphans, widows | Baseline değil | Firefox'ta yok |
Seriyi Toparlarken
On üç yazıda Bookstore'un her ekranını property property stilledik. Font ve metin bloğunda (01–03) self-host variable font, okunur link alt çizgisi, satır kırma ve çok satırlı kesme; kutunun görünüşünde (04–05) background katmanları, gradient'ler, kenarlık, gölge ve focus halkası; görsel efektlerde (06–08) transform, filter, blend mode, clip-path ve mask; görseller ve üretilmiş içerikte (09–10) img reset'i, SVG (vektör görsel formatı) ikonlar, counter'lar ve liste işaretleri; son blokta (11–13) scroll davranışı, form kontrolleri, tablolar ve yazdırma.
Bütün seri boyunca aynı üç alışkanlık işe yaradı. Shorthand'in neyi sıfırladığını bil (font, background, border). Her property'nin Baseline durumuna bak ve "Baseline değil" olanı progressive enhancement olarak ekle; çoğu zaman sebep tek bir tarayıcının bir alt özelliği (accent-color'da Chrome Android, overscroll-behavior'da Safari, user-select'te Safari'nin prefix'i). Ve ölç: bu seride ölçüm, görselleri sıkıştıran bir flex şeridini, forced colors'ta kaybolan bir onay işaretini ve sticky başlıkla gitmeyen bir kenarlığı yakaladı; üçü de ekran görüntüsünde ilk bakışta görünmüyordu.
Bu seri "şu görünümü hangi property ile yazarım?" sorusuna cevap verdi. "CSS bu kararı neden böyle verdi?" sorusu, yani cascade, specificity, box model, layout (Flexbox, Grid), responsive tasarım, custom property'ler, animasyon ve 2023–2026'da gelenlerin özeti, sitedeki CSS3 serisinin konusu. Bu seriyi bitirdiysen o seriyi 01. yazısından baştan okumak, bu seride yazdığın her kuralın neden çalıştığını görmenin en kısa yolu.
Küçük Bir Deneme
★☆☆ Sipariş tablosunda .num'dan tabular-nums'ı kaldır ve 13-pages.mjs'in yazdırdığı başlangıç x'lerinin nasıl dağıldığına bak; sonra Fraunces'ın da tnum desteği olup olmadığını aynı ölçümle bul.
★★☆ Faturaya @page :first ile ilk sayfada daha geniş bir üst boşluk ver ve 13-print.mjs'e ilk sayfanın metin konumunu ölçen bir satır ekle.
★★★ Sipariş tablosunda tamamlanan siparişleri yazdırırken gizleyen bir "Print only open orders" seçeneği yaz (bir checkbox ve :has() ile, JavaScript'siz) ve PDF'te kaç sayfa kaldığını ölç.
Seri burada bitiyor. Bir property'nin davranışından emin olmadığında bu serideki gibi küçük bir lab sayfası yaz ve iki motorda ölç; tarayıcı, dokümandan daha güvenilir bir kaynak.