sdxc

[ @sdxc/u/typography ]

text-decoration-line

Applies text-decoration-line from a bare value, or sets only the given keys from a text-decoration options object.

import { textDecoration } from "@sdxc/u/typography";

Quick reference

Every documented call, beside the CSS it emits.

CallCSS
u.textDecoration()css({ textDecorationLine: "underline" })
u.textDecoration("line-through")css({ textDecorationLine: "line-through" })
u.textDecoration({ line: "underline", color: "brand", offset: 3 })css({ textDecorationLine: "underline", textDecorationColor: "var(--ui-brand-fg)", textUnderlineOffset: "3px" })
u.textDecoration({ style: "wavy", color: "danger", thickness: "from-font" })css({ textDecorationStyle: "wavy", textDecorationColor: "var(--ui-danger-fg)", textDecorationThickness: "from-font" })

Examples

Basic example

Use textDecoration(line) to draw a line on text: textDecoration() underlines, and "overline" and "line-through" draw above and across it:

textDecoration()

The quick brown fox jumps over the lazy dog.

textDecoration("overline")

The quick brown fox jumps over the lazy dog.

textDecoration("line-through")

The quick brown fox jumps over the lazy dog.

<div mix={[...]}>
	<div>
		<p mix={[...]}>textDecoration()</p>
		<p mix={[textDecoration(), text("xl")]}>The quick brown fox jumps over the lazy dog.</p>
	</div>
	<div>
		<p mix={[...]}>textDecoration("overline")</p>
		<p mix={[textDecoration("overline"), text("xl")]}>
			The quick brown fox jumps over the lazy dog.
		</p>
	</div>
	<div>
		<p mix={[...]}>textDecoration("line-through")</p>
		<p mix={[textDecoration("line-through"), text("xl")]}>
			The quick brown fox jumps over the lazy dog.
		</p>
	</div>
</div>

Decoration color

Pass an options object with a color from the theme, like textDecoration({ line: "underline", color: "brand" }), to tint the line apart from the text:

Our bakery opens at seven, and the weekly menu changes every Monday. Anything with nuts is marked, and the allergen list covers the rest.

<p mix={[maxIs(96), ...]}>
	Our bakery opens at seven, and the{" "}
	<a href="/weekly-menu" mix={[textDecoration({ line: "underline", color: "brand" })]}>
		weekly menu
	</a>{" "}
	changes every Monday. Anything with nuts is marked, and the{" "}
	<a href="/allergen-list" mix={[textDecoration({ line: "underline", color: "danger" })]}>
		allergen list
	</a>{" "}
	covers the rest.
</p>

Decoration style

Set style to "solid", "double", "dotted", "dashed" or "wavy" to change how the line is drawn:

The quick brown fox jumps over the lazy dog.

The quick brown fox jumps over the lazy dog.

The quick brown fox jumps over the lazy dog.

The quick brown fox jumps over the lazy dog.

The quick brown fox jumps over the lazy dog.

<div mix={[...]}>
	<p mix={[textDecoration({ line: "underline", style: "solid" }), text("xl")]}>
		The quick brown fox jumps over the lazy dog.
	</p>
	<p mix={[textDecoration({ line: "underline", style: "double" }), text("xl")]}>
		The quick brown fox jumps over the lazy dog.
	</p>
	<p mix={[textDecoration({ line: "underline", style: "dotted" }), text("xl")]}>
		The quick brown fox jumps over the lazy dog.
	</p>
	<p mix={[textDecoration({ line: "underline", style: "dashed" }), text("xl")]}>
		The quick brown fox jumps over the lazy dog.
	</p>
	<p mix={[textDecoration({ line: "underline", style: "wavy", color: "danger" }), text("xl")]}>
		The quick brown fox jumps over the lazy dog.
	</p>
</div>

Thickness and offset

Set thickness and offset in pixels, or pass "from-font" and "auto", to change how heavy the line is and how far below the text it sits:

thickness: 1, offset: 2

thickness: 2, offset: 4

thickness: 4, offset: 8

<div mix={[...]}>
	<p mix={[textDecoration({ line: "underline", thickness: 1, offset: 2 }), text("xl")]}>
		thickness: 1, offset: 2
	</p>
	<p mix={[textDecoration({ line: "underline", thickness: 2, offset: 4 }), text("xl")]}>
		thickness: 2, offset: 4
	</p>
	<p
		mix={[
			textDecoration({ line: "underline", thickness: 4, offset: 8, color: "brand" }),
			text("xl"),
		]}
	>
		thickness: 4, offset: 8
	</p>
</div>

Underlining on hover

Combine textDecoration("none") with hover(textDecoration({ line: "underline", offset: 4 })) to underline a link only while it is hovered. Hover the links to try it:

<nav mix={[...]}>
	<a
		href="/pricing"
		mix={[textDecoration("none"), hover(textDecoration({ line: "underline", offset: 4 }))]}
	>
		Pricing
	</a>
	<a
		href="/customers"
		mix={[textDecoration("none"), hover(textDecoration({ line: "underline", offset: 4 }))]}
	>
		Customers
	</a>
	<a
		href="/changelog"
		mix={[textDecoration("none"), hover(textDecoration({ line: "underline", offset: 4 }))]}
	>
		Changelog
	</a>
</nav>

Applying on a state

Wrap the call in a state utility to scope it to one selector.

u.hover(u.textDecoration())

Responsive design

Wrap the call in a container query to scope it to one width.

u.at("md", u.textDecoration())

Customizing your theme

Customizing colors

Define a palette as --ui-color-{name}-{50..950} and map a tone onto it with the --ui-{tone}-* variables, the way theme.css maps the built-in ones:

:root {
	--ui-color-info-50: oklch(0.97 0.02 230);
	--ui-color-info-200: oklch(0.88 0.06 230);
	--ui-color-info-500: oklch(0.62 0.16 230);
	--ui-color-info-600: oklch(0.52 0.18 230);
	--ui-color-info-900: oklch(0.3 0.1 230);

	--ui-info-bg-tint: var(--ui-color-info-50);
	--ui-info-bg-solid: var(--ui-color-info-600);
	--ui-info-fg: var(--ui-color-info-600);
	--ui-info-fg-muted: var(--ui-color-info-500);
	--ui-info-fg-emphasis: var(--ui-color-info-900);
	--ui-info-fg-on-solid: white;
	--ui-info-border: var(--ui-color-info-200);
	--ui-info-border-strong: var(--ui-color-info-600);
	--ui-info-ring: var(--ui-color-info-500);
}
declare module "@sdxc/u" {
	interface ColorPalettes {
		info: true;
	}
	interface SemanticTones {
		info: true;
	}
}

The new name is then accepted wherever the scale is:

bg("info")

Signature

u.textDecoration(value?: TextDecorationLineValue)

Written by Sergio Xalambrí. Follow @sergiodxa for new packages, or sponsor the work.