Alt çizgileri, üst çizgileri ve üstü çizili metinleri kenarlıklar, arka plan gradyanları veya sözde öğelerle taklit etmek yerine yerel text-decoration özelliklerini kullanarak biçimlendirin. Yerel bir dekorasyon, kaydırılan satırlardaki metni takip eder, yazı tipinin metriklerini izler, glif alt çıkıntılarını atlar ve iç içe yerleştirilmiş öğeler aracılığıyla devralır. Bu nedenle, bunların hiçbirinin yeniden uygulanması gerekmez. Bu kılavuzun sonundaki kutu tabanlı teknikleri yalnızca süslemenin metin boyunca uzanması yerine metni çevrelemesi veya sarması gerektiğinde kullanın.
Metin süslemeleri yalnızca bağlantılara değil, tüm metinlere uygulanır. Altı çizili metin bağlantı değilse bağlantı olarak algılanmadığından emin olun. Bir bağlantıyı süslerken, komut dosyası işleyicisi olan href="javascript:void(0)" yerine, hedefi gösteren gerçek bir <a href> kullanın (yeni sekme açmak için target="_blank" rel="noopener" ekleyin). Gerçek bir bağlantı; orta tıklama, bağlantı kopyalama ve ekran okuyucu davranışını korur.
Çizgiye stil uygulama
text-decoration kısayoluyla çizgi, stil, renk ve kalınlığı, text-underline-offset ile de metinden uzaklığı ayarlayın. Seçiciyi :where() içine sarmalayın. Böylece varsayılanlar sıfır özgüllüğe sahip olur ve daha sonra yapılan geçersiz kılma işlemleri, özel özelliklere gerek kalmadan geçerli olur.
:where(.decorated) {
/* Thickness is relative to the font size (0.08em is an example value), so the line is not too heavy
on small text or too light on large text, and max() keeps it at least 1px so it never disappears. */
text-decoration: underline solid currentColor max(1px, 0.08em);
/* Use em so the gap scales with the font size. 0.2em clears most descenders; example value. */
text-underline-offset: 0.2em;
}
/* Example hover state: a softer line that firms up on hover and focus. The 50% mix and
0.12em thickness are example values. */
:where(.decorated) {
text-decoration-color: color-mix(in srgb, currentColor, transparent);
}
:where(.decorated:is(:hover, :focus-visible)) {
text-decoration-color: currentColor;
text-decoration-thickness: max(1px, 0.12em);
}
/* Other lines are a different text-decoration-line on the same properties */
.decorated-over { text-decoration-line: overline; }
.decorated-through { text-decoration-line: line-through; }
text-decoration-style; solid, double, dotted, dashed ve wavy ödeme yöntemlerini kabul eder. text-underline-offset yalnızca alt çizgilere uygulanır.
Tasarım için başlangıç noktaları:
- Kalınlık: Gövde metni için yaklaşık
0.06emila0.1em. Başlıklar ve vurgulanan durumlar için daha kalın (0.1em-0.15em) bir yazı tipi kullanın. - Zaman farkı: yaklaşık
0.15emila0.25em. Noktalı ve dalgalı çizgiler, düz çizgilere göre biraz daha fazla alana ihtiyaç duyar. Bu nedenle, bu çizgiler için ofseti artırın. - Renk:
currentColor, çizginin metinle eşleşmesini sağlar. Metin renginin daha yumuşak bir karışımı, fareyle üzerine gelindiğinde belirginleşerek uzun bağlantı dizilerinin daha sakin görünmesini sağlar. - Stil: Bağlantılar için
solid, terimler ve kısaltmalar içindotted, hatalar gibi ek açıklamalar içinwavy.
Satırın nerede atlanacağını kontrol etme
Mürekkep atlaması
Varsayılan olarak, alt çizgiler ve üst çizgiler, bunları kesen glif parçalarının (ör. alt çıkıntılar) etrafında kesilir. Davranışı seçmek için text-decoration-skip-ink ayarını yapın:
.decorated {
/* auto: skip ink for most scripts (default). none: draw straight through.
all: also skip ink in scripts where auto does not, such as Japanese or Chinese. */
text-decoration-skip-ink: all;
}
- Latin metinler için
autodeğerini koruyun ve bunu belirtmeyin. Bu, varsayılan değerdir. - Alt çizgi, ideografik glifleri kesecek kadar taban çizgisine yakın olduğunda veya karma alfabeli metnin tutarlı görünmesi gerektiğinde
allkullanın. - Boşlukların kesinti gibi görüneceği çok kalın veya dekoratif bir çizgi için
nonekullanın.
Alanları atla
text-decoration-skip-spaces, boşlukların altına çizgi çizilip çizilmeyeceğini belirler. Varsayılan değer olan start end, baştaki ve sondaki boşlukları süslemeden bırakır.
.decorated {
/* Spaces collapse by default, so there is nothing to skip. Preserve them when the
leading or trailing spaces are meaningful, such as padded input values. */
white-space: pre;
/* none: decorate every space. all: skip every space, so each word is underlined separately.
start | end | start end: skip only leading, trailing, or both. */
text-decoration-skip-spaces: all;
}
Süslemenin dolguyu (none) görünür şekilde kaplaması veya her kelime arasında bölünmesi (all) gerekmiyorsa text-decoration-skip-spaces değerini bildirmeyin. Bağlantı metni gibi sıradan satır içi metinlerin başında veya sonunda boşluk olmadığından bildirim hiçbir şey yapmaz.
Çizgiyi içe yerleştirme ile kırpma veya uzatma
text-decoration-inset, satırın başlangıç ve bitiş noktalarını taşır. Pozitif değerler ucu içe doğru çeker, negatif değerler ise dışa doğru iter. Tek bir değer her iki ucu da hareket ettirir. İki değer, başlangıç ve bitişi ayrı ayrı ayarlar. Yüzdeler, süslü kutunun satır içi boyutunu ifade eder.
/* Small insets soften the ends of the line; larger ones read as a deliberately short line.
Both values are examples. */
.trimmed { text-decoration-inset: var(--deco-inset, 0.1em); }
.extended { text-decoration-inset: calc(var(--deco-inset, 0.1em) * -1); }
Kenarlık veya arka plan gradyanı olmadan fareyle üzerine gelindiğinde alt çizgi göstermek için sonu% 100 kırpın ve tekrar 0'a geçirin:
.reveal {
text-decoration: underline; /* Always visible, including for reduced motion */
}
/* Only hide and animate the line when the user has not asked for reduced motion. */
@media (prefers-reduced-motion: no-preference) {
.reveal {
/* Trim the end by the full inline size so the line starts with zero length. */
text-decoration-inset: 0 100%;
/* 150ms to 300ms feels responsive without lagging; ease-out starts quickly. Example values. */
transition: text-decoration-inset var(--reveal-duration, 0.25s) ease-out;
}
/* Include :focus-visible so keyboard users get the same reveal as pointer users. */
.reveal:is(:hover, :focus-visible) {
text-decoration-inset: 0 0;
}
}
Sözde öğe ile özel çizgi çizme
Çizginin, text-decoration tarafından çizilemeyen bir şekil (ör. dalgalı çizgi) olması gerektiğinde sözde öğe kullanın ve kırparak gösterin. Ek işaretleme gerekmediğinden bağlantı düz bir <a> olarak kalır.
<a class="draw" href="#">Hover to draw underline</a>
.draw {
position: relative;
display: inline-block;
color: inherit;
text-decoration: none;
padding-block-end: 0.4em; /* Space for the line below the text; example value */
}
.draw::after {
content: "";
position: absolute;
inset: auto 0 0 0;
block-size: 0.4em; /* Height of the squiggle; example value */
pointer-events: none;
border: var(--deco-thickness, max(1px, 0.08em)) solid var(--deco-color, currentColor);
/* A single shape strokes along its path, using the border width as the stroke. Example squiggle. */
border-shape: shape(from 0% 50%,
curve to 20% 50% with 5% 0% / 15% 100%,
smooth to 40% 50% with 35% 100%,
smooth to 60% 50% with 55% 100%,
smooth to 80% 50% with 75% 100%,
smooth to 100% 50% with 95% 100%);
}
/* Only hide and animate the line when the user has not asked for reduced motion;
otherwise it stays fully drawn. */
@media (prefers-reduced-motion: no-preference) {
.draw::after {
/* Clip the line away from the right edge. The negative block insets keep the stroke
from being cut off vertically. */
clip-path: inset(-1em 100% -1em 0);
/* A slightly slower draw than a hover reveal reads as drawing; example duration. */
transition: clip-path var(--draw-duration, 0.6s) ease-out;
}
.draw:is(:hover, :focus-visible)::after {
clip-path: inset(-1em 0 -1em 0); /* Fully drawn */
}
}
Metni kutuyla çevrele
İki kutu özelliği, metni çizgiyle değil, ana hatlarıyla süsler. Metne dolgu ekleyerek ana hattın metne dokunmamasını sağlayın.
/* Gradient outline with a see-through middle */
.ring {
padding: 0.2em 0.75em; /* Example values: enough room that the outline does not touch the text */
/* The border width is the visible outline thickness. Relative to the font size, with a 2px
minimum so it stays visible on small text; example value. */
border: var(--ring-width, max(2px, 0.12em)) solid transparent;
background: linear-gradient(135deg, var(--ring-start, #2563eb), var(--ring-end, #db2777)) border-box;
/* Paint the background only under the border, so the inside stays transparent. */
background-clip: border-area;
}
/* Border that follows a shape that border-radius cannot draw, such as a tag with a pointed end */
.tag {
padding: 0.2em 1.5em 0.2em 0.9em; /* Example values: extra room at the point so the text is not clipped */
border: var(--shape-stroke, max(2px, 0.08em)) solid var(--shape-color, currentColor); /* Example stroke width */
/* A single shape strokes along its path. Two shapes fill the area between them.
This polygon is an example; use shape() for curves. */
border-shape: polygon(0 0, 85% 0, 100% 50%, 85% 100%, 0 100%);
}
border-shape yalnızca kenarlığı değiştirir. Arka plan hâlâ dikdörtgen kutu olduğundan bir şekli doldurmak için bu özelliği kullanmayın.
Yalnızca köşelerin farklı bir şekle (ör. eğimli, oyuklu veya çentikli etiket) sahip olması gerektiğinde border-radius ile birlikte corner-shape kullanın. Arka plan ve kenarlık köşeleri takip eder ve desteklenmeyen tarayıcılar sıradan yuvarlak köşelere geri döner.
.label {
padding: 0.2em 0.9em; /* Example values */
border: var(--shape-stroke, max(2px, 0.08em)) solid var(--shape-color, currentColor);
border-radius: 0.6em; /* Corner size; example value */
corner-shape: bevel; /* round (default) | scoop | bevel | notch | square | squircle */
}
Teknik seçme
text-decoration(çizgi, mürekkep atlama, boşluklar, içe yerleştirme): Çizgi, metin boyunca uzanmalı, metni sarmalı ve yazı tipi metriklerini takip etmelidir. Bu, varsayılan seçimdir.border-shapeveclip-pathiçeren sözde öğe: Çizgi, özel bir şekildir veya çizim animasyonu gerektirir. Bu seçeneği yalnızcatext-decoration-style, ek konumlandırma gerektiği için görünümü oluşturamadığında kullanın.background-clip: border-area: Metnin gradyan ana hattı olması gerekir. Düz bir ana hat yeterli olduğunda düzborder-colorkullanın.corner-shape: Yalnızca köşelerin farklı bir şekle (ör. eğimli, oyuk veya çentikli) sahip olması gerekir. Köşe boyutunu ayarlayanborder-radiusile birlikte kullanın.border-shape: Ana hat içinborder-radiusaracının çizemeyeceği bir şekil (ör. etiket veya ok) gerekiyor. Yuvarlatılmış köşeler yeterli olduğundaborder-radiuskullanın.- İçeride fareyle üzerine gelindiğinde göster: Bir bağlantının, renk değişikliğinin ötesinde fareyle üzerine gelme imkanı sunması gerektiğinde eklemeye değer. Etkileşimli olmayan metinler için bu adımı atlayın.
Yedek Stratejiler
Her yedek, metnin okunabilirliğini ve temel dekorasyonunu korur. İhtiyacı Baseline hedefinize göre çerçeveleyin: Bir özellik içermeyen tarayıcılar varsa eşleşen yedek değeri uygulayın.
Mürekkep atlama all
Baseline hedefiniz text-decoration-skip-ink: all özelliğini desteklemiyorsa beyan yoksayılır ve tarayıcı auto özelliğini kullanmaya devam eder. Latin alfabesindeki alt uzantılar yine atlanır. Yalnızca auto tarafından kapsanmayan alfabelerde (ör. Japonca) mürekkep atlama özelliği devre dışı bırakılır. Bu, kontrollü azalma olduğundan ek kod gerekmez.
Alanları atla
Baseline hedefiniz text-decoration-skip-spaces özelliğini desteklemiyorsa tarayıcı, boşlukları kendi varsayılan işleme yöntemini kullanır. Bu, kontrollü azalmadır: Çizgi, tarayıcının atlamadığı boşlukların altına çizilir.
İçe doğru
Temel hedefiniz text-decoration-inset özelliğini desteklemiyorsa bildirim yok sayılır. Bu nedenle, bağlantı normal ve tamamen görünür alt çizgisini korur ve geçişte animasyon uygulanacak bir şey olmaz. Bu, kontrollü azalmadır: Fareyle üzerine gelindiğinde gösterilen içerik kaybolur ve bağlantının altı çizili kalır.
Sınır bölgesi
Referans hedefiniz background-clip: border-area özelliğini desteklemiyorsa bildirim yoksayılır ve arka plan, yalnızca metnin ana hattını değil, metnin tamamını doldurarak tüm kenarlık kutusunun altına boyanır. Gradyan, tasarımın bir parçasıysa düz renkli bir kenarlıkla yetinmeyin. Bunun yerine, gradyanı yeniden oluşturun ve background-clip: border-area efektini yalnızca @supports içinde uygulayın.
Öğenin arka planı bilinen düz bir renk olduğunda opak bir katman kullanın. Yüzey rengini dolgu kutusunun üzerine ve gradyanı kenarlık kutusunun altına boyayın. Böylece gradyan yalnızca şeffaf kenarlıktan görünür:
.ring {
border: var(--ring-width, max(2px, 0.12em)) solid transparent; /* Example width */
/* Fallback: an opaque surface layer hides the gradient inside the border. */
background:
linear-gradient(var(--surface, canvas) 0 100%) padding-box,
linear-gradient(135deg, var(--ring-start, #2563eb), var(--ring-end, #db2777)) border-box;
}
@supports (background-clip: border-area) {
.ring {
background: linear-gradient(135deg, var(--ring-start, #2563eb), var(--ring-end, #db2777)) border-box;
background-clip: border-area; /* The inside stays transparent */
}
}
İç kısmın şeffaf kalması gerektiğinde maskelenmiş bir sözde öğe kullanın. Sözde öğe, gradyanı taşır ve bir maske, dolgu halkası dışındaki her şeyi keser:
@supports not (background-clip: border-area) {
.ring {
position: relative;
border-color: transparent;
}
.ring::before {
content: "";
position: absolute;
inset: calc(var(--ring-width, max(2px, 0.12em)) * -1); /* Cover the border box */
padding: var(--ring-width, max(2px, 0.12em)); /* Ring thickness */
border-radius: inherit;
background: linear-gradient(135deg, var(--ring-start, #2563eb), var(--ring-end, #db2777));
/* Keep only the area between the content box and the border box. */
mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
mask-composite: exclude;
pointer-events: none;
}
}
Kenarlık şekli
Baseline hedefiniz border-shape özelliğini desteklemiyorsa bildirim yok sayılır ve öğe, dikdörtgen kenarlığını korur. Yuvarlak dikdörtgen, yalnızca şekil tamamen dekoratif olduğunda kabul edilebilir bir yedektir. Şekil bir anlam taşıyorsa (ör. etiket, ok veya açıklama) mümkün olduğunca benzer şekilde yeniden oluşturun ve border-shape özelliğini yalnızca @supports içinde uygulayın.
Kırpılmış bir sözde öğeyle dış çizgiyi çizin. Kutunun desteklenen durumdakiyle aynı boyutta olması için şeffaf bir kenarlık kullanın, sözde öğeyi dış çizgi rengiyle doldurun ve evenodd clip-path ile bir halka şeklinde kesin: dış şekil, ardından kontur genişliği kadar içe yerleştirilmiş aynı şekil.
.tag {
--stroke: max(2px, 0.08em); /* Example stroke width */
position: relative;
padding: 0.2em 1.5em 0.2em 0.9em; /* Example values */
border: var(--stroke) solid transparent;
}
@supports not (border-shape: circle(50%)) {
.tag::before {
content: "";
position: absolute;
inset: calc(var(--stroke) * -1); /* Cover the border box */
background: var(--shape-color, currentColor);
pointer-events: none;
/* Outer shape, then the inner shape inset by the stroke. The inner points are approximate on
diagonal edges, so the stroke looks slightly thinner there. */
clip-path: polygon(evenodd,
0 0, 85% 0, 100% 50%, 85% 100%, 0 100%,
var(--stroke) var(--stroke),
calc(85% - var(--stroke)) var(--stroke),
calc(100% - var(--stroke) * 2) 50%,
calc(85% - var(--stroke)) calc(100% - var(--stroke)),
var(--stroke) calc(100% - var(--stroke)));
}
}
@supports (border-shape: circle(50%)) {
.tag {
border-color: var(--shape-color, currentColor);
border-shape: polygon(0 0, 85% 0, 100% 50%, 85% 100%, 0 100%);
}
}
Ana hat yerine içi dolu bir şekil için aynı noktalara sahip clip-path: polygon(...) öğesini doğrudan öğenin üzerine yerleştirin.
Sözde öğe alt çizgisi için .draw::after üzerinde border-block-end ile düz bir çizgi çizin ve block-size, border ve border-shape dalgalı çizgisini yalnızca @supports (border-shape: circle(50%)) içinde uygulayın. Çizgi düzdür ancak clip-path animasyonu şekle bağlı olmadığı için çizilmeye devam eder.
clip-path, odak halkalarını ve box-shadow öğesini de kırpar. Odağı göstermek için kırpılan öğenin dış çizgisine güvenmeyin. Bunun yerine :focus-visible öğesini renk veya arka plan değişikliğiyle şekillendirin.