Text

A powerful typography component for headings, paragraphs, blockquotes, and inline text with complete styling control.

Key Features

  • Semantic HTML — h1-h6, p, blockquote, span, div, section, article
  • Responsive Headings — automatically scale at larger breakpoints
  • Full Typography Control — size, weight, color, alignment, font, leading, tracking
  • Transforms & Decoration — uppercase, underline, italic, and more
  • Visual Variants — solid, outline, ghost, soft, link, strong, subtle
  • Icon & Badge Slots — leading/trailing icons with automatic color inheritance
  • Gradient Text — apply gradient effects to entire text or specific words
  • Prose Mode — optimal typography for long-form articles
  • Accessibility-First — ARIA role/level added automatically for headings

Basic Usage

The text component accepts positional text, a keyword text: argument, or a block. By default it renders a paragraph element.

Basic Usage
<%= rui_text("Hello World") %>

<%# as: sets the HTML element %>
<%= rui_text("Heading", as: :h2, color: :primary) %>

<%# tag: is an alias for as: — use whichever reads more naturally %>
<%= rui_text("Heading", tag: :h2, color: :primary) %>

<%= rui_text(size: :lg, weight: :bold) do %>
  Bold large paragraph
<% end %>

<%# Keyword argument instead of positional %>
<%= rui_text(text: "Keyword text", as: :span) %>

Hello World

Heading

Bold large paragraph

Keyword text

Headings

Use as: :h1 through as: :h6 for semantic headings. They are responsive (scale up at md: breakpoint) and automatically include role="heading" with aria-level. Prefer tag: if that reads more naturally — it is an alias for as:.

Headings h1–h6
<%= rui_text("Heading 1", as: :h1) %>
<%= rui_text("Heading 2", as: :h2) %>
<%= rui_text("Heading 3", as: :h3) %>
<%= rui_text("Heading 4", as: :h4) %>
<%= rui_text("Heading 5", as: :h5) %>
<%= rui_text("Heading 6", as: :h6) %>

Heading 1

Heading 2

Heading 3

Heading 4

Heading 5
Heading 6

Built-in Heading Scale

Each heading level has a fixed responsive size and default weight. The size: param has no effect on headings — they always use this scale.

Element Mobile size md: size Default weight
h1text-5xltext-6xlextrabold
h2text-4xltext-5xlbold
h3text-3xltext-4xlbold
h4text-2xltext-3xlsemibold
h5text-xltext-2xlsemibold
h6text-lgtext-xlsemibold

Need a different heading size?

Use class: to override. The component uses tw_merge, so your class wins over the built-in scale.

Override heading size via class:
<%# Hero heading — bigger than the built-in h1 scale %>
<%= rui_text("Hero Title", as: :h1, color: :primary, class: "text-7xl md:text-9xl") %>

<%# Compact heading — smaller than the built-in h2 scale %>
<%= rui_text("Sidebar heading", as: :h2, class: "text-xl md:text-2xl") %>

Override Heading Weight

Unlike size:, weight: works on headings — it overrides the level default.

Custom Heading Weights
<%= rui_text("Lightweight H1", as: :h1, weight: :light) %>
<%= rui_text("Normal-weight H2", as: :h2, weight: :normal) %>
<%= rui_text("Black-weight H4", as: :h4, weight: :black) %>

Lightweight H1

Normal-weight H2

Black-weight H4

Paragraphs

Without as:, text renders as a paragraph (or span when inline: true). Use size: and weight: for additional control.

Paragraphs
<%= rui_text("Default paragraph") %>
<%= rui_text("Large paragraph", size: :lg) %>
<%= rui_text("Small muted paragraph", size: :sm) %>

<%# Inline rendering with a span %>
<%= rui_text("Inline span text", inline: true) %>
<%= rui_text("Also inline", as: :span) %>

Default paragraph with normal size and weight. Includes bottom margin and proper line height.

Large paragraph with increased font size for emphasis.

Small paragraph, perfect for captions and secondary information.

Inline: inline: true renders a span with no block margin.

Colors

All semantic and Tailwind colors are supported via ColorBuilderHelper, with automatic dark mode.

Semantic Colors

Semantic Colors
<%= rui_text("Primary",   color: :primary) %>
<%= rui_text("Secondary", color: :secondary) %>
<%= rui_text("Success",   color: :success) %>
<%= rui_text("Danger",    color: :danger) %>
<%= rui_text("Warning",   color: :warning) %>
<%= rui_text("Info",      color: :info) %>

Primary

Secondary

Success

Danger

Warning

Info

Neutral

Tailwind Colors

Tailwind Colors
<%= rui_text("Red",    color: :red) %>
<%= rui_text("Orange", color: :orange) %>
<%= rui_text("Amber",  color: :amber) %>
<%= rui_text("Green",  color: :green) %>
<%= rui_text("Teal",   color: :teal) %>
<%= rui_text("Blue",   color: :blue) %>
<%= rui_text("Indigo", color: :indigo) %>
<%= rui_text("Purple", color: :purple) %>
<%= rui_text("Pink",   color: :pink) %>

Red

Orange

Amber

Yellow

Lime

Green

Emerald

Teal

Cyan

Sky

Blue

Indigo

Violet

Purple

Fuchsia

Pink

Rose

Black & White

Black & White
<%= rui_text("White text", color: :white) %>
<%= rui_text("Black text", color: :black) %>

White text on dark background

No shade variants — consistent in both light and dark mode.

Black text on light background

Pure black for maximum contrast.

Sizes

10 sizes from :xs to :xl6 for paragraphs, spans, and divs. Default is :base.

size: does not work on headings

When as: :h1:h6 is set, the size: param is ignored entirely. Headings use their own fixed responsive scale. See the Headings section for the scale and how to override with class:.

Invalid sizes silently fall back to :base

Only :xs :sm :base :lg :xl :xl2 :xl3 :xl4 :xl5 :xl6 are valid. Anything else (e.g. :xl9, :xl7) resets to :base without an error.

Sizes
<%= rui_text("Extra Small",    size: :xs) %>
<%= rui_text("Small",          size: :sm) %>
<%= rui_text("Base (default)", size: :base) %>
<%= rui_text("Large",          size: :lg) %>
<%= rui_text("Extra Large",    size: :xl) %>
<%= rui_text("2XL",            size: :xl2) %>
<%= rui_text("3XL",            size: :xl3) %>
<%= rui_text("4XL",            size: :xl4) %>
<%= rui_text("5XL",            size: :xl5) %>
<%= rui_text("6XL",            size: :xl6) %>
xs — text-xs sm — text-sm base — text-base (default) lg — text-lg xl — text-xl xl2 — text-2xl xl3 — text-3xl xl4 — text-4xl xl5 — text-5xl xl6 — text-6xl

Font Weights

Nine font weight options from thin (100) to black (900). Headings apply weight automatically by level; use weight: to override.

Font Weights
<%= rui_text("Thin (100)",       weight: :thin) %>
<%= rui_text("Extralight (200)", weight: :extralight) %>
<%= rui_text("Light (300)",      weight: :light) %>
<%= rui_text("Normal (400)",     weight: :normal) %>
<%= rui_text("Medium (500)",     weight: :medium) %>
<%= rui_text("Semibold (600)",   weight: :semibold) %>
<%= rui_text("Bold (700)",       weight: :bold) %>
<%= rui_text("Extrabold (800)",  weight: :extrabold) %>
<%= rui_text("Black (900)",      weight: :black) %>

Thin (100) — font-thin

Extralight (200) — font-extralight

Light (300) — font-light

Normal (400) — font-normal

Medium (500) — font-medium

Semibold (600) — font-semibold

Bold (700) — font-bold

Extrabold (800) — font-extrabold

Black (900) — font-black

Alignment

Control text alignment with align:. The default is :left.

Alignment
<%= rui_text("Left aligned (default)", align: :left) %>
<%= rui_text("Center aligned",         align: :center) %>
<%= rui_text("Right aligned",          align: :right) %>
<%= rui_text("Justified text",         align: :justify) %>

Left aligned — default, no class emitted

Center aligned

Right aligned

Justified — this text is longer to show how justify spreads words across the full container width.

Transforms & Decoration

Apply CSS text-transform (transform:), text-decoration (decoration:), and italic: styling.

Text Transform

Text Transform
<%= rui_text("uppercase text",   transform: :uppercase) %>
<%= rui_text("LOWERCASE TEXT",   transform: :lowercase) %>
<%= rui_text("capitalize words", transform: :capitalize) %>
<%= rui_text("Normal Case",      transform: :normal) %>

uppercase — adds CSS uppercase

LOWERCASE — adds CSS lowercase

capitalize each word

normal-case — resets inherited transforms

Text Decoration

Text Decoration
<%= rui_text("Underlined text",    decoration: :underline) %>
<%= rui_text("Overlined text",     decoration: :overline) %>
<%= rui_text("Strikethrough text", decoration: :line_through) %>
<%= rui_text("No decoration",      decoration: :none) %>

Underlined text

Overlined text

Strikethrough text

No decoration (overrides inherited underlines)

Italic

Italic
<%= rui_text("Italic text", italic: true) %>

<%# Combine with transform or decoration %>
<%= rui_text("Italic uppercase", italic: true, transform: :uppercase) %>
<%= rui_text("Italic underline", italic: true, decoration: :underline) %>

Italic text

Italic and uppercase combined

Italic with underline decoration

Typography

Fine-tune typography with font: (font family), leading: (line height), and tracking: (letter spacing).

Font Family

Font Family
<%= rui_text("Sans-serif (default)", font: :sans) %>
<%= rui_text("Serif font",           font: :serif) %>
<%= rui_text("Monospace font",       font: :mono) %>

Sans-serif — font-sans (default)

Serif — font-serif

Monospace — font-mono

Line Height (leading:)

leading: is an alias for line_height:. Applies leading-* Tailwind classes.

Line Height
<%= rui_text("leading: :none",    leading: :none) %>
<%= rui_text("leading: :tight",   leading: :tight) %>
<%= rui_text("leading: :snug",    leading: :snug) %>
<%= rui_text("leading: :normal",  leading: :normal) %>
<%= rui_text("leading: :relaxed", leading: :relaxed) %>
<%= rui_text("leading: :loose",   leading: :loose) %>

leading: :none — leading-none (1)

leading: :tight — leading-tight (1.25)

leading: :snug — leading-snug (1.375)

leading: :normal — leading-normal (1.5)

leading: :relaxed — leading-relaxed (1.625)

leading: :loose — leading-loose (2)

Letter Spacing (tracking:)

tracking: is an alias for letter_spacing:. Applies tracking-* Tailwind classes.

Letter Spacing
<%= rui_text("tracking: :tighter", tracking: :tighter) %>
<%= rui_text("tracking: :tight",   tracking: :tight) %>
<%= rui_text("tracking: :normal",  tracking: :normal) %>
<%= rui_text("tracking: :wide",    tracking: :wide) %>
<%= rui_text("tracking: :wider",   tracking: :wider) %>
<%= rui_text("tracking: :widest",  tracking: :widest) %>

tracking: :tighter — tracking-tighter (-0.05em)

tracking: :tight — tracking-tight (-0.025em)

tracking: :normal — tracking-normal (0)

tracking: :wide — tracking-wide (0.025em)

tracking: :wider — tracking-wider (0.05em)

tracking: :widest — tracking-widest (0.1em)

Combining Typography Options

Combined Typography
<%# Article-style heading %>
<%= rui_text("Article Title", as: :h2, weight: :light, tracking: :tight, leading: :snug) %>

<%# Label / caption style %>
<%= rui_text("SECTION LABEL", size: :xs, weight: :semibold, transform: :uppercase, tracking: :widest) %>

<%# Mono code inline %>
<%= rui_text("bundle exec rake test", font: :mono, size: :sm, color: :zinc) %>

Article Title

SECTION LABEL

bundle exec rake test

Variants

Visual variants add background colors, borders, and structural styling via ColorBuilderHelper.

Colored Variants

Five color-aware variants: solid, outline, ghost, soft, and link. Pair any variant with any color.

Colored Variants
<%= rui_text("Solid",   variant: :solid,   color: :primary) %>
<%= rui_text("Outline", variant: :outline, color: :success) %>
<%= rui_text("Ghost",   variant: :ghost,   color: :info) %>
<%= rui_text("Soft",    variant: :soft,    color: :warning) %>
<%= rui_text("Link",    variant: :link,    color: :primary) %>

Solid Primary

Solid Success

Solid Danger

Solid Warning

Solid Info

Outline Primary

Outline Success

Outline Danger

Outline Warning

Outline Info

Ghost Primary

Ghost Success

Ghost Danger

Ghost Warning

Ghost Info

Soft Primary

Soft Success

Soft Danger

Soft Warning

Soft Info

Link Primary

Link Success

Link Danger

Link Info

Simple Variants

Two non-color variants apply structural styling only.

Simple Variants
<%= rui_text("Default",          variant: :default) %>
<%= rui_text("Strong (bold)",    variant: :strong) %>
<%= rui_text("Subtle (muted)",   variant: :subtle) %>

Default — no variant class added

Strong — applies font-bold

Subtle — applies opacity-70 for a muted appearance

Accent

accent: true applies opacity-80 for a slightly dimmed appearance, useful for secondary text within a colored context.

Accent
<%= rui_text("Normal text", color: :primary) %>
<%= rui_text("Accent text", color: :primary, accent: true) %>

Normal text — full opacity

Accent text — opacity-80

Blockquotes

Render semantic blockquotes with a left border and italic style. Add cite: for an attribution footer.

Blockquotes
<%= rui_text(as: :blockquote) do %>
  To be or not to be, that is the question.
<% end %>

<%# With citation %>
<%= rui_text(as: :blockquote, cite: "William Shakespeare") do %>
  The fault, dear Brutus, is not in our stars, but in ourselves.
<% end %>

<%# Styled blockquote %>
<%= rui_text(as: :blockquote, cite: "Donald Knuth", color: :primary, font: :serif, size: :lg) do %>
  Premature optimization is the root of all evil.
<% end %>
To be or not to be, that is the question.
The fault, dear Brutus, is not in our stars, but in ourselves. William Shakespeare
Premature optimization is the root of all evil. Donald Knuth

With Icons

Add icons via the with_icon slot. Icons inherit text color by default. Use position: :leading (default) or :trailing.

With Icons
<%# Leading icon (default) %>
<%= rui_text("Featured Content", color: :info) do |t| %>
  <% t.with_icon(:star) %>
<% end %>

<%# Trailing icon %>
<%= rui_text("Learn More", color: :primary) do |t| %>
  <% t.with_icon(name: :arrow_right, position: :trailing) %>
<% end %>

<%# Icon inside a variant %>
<%= rui_text("Success!", variant: :solid, color: :success) do |t| %>
  <% t.with_icon(name: :check_circle, position: :leading) %>
<% end %>

Featured Content

Learn More

Warning Message

Success!

Gradient Text

Apply gradient effects with gradient:. Accepts a style symbol, a matching string, or a hash for word-level targeting.

Gradient Text
<%# Symbol — gradient applied to entire text %>
<%= rui_text("Beautiful Gradient", gradient: :ocean, size: :xl2, weight: :bold) %>

<%# String — gradient applied to the matched word only %>
<%= rui_text("Make it gradient today", gradient: "gradient") %>

<%# Hash — target a specific word with a specific style %>
<%= rui_text("Ocean vibes ahead", gradient: { text: "Ocean", style: :ocean }) %>

Sunset Gradient

Ocean Gradient

Forest Gradient

Sunrise Gradient

Aurora Gradient

Available gradient styles:

  • :sunset — purple → pink (default)
  • :ocean — yellow → blue → indigo
  • :forest — blue → teal → green
  • :sunrise — purple → orange → yellow
  • :aurora — purple → teal → red

Prose Mode

prose: true adds Tailwind's typography prose classes, giving automatic spacing and styling to raw HTML content inside the element.

Prose Mode
<%= rui_text(prose: true, as: :article) do %>
  <h2>Article Title</h2>
  <p>First paragraph with automatic prose styling...</p>
  <p>Second paragraph...</p>
  <ul>
    <li>List item one</li>
    <li>List item two</li>
  </ul>
<% end %>

The Power of Typography

Typography is the art and technique of arranging type to make written language legible, readable, and appealing when displayed.

Good typography establishes a strong visual hierarchy, provides a graphic balance to the website, and sets the product's overall tone.

  • Choose appropriate typefaces
  • Set proper line heights and spacing
  • Maintain readability across devices

Text Formatting (rui_text_fmt)

For data-driven text transformations — truncation, highlighting, number formatting, time-ago — use the companion rui_text_fmt component.

TextFmt Features

  • Truncate — limit text to N characters
  • Highlight — mark search terms with a colored background
  • Sanitize — strip dangerous HTML
  • Number Formatting — currency, percentage, phone numbers
  • Time Ago — "3 hours ago" format
  • Linkify — auto-convert URLs to links
  • Pluralize — "1 item" vs "5 items"
Text Formatting Examples
<%= rui_text_fmt("This is a very long text...", truncate: 30) %>
<%= rui_text_fmt(99.99, number_format: :currency) %>
<%= rui_text_fmt("Search for Rails in this text", highlight: "Rails") %>
<%= rui_text_fmt(Time.now - 2.hours, time_ago: true) %>
<%= rui_text_fmt("comment", pluralize: true, count: 5, variant: :soft, color: :info) %>

This is a very long text that will be truncated...

$99.99

Search for Rails in this Rails text

5 comments

API Reference

rui_text

Typography component for semantic, accessible text with full styling control.

Parameter Type Default Description
content String Text content — positional first arg, keyword text:, or block
as Symbol :p HTML element to render. Headings (h1–h6) are responsive and get ARIA role/level automatically.
:p :span :div :h1 :h2 :h3 :h4 :h5 :h6 :blockquote :section :article
tag Symbol Alias for as: — use whichever reads more naturally. as: takes priority if both are given.
inline Boolean false Force a span tag regardless of as:/tag: value — useful for inline text inside other elements

Typography

Font size, weight, family, line height, and letter spacing.

Parameter Type Default Description
size Symbol :base Font size. Ignored for heading elements (h1–h6), which use their own responsive scale.
:xs :sm :base :lg :xl :xl2 :xl3 :xl4 :xl5 :xl6
weight Symbol Font weight. Headings default by level (h1 → extrabold, h2/h3 → bold, h4–h6 → semibold); non-headings default to :normal.
:thin :extralight :light :normal :medium :semibold :bold :extrabold :black
font Symbol :sans Font family.
:sans :serif :mono
leading Symbol :normal Line height. Alias for line_height:. For headings, only takes effect when explicitly set.
:none :tight :snug :normal :relaxed :loose
line_height Symbol :normal Line height (prefer the leading: alias). Options same as leading:.
:none :tight :snug :normal :relaxed :loose
tracking Symbol :normal Letter spacing. Alias for letter_spacing:.
:tighter :tight :normal :wide :wider :widest
letter_spacing Symbol :normal Letter spacing (prefer the tracking: alias). Options same as tracking:.
:tighter :tight :normal :wide :wider :widest

Color

Text color and gradient effects via ColorBuilderHelper.

Parameter Type Default Description
color Symbol :primary Text color. Accepts any semantic color (:primary, :success, :danger, :warning, :info) or any Tailwind palette color (:red, :blue, :emerald, etc.).
gradient Symbol / String / Hash Gradient effect. Symbol applies to entire text; String matches a word; Hash { text:, style: } targets a specific word with a specific style.
:sunset :ocean :forest :sunrise :aurora
accent Boolean false Apply opacity-80 for a subtly dimmed appearance — useful for secondary text in a colored context.

Formatting

Text alignment, transform, decoration, and italic.

Parameter Type Default Description
align Symbol :left Text alignment. No CSS class is emitted for the default :left.
:left :center :right :justify
transform Symbol CSS text-transform.
:uppercase :lowercase :capitalize :normal
decoration Symbol CSS text-decoration. Use :line_through (underscore) not :line-through.
:underline :overline :line_through :none
italic Boolean false Apply CSS font-style: italic (adds the italic Tailwind class).

Variants

Visual styling presets. Colored variants (solid/outline/ghost/soft/link) require a color: value.

Parameter Type Default Description
variant Symbol :default Visual style. :solid, :outline, :ghost, :soft, :link use ColorBuilderHelper with the color: value. :strong adds font-bold. :subtle adds opacity-70.
:default :solid :outline :ghost :soft :link :strong :subtle

Special Modes

Prose mode and blockquote citation.

Parameter Type Default Description
prose Boolean false Apply Tailwind Typography prose classes for long-form content. When true, most other styling params are bypassed.
cite String Blockquote citation. Only used when as: :blockquote. Renders a <cite> element below the quote with an aria-describedby link.

Slots

Content slots for customizing component parts

Slot Description
with_icon Icon slot. Accepts name: (Lucide icon symbol) and position: (:leading or :trailing, default :leading). Icon inherits text color unless color: is explicitly set on the icon.
with_badge Badge slot. Appends a Badge component after the text content.

Related Components