Using the design system

This page shares how to get started with the arXiv Design System: basic markup, which files to link to, in what order, and a handful of things to avoid.

If you are an AI assistant, AGENTS.md at the repository root holds the file map in a form you can route from.

Core linked files

Every core file you need to include in your repo, and in what order.

Accessibility essentials

  • theme.js is not deferred. The script is deliberately not deferred because it writes the reader's theme onto <html> before the first paint. If we added defer then the page will render light first, and then flip if the reader chose dark mode in their system. Many readers choose dark mode because light mode is less legible or hurts their eyes and we want to honor that.

Basic page markup

This is all you need for a public arXiv page. Copy it and follow the comments.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Your page &mdash; arXiv</title>

  <link rel="stylesheet" href="fonts.css">
  <link rel="stylesheet" href="design-system.css">
  <script src="theme.js"></script>
</head>

<body class="ds-page">
  <div class="ds-container">
    <!-- add section elements as direct children here -->
  </div>
</body>
</html>

Accessibility essentials

  • Every section starts with a heading. Headings provide important navigation structure for screen reader users so a <section> without one is hard to find.
  • Naming sections (optional). A name on the section itself (aria-labelledby pointing at the heading) is optional, but useful for a section that a reader would want to jump to directly. Use your discretion. Every named section becomes an entry in the landmark list.
  • Write the name arXiv so that screen readers say “archive”. A screen reader reads the Xiv in our name as a Roman numeral. We can take a few steps to fix this:
    • For an image like the logo, add alt text that says “archive”.
    • Where the name is typed this markup will be pronounced correctly: <span aria-hidden="true">arXiv</span><span class="is-sr-only">archive</span>.
    • When arXiv's name appears in a paragraph of text that is likely to be copied (ie: citations) we unfortunately must keep it as plain text and live with the screen reader mis-pronunciation. This is because the hidden word is copied along with the visible one and would break every pasted citation.

Building on the foundation

Internal tools

When building internal tools like arXiv Check or Admin Console pages, one class is added to <html> and a tier 2 stylesheet is added to the <head> section, in this order.

<html lang="en" class="ds-internal">
…
<link rel="stylesheet" href="../fonts.css">
<link rel="stylesheet" href="../design-system.css">    <!-- tier 1 -->
<link rel="stylesheet" href="internal-tools.css">      <!-- tier 2 -->
<script src="../theme.js"></script>

internal-tools.css does not work on its own

internal-tools.css is not a standalone stylesheet. It is a lightweight file that holds only the special styles or overrides that are specific to internal tools. Load it on its own and you get no foundation at all.

  • The accent color defines internal pages. Access Lime is highly differentiated from the public site's Open Blue and clearly signals that you are in a different environment.
  • All you need is a parent class. .ds-internal re-points --ds-accent and its family to Access Lime, and every component inside it that reaches for the accent follows without being told. It works on any parent, so a page that shows both surfaces puts it on a wrapper instead of on <html>. There is no second copy of the button, the tag or the switch inside the tier 2 stylesheet: it is not needed. Just a handful of new styles and overrides, and that class on the wrapper, are enough.
  • Internal tools are compact. .ds-internal also sets less padding inside table cells and cards, through the density tokens (--ds-cell-padding, --ds-card-padding), so a dense screen holds more. There is no compact class: the density comes with the surface.
  • Never copy a component into the tier 2 stylesheet to restyle it. If it needs to look different on your surface, what you need is a token change, not a second copy. A component that exists twice creates drift and lots of sad devs.
  • Maintain the accent even on links to the other environment. Are you linking to the internal tools from a public page, or vice versa? Maintain the accent color and let the button label clearly tell the user where it will take them. See DESIGN-POLICIES.

Container options

.ds-container is a grid with various options for managing section layout.

  • Sections. The container's direct children are <section> elements, and the container sets the gap between them. Do not add top or bottom margins to sections, the container already does.
  • Full width. A coloured band that runs edge to edge gets .ds-full with a zone class (see Page zones). Do not add negative margins or use viewport units for placement. Using a calculation like calc(-50vw + 50%) overhangs the section band and causes the page to scroll sideways in some environments.
  • Page width. Width comes from --ds-width-page and --ds-gutter. Need to change the page width? Repoint one of the tokens, do not add a second width beside it.
<div class="ds-container">
<section>…</section>                   <!-- content track -->
<section class="ds-full ds-zone-secondary">…</section>  <!-- edge to edge, tinted -->
</div>

Combining components

Most areas of a page can be built by putting existing components together. Look for a combination before inventing a component.

  • Examples in these docs. The search form with the results' settings under it; a table with its toolbar of filters and bulk actions; a sidebar of accordions; a card that links, with a tag; secondary navigation with a compact filter bar.
  • Each component works inside another. Use a component's documented markup unchanged inside the other.
  • A new class is the last step. If a combination needs CSS, it is a rule on the outer component about what it can hold, written in the design system. Ask before adding a component.