Border
Draw a horizontal or vertical rule on any element with the border--h and border--v utilities, named on the same 10 to 75 shade scale as backgrounds. On 1-bit displays a step renders as a dither pattern of black and white pixels, so a rule can read as gray. 4-bit and full-color screens draw all 14 steps; the other rails pair them onto seven levels.
Usage
Use directional step selectors:
border--h-{step} and
border--v-{step}
with steps 10 to 75
(the background utility shade scale), plus semantic
border--h-black /
border--h-white.
Borders render grayscale by default; themes repaint the whole rail.
4-bit and full-color screens give each of the 14 steps its own art. Everywhere else (the default rail,
1-bit, 2-bit, and the limited palettes) the steps pair onto the seven border levels, so
border--h-40 and
border--h-45 draw the same line.
Pick steps two apart when two rules have to read differently on a 1-bit panel.
The numbered level classes (border--h-1 through
border--h-7, and their vertical counterparts) are
deprecated and will be removed in Framework 4.0. Prefer step selectors in new markup.
Horizontal Borders
<div class="border--h-10">Dark border</div>
<div class="border--h-45">Mid border</div>
<div class="border--h-75">Light border</div>
Vertical Borders
<div class="border--v-20">Vertical border</div>
<div class="border--v-65">Vertical border</div>
Themed Borders
There are no per-hue border classes: the step rail renders the classic
patterns by default, and a theme recolors them (and
.divider) without changing their
geometry via theme-slots.utility-remap-border-grayscale($hue, $side).
The dark side paints black-on-hue,
bright paints hue-on-white.
Pick a Style in the screen picker to watch the rails above repaint.
The 2-bit rail is the exception: its four tones are literal in the line data, so a hue remap leaves it black, white and two grays. That is deliberate, since a hue quantizes to gray on a 4-tone panel anyway.
A theme that wants to move the 2-bit rail names levels instead, with
theme-slots.utility-border-level($level, $dir, $from-level),
the way the shipped Dark theme does. See
Theme Slots
Theme Slots
Every themable surface: semantic channels, component slots, utility remaps, border lines, and the chart ramp
Every surface a theme can re-point, with the mixin that sets it: semantic channels, component slots, utility remaps, border lines, and the chart ramp. Slots take token references, so each one still resolves through the device mode at render time.
.
@include theme-slots.utility-remap-border-grayscale("yellow", $side: "dark");
@include theme-slots.utility-remap-border-grayscale("red", $side: "bright");
Black & White Borders
Semantic border--h-black /
border--h-white borders adapt to themes
automatically. They resolve through framework semantic fill tokens, so they always
represent the strongest and softest fill in the current theme context.
<div class="border--h-black">Black border (strongest fill)</div>
<div class="border--h-white">White border (softest fill)</div>
<div class="border--v-black">Black vertical border</div>
<div class="border--v-white">White vertical border</div>
Borders in JavaScript
Border rails are readable from JS through the paint API:
TRMNLPaint.border(spec, { dir }) resolves a step,
or the literal 'black' /
'white' rails straight from the live cascade
(theme tinting, bit depth and dark mode included), and
applyBorder() paints it onto a node. Because these
fill-backed utilities carry real ink in every mode, they are the reliable hairline source for JS-drawn visuals
like chart grids. See
Painting Borders
Painting Borders
Read border rails as BorderFill objects for custom rails and Highcharts axes
The border resolvers read the framework border rails as BorderFill objects. Apply them to custom rails, or convert them for Highcharts axes and grid lines.
.