close

Type fundamentals

Text is the primary way of communicating within GitLab. A thoughtful use of semantics and visual hierarchy can provide consistency and clarity to aid in comprehension and action.

Typefaces

Custom typefaces support a consistent core experience for users, regardless of their device. A finer control of font size, variable weight, and other attributes like disambiguation enable greater optimization of usability and polish.

The typefaces were chosen because:

  • Tall x-height that improves legibility at small sizes and readability of mixed- and lower-case text.
  • Features that include character disambiguation and OpenType Font Variations.
  • Balanced and complementary pairing that supports the GitLab brand expression.
  • Open source.

GitLab Sans

GitLab Sans, based on Inter, is used for most user interface (UI) elements, with system fonts used as a back-up.

The quick orange tanuki jumps over the lazy dog. 1234567890

Sans serif font stack

font-family: 'GitLab Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Noto Sans',
  Ubuntu, Cantarell, 'Helvetica Neue', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji',
  'Segoe UI Symbol', 'Noto Color Emoji';

GitLab Mono

GitLab Mono, based on JetBrains Mono, is used for code-related elements, for example, code blocks, branch names, commit IDs, and pipeline IDs. The fonts are available to download in this package.

The quick orange tanuki jumps over the lazy dog. 1234567890

Monospace font stack

font-family: 'GitLab Mono', 'Menlo', 'DejaVu Sans Mono', 'Liberation Mono', 'Consolas',
  'Ubuntu Mono', 'Courier New', 'andale mono', 'lucida console', monospace;

Download the GitLab fonts ↗︎

Type scales

GitLab utilizes two type scales: dynamic and fixed.

  • The dynamic scale is used for any UI text within GitLab. The 500800 options rely on the viewport width to dynamically change size between the min and max.
  • The fixed scale is used for Markdown (user generated content). Sizes match the min of the dynamic scale.
Design token Dynamic scale Fixed scale Use
Min Max
font.size.100 12px 12px 12px Meta text, small labels
font.size.200 13px 13px 13px Level 6 headings
font.size.300 14px 14px 14px Level 5 headings, body text, input labels, help text
font.size.400 16px 16px 16px Level 4 headings, large body text
font.size.500 18px 20px 18px Level 3 headings
font.size.600 21px 25px 21px Level 2 headings
font.size.700 24px 30px 24px Level 1 headings, limited to one per page (see Semantics).
font.size.800 28px 36px 28px A display option that can be applied to a level 1 heading to increase its prominence. This can be useful for a learning path or feature promotion. Limited to one per page.

Note that in implementation the variables use rem values (relative units) instead of pixels (absolute units), so that text respects browser settings for size and scale.

Font-size

Text size is determined by the following parameters:

  • Content type:
    • UI: default
    • Markdown: markdown
    • Compact Markdown: compact-markdown
  • Media breakpoints:
    • min-width: 0: default
    • min-width: 768px: md
    • min-width: 992px: lg
    • min-width: 1200px: xl
  • Font family:
    • Regular: default
    • Monospace: monospace
  • Element type:
    • small paragraph / UI text: sm
    • medium paragraph / UI text: default
    • large paragraph / UI text: lg
    • headers: h1..h6

Font weight

GitLab uses contrasting font weights to support visual hierarchy within the application. Generally, two weights are used by default: 400 and 600.

Value Use
400 Body copy and data tables
600 Headings and specific UI elements, such as an input label

Line-height

TODO:
Add line height details. Create an issue

Text color

There are a number of text colors defined in GitLab. Color choice depends on the location and purpose of the text.

Sample
Name
Value
text.color.danger

Used for text indicating a problem, critical state, destructive action, error, failure, removal, stop, or declination.

  • Figma: text-color-danger
  • CSS: var(--gl-text-color-danger)
  • SCSS: $gl-text-color-danger
  • color.red.600
  • color.red.300
text.color.default

Used for the default text color.

  • Figma: text-color-default
  • CSS: var(--gl-text-color-default)
  • SCSS: $gl-text-color-default
  • color.neutral.800
  • color.neutral.50
text.color.disabled

Used for disabled text.

  • Figma: text-color-disabled
  • CSS: var(--gl-text-color-disabled)
  • SCSS: $gl-text-color-disabled
  • color.neutral.400
  • color.neutral.400
text.color.heading

Used for headings level 1-6.

  • Figma: text-color-heading
  • CSS: var(--gl-text-color-heading)
  • SCSS: $gl-text-color-heading
  • color.neutral.950
  • color.neutral.0
text.color.strong

Used for text with the highest contrast.

  • Figma: text-color-strong
  • CSS: var(--gl-text-color-strong)
  • SCSS: $gl-text-color-strong
  • color.neutral.950
  • color.neutral.0
text.color.subtle

Used for supplemental text that doesn't need to be as prominent as other text.

  • Figma: text-color-subtle
  • CSS: var(--gl-text-color-subtle)
  • SCSS: $gl-text-color-subtle
  • color.neutral.600
  • color.neutral.200
text.color.success

Used for text indicating success, completion, approval, addition, or validity.

  • Figma: text-color-success
  • CSS: var(--gl-text-color-success)
  • SCSS: $gl-text-color-success
  • color.green.600
  • color.green.300
text.color.warning

Used for text that requires caution or careful attention.

  • Figma: text-color-warning
  • CSS: var(--gl-text-color-warning)
  • SCSS: $gl-text-color-warning
  • color.orange.600
  • color.orange.300
text.primary Deprecated

Use text.color.default instead.

  • Figma: ⚠️ DEPRECATED/text-primary
  • CSS: var(--gl-text-primary)
  • SCSS: $gl-text-primary
  • text.color.default
  • text.color.default
text.secondary Deprecated

Use text.color.subtle instead.

  • Figma: ⚠️ DEPRECATED/text-secondary
  • CSS: var(--gl-text-secondary)
  • SCSS: $gl-text-secondary
  • text.color.subtle
  • text.color.subtle
text.tertiary Deprecated

Use text.color.disabled instead.

  • Figma: ⚠️ DEPRECATED/text-tertiary
  • CSS: var(--gl-text-tertiary)
  • SCSS: $gl-text-tertiary
  • text.color.disabled
  • text.color.disabled

The disabled text color has a 3.52 contrast ratio on white, which falls short of the 4.5:1 ratio needed to pass WCAG 2.2 SC 1.4.3 Contrast (Minimum) (Level AA). Disabled (inactive) elements are not required to have sufficient contrast, but we try to get as close as possible while still visually differentiating active and inactive text. Refer to the forms pattern details for more information about placeholder text.

Code reference

Typography is the most common place to accidentally rebuild the design system: a size, a weight, a line height, and a color together look like an ordinary set of utilities, but they reproduce a decision the type scale already made.

Utilities

PurposeUtilities
Text sizegl-text-100 to gl-text-800, and the gl-text-sm, gl-text-base, and gl-text-lg aliases
Weightgl-font-normal (400), gl-font-bold (600)
Line heightgl-leading-16, gl-leading-20, gl-leading-24, and the rest of the scale, gl-leading-heading
Familygl-font-monospace
Colorgl-text-default, gl-text-subtle, gl-text-strong, gl-text-heading, gl-text-link, gl-text-disabled
Wrappinggl-truncate, gl-break-anywhere, gl-wrap-anywhere, gl-whitespace-nowrap
Alignmentgl-text-left, gl-text-center, gl-text-right

Heading utilities are covered in headings. gl-text-100 to gl-text-800 map to the font.size steps of the type scale; gl-text-sm, gl-text-base, and gl-text-lg are aliases for 100, 300, and 400. gl-text-base is the default UI body size. gl-text-xs is below the type scale — don't use it.

Steps from 500 up are fluid: they scale with the viewport. Use the matching gl-text-100-fixed to gl-text-800-fixed utilities for Markdown and other user-generated content.

Size text from the scale

Text size utilities set font-size only; they don't carry a line height. Where the default line height isn't right for the size, pair it with a gl-leading-* value from the scale rather than a number of your own.

Do
<p class="gl-text-base gl-leading-20 gl-text-default">
  This job ran on a shared runner and finished in 3 minutes. Retry it to pick up the latest
  configuration.
</p>
Don’t
<p class="gl-text-base" style="line-height: 1.4">
  This job ran on a shared runner and finished in 3 minutes. Retry it to pick up the latest
  configuration.
</p>

Use the documented weights

The product uses two weights: 400 for body copy and data tables, and 600 for headings and specific UI elements such as input labels.

Do
<span class="gl-font-bold">Total</span>
Don’t
<span class="gl-font-semibold">Total</span>

gl-font-bold is 600 in this preset, not 700. gl-font-semibold resolves to 500, which isn't one of the two weights the type system defines, so it reads as a near-miss against everything around it.

Weight is also not emphasis. Use <strong> or <em> when the meaning matters, so the emphasis reaches assistive technology as well as the eye.

Use semantic text colors

Text color follows the same rule as everything else: semantic utilities only. See color for the full set and type fundamentals for what each one is for.

Do
<p class="gl-text-subtle">Updated 2 hours ago</p>
Don’t
<p class="gl-text-gray-500">Updated 2 hours ago</p>

Handle long text deliberately

Branch names, project paths, and user-entered values have no length limit.

  • gl-truncate for single-line truncation with an ellipsis. When it sits inside a flex item, that item needs gl-min-w-0 — see truncate inside a flex container.
  • gl-break-anywhere or gl-wrap-anywhere for long unbroken strings that must stay fully visible.
  • gl-whitespace-nowrap only where wrapping would break meaning, such as a keyboard shortcut. It makes the element as wide as its content, so it needs a container that can handle that.

Truncated text always needs another way to read the full value. A tooltip is enough for reference content; if the user needs the value to complete a task, keep it available in the UI.

Common pitfalls

Styling visually hidden text

<span class="gl-sr-only gl-text-lg gl-font-bold">3 open issues</span>

gl-sr-only removes the element from the visual layout, so neither the weight nor the size has any effect. Screen readers don't convey visual styling. Remove the styling and keep the class list honest about what the element does.

Two size or color utilities on the same element

<p class="gl-text-base gl-text-sm">Which size is this?</p>
<p class="gl-text-danger gl-text-subtle">Which color is this?</p>

Each pair sets one property twice. The winner is decided by the order of the compiled stylesheet, not the order in the class attribute, so you can't tell which value applies by reading the markup — here gl-text-sm wins the first pair and gl-text-subtle wins the second. The color pair is also a design question rather than a formatting one: subtle and danger express different intents, so decide which one the text is. See declare each property once for how your editor can flag these as you type.

Last updated at: