sveltelean Primitives
Versionv0.2.0 GitHub

Example

A rule and separators between links

The first topic ends here.


A second topic starts after the rule.

<p>The first topic ends here.</p>
<hr data-slean="separator" />
<p>A second topic starts after the rule.</p>

<nav aria-label="Separator example" class="links">
	<a href="/primitives">Primitives</a>
	<div role="separator" aria-orientation="vertical" data-slean="separator"></div>
	<a href="/table">Table</a>
	<div role="separator" aria-orientation="vertical" data-slean="separator"></div>
	<a href="/styling">Styling</a>
</nav>
Tier 0: no script. The rule is an <hr>; the lines between the links are elements with role="separator" and aria-orientation="vertical", which is what the stylesheet reads.

Why this implementation exists

<hr> is a separator for assistive technology and a thematic break in the document; the browser draws it with an inset border that the stylesheet replaces with a one-pixel line. Between inline items there is no element for a vertical line, so the ARIA role takes its place, with the orientation set because the role defaults to horizontal.

The decision that matters is whether a separator is announced at all. Most lines in an interface only draw a boundary that the structure already makes, and hearing "separator" between every pair of links adds nothing. The contract names the two forms and how to silence one.

The browser owns

  • the separator role of <hr> and its horizontal orientation
  • the vertical orientation announced from aria-orientation
  • leaving a decorative separator out of the accessibility tree (aria-hidden)

Svelte Lean owns

  • separator.css: the one-pixel border, the spacing, the vertical line that fills its row
  • the contract: when a separator is announced and when it is decorative
  • documentation

Usage

The markup needs no package. Install @svelte-lean/styles for the stylesheet; @svelte-lean/primitives adds the typed contract and nothing at runtime.

npm install @svelte-lean/styles
stylesheets
import '@svelte-lean/styles/separator.css';

Use <hr> between blocks that change topic. Use the vertical form between items in a row, inside a flex container: the line takes the row’s height. In running text it is one line of text tall.

For a decorative line add aria-hidden="true". On an <hr>, role="none" has the same effect, but it cannot carry aria-orientation, so the vertical form uses aria-hidden.

Anatomy

PartElementdata-slean-partRequiredNotes
root<hr data-slean="separator">–yesHorizontal, between blocks. aria-hidden="true" when decorative.
vertical<div role="separator" aria-orientation="vertical">–noBetween inline items. The styles read aria-orientation.

Runtime profile

Tier 0: the separator has no behavior module, the Vite plugin maps separator to no module, and the native-only fixture proves the path ships no Svelte Lean JavaScript.

Accessibility contract

  • <hr> is exposed as a horizontal separator; the vertical form as a vertical separator from aria-orientation.
  • A static separator is not focusable and has no name.
  • A decorative separator with aria-hidden="true" is not in the accessibility tree.
  • A focusable separator with a value is a window splitter, which this primitive is not.

Keyboard

KeyWhenResult
TabanywherePasses the separator by: a static separator is not focusable (native)

Platform features

FeatureBaselineOutside the target
<hr>, role="separator", aria-orientationWidely availableNot applicable within the support policy

Without JavaScript

Fully functional.

Server rendering

Static HTML.

Before hydration

Nothing is attached.

Styling

separator.css removes the inset border of <hr>, draws a one-pixel border in the border token, sets the spacing, and turns an element with aria-orientation="vertical" into a line that fills its flex row. The tokens it reads:

TokenDefault (light)Applies to
--slean-space-41remmargin-block
--slean-bordervar(--slean-neutral-6)border-block-start, border-inline-start
--slean-space-20.5remmargin-inline

State selectors the stylesheet targets, all from the platform or ARIA: [aria-orientation="vertical"].

Compatibility notes

Everything here is widely available.

Examples

Decorative separators

A line that repeats a boundary the content already has is decoration. Add aria-hidden="true" so it is not announced, or draw it as a border in the application's CSS with no element at all.

decorative.html
<!-- The names already read as separate items; the line only draws that boundary. -->
<p class="byline">
	<span>Amara Okafor</span>
	<span role="separator" aria-orientation="vertical" data-slean="separator" aria-hidden="true"></span>
	<span>Design team</span>
</p>

<!-- The same line in the application's CSS, with no element. -->
<style>
	.byline > span + span {
		border-inline-start: 1px solid var(--slean-border);
		padding-inline-start: 0.5rem;
	}
</style>

Testing

Source