# Iris CSS documentation Every Iris CSS docs page in one file, for AI tools. Source: https://iriscss.com/documentation/ --- ## Iris CSS: rules for AI assistants Read this before you write HTML or CSS for a page that uses Iris CSS. Full docs: https://iriscss.com/llms.txt ### How Iris CSS works - Plain semantic HTML is styled with no classes. Write the right element first: `button`, `form`, `label`, `table`, `dialog`, `details`, `nav`, `article`, `header`, `footer`. - Classes are optional modifiers with no prefix: `.primary`, `.outlined`, `.large`. Add one only for a variant or a component that HTML has no element for. - Custom properties carry the `--i-` prefix, such as `--i-color-primary` or `--i-spacing`. Change the look by overriding them, on `:root` for the whole page or on one element. - Light and dark mode are automatic. `data-theme="light"` or `data-theme="dark"` (or the `.light` and `.dark` classes) forces a theme on any element and everything inside it. - Every Iris rule is in a cascade layer, so plain CSS you write wins without `!important` or extra specificity. - Interactive components use native HTML: `popover`, `dialog` with invoker commands, `details`. They need no JavaScript. ### Do not - Do not use classes from other frameworks. `.btn`, `.btn-primary`, `.row`, `.col-md-6`, `.d-flex`, `.mt-3`, `.p-4`, `.text-gray-500`, `.navbar-nav`, `.form-control`, `.modal-dialog` and Tailwind utilities do nothing in Iris CSS. - Do not invent classes. If a class is not listed below, it does not exist. Use plain CSS for anything else. - Do not add classes to elements that are already styled. ` ``` ### Theme colors Colors that change with the theme are `light-dark()` pairs. Override them with a pair of your own, or with one value to use it in both themes. See [themes](https://iriscss.com/documentation/customize/themes/index.html.md) for the full list. ```css :root { --i-color-primary: light-dark(#6d28d9, #a78bfa); } ``` ### Naming - **Owner first**: `--i-{owner}-{part}-{state}-{property}`, for example `--i-navbar-brand-font-size` or `--i-table-row-hover-color-background`. Part and state are optional. - **Colors end in a role**: `color-text`, `color-background`, `color-border` or `color-outline`, for example `--i-input-color-border`. - **Global tokens start with a category**: `--i-color-primary`, `--i-font-family`, `--i-spacing`, `--i-border-radius`. Many elements read them. - **Private variables**: Names that start with `--_` switch values inside one element. They are not part of the API and can change at any time. ### Global variables The tokens below are read across the framework. Each element and component page ends with a table of its own variables. #### Typography | Variable | Default | Note | | --- | --- | --- | | `--i-font-emoji` | `"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Twemoji Mozilla", "Noto Color Emoji"` | Font stacks: each platform's system font, then generic fallbacks | | `--i-font-sans` | `system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Helvetica Neue", Arial, "Noto Sans", sans-serif, var(--i-font-emoji)` | | | `--i-font-mono` | `ui-monospace, "Cascadia Mono", SFMono-Regular, Menlo, Consolas, "Roboto Mono", "Liberation Mono", "Courier New", monospace, var(--i-font-emoji)` | | | `--i-font-family` | `var(--i-font-sans)` | | | `--i-line-height` | `1.5` | Base text. The root size starts at the size the user set in the browser and grows to 112.5% between a 576px and a 1280px wide viewport. | | `--i-font-weight` | `400` | | | `--i-font-size` | `clamp(100%, 89.75% + 0.285svw, 112.5%)` | | | `--i-text-underline-offset` | `0.125em` | | #### Spacing | Variable | Default | | --- | --- | | `--i-spacing` | `1rem` | | `--i-typography-spacing` | `1rem` | | `--i-section-spacing-block` | `var(--i-spacing)` | | `--i-section-spacing-inline` | `var(--i-spacing)` | #### Borders | Variable | Default | Note | | --- | --- | --- | | `--i-border-radius-small` | `0.125rem` | Border radius scale | | `--i-border-radius` | `0.25rem` | | | `--i-border-radius-medium` | `0.375rem` | | | `--i-border-radius-large` | `0.5rem` | | | `--i-border-radius-xlarge` | `0.75rem` | | | `--i-border-radius-pill` | `9999px` | | | `--i-border-width` | `0.0625rem` | Border widths | | `--i-focus-ring-width` | `0.125rem` | | #### Motion | Variable | Default | Note | | --- | --- | --- | | `--i-duration` | `0.2s` | Transitions | | `--i-easing` | `ease-in-out` | | #### Icons SVG data URIs with the color baked in. Replace the whole value to change an icon or its color. | Variable | Default | | --- | --- | | `--i-svg-checkmark` | `url("data:image/svg+xml,…")` | | `--i-svg-chevron-down` | `url("data:image/svg+xml,…")` | | `--i-svg-close` | `url("data:image/svg+xml,…")` | | `--i-svg-dash` | `url("data:image/svg+xml,…")` | | `--i-svg-date` | `url("data:image/svg+xml,…")` | | `--i-svg-invalid` | `url("data:image/svg+xml,…")` | | `--i-svg-loading` | `url("data:image/svg+xml,…")` | | `--i-svg-menu` | `url("data:image/svg+xml,…")` | | `--i-svg-search` | `url("data:image/svg+xml,…")` | | `--i-svg-time` | `url("data:image/svg+xml,…")` | | `--i-svg-valid` | `url("data:image/svg+xml,…")` | --- ## Themes Source: https://iriscss.com/documentation/customize/themes/ Iris CSS follows the system light or dark setting. `data-theme` forces either one, on the page or on any element. Every theme color is a `light-dark()` pair, and `:root` sets `color-scheme: light dark`. The browser picks the side that matches the user's setting, so dark mode needs no extra CSS. Add the `color-scheme` meta tag too, so the page background is right before the stylesheet loads. ```html ``` ### Force a theme Set `data-theme` on `` to choose the theme for the whole page. ```html ``` ### Theme one element `data-theme` works on any element. The element repaints its text and background, and everything inside follows, nested themes included. The `.light` and `.dark` classes do the same. ```html

Light

Always light.

Dark

Always dark.

``` ### Theme toggle A toggle only has to set `data-theme` and remember it. Read the saved value in the ``, before the page paints, so it does not flash the wrong theme. This site uses the same script. ```html ``` ### Your own theme colors Override a theme color with your own `light-dark()` pair. A single color, without `light-dark()`, is used in both themes. A color set on `:root` reaches nested themes too. Browsers without `light-dark()` (Chrome before 123, Firefox before 120, Safari before 17.5) recompute colors on each nested theme, so there set it on `:root, [data-theme], .light, .dark` to cover them. ```css :root { --i-color-background: light-dark(#fffdf7, #101418); --i-color-primary: light-dark(#6d28d9, #a78bfa); --i-color-primary-inverse: light-dark(#fff, #1e1b4b); } ``` Each color family is a color and an `-inverse` color, the text that sits on top of it. Hover, border and focus colors are mixed from these two, so you never set them one by one. See [colors](https://iriscss.com/documentation/modifiers/colors/index.html.md) for the classes that use them. --- ## Color palette Source: https://iriscss.com/documentation/customize/color-palette/ 26 color families with 11 shades each, from 50 (lightest) to 950 (darkest). The palette is the same in both themes. Each shade is a variable, `--i-color-{family}-{shade}`. Hover a swatch to see its name. White and black are `--i-color-white` and `--i-color-black`. | Color | 50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 950 | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | | red | #fef2f2 | #ffe2e2 | #ffc9c9 | #ffa2a2 | #ff6467 | #fb2c36 | #e7000b | #c10007 | #9f0712 | #82181a | #460809 | | rose | #fff1f2 | #ffe4e6 | #ffccd3 | #ffa1ad | #ff637e | #ff2056 | #ec003f | #c70036 | #a50036 | #8b0836 | #4d0218 | | pink | #fdf2f8 | #fce7f3 | #fccee8 | #fda5d5 | #fb64b6 | #f6339a | #e60076 | #c6005c | #a3004c | #861043 | #510424 | | fuchsia | #fdf4ff | #fae8ff | #f6cfff | #f4a8ff | #ed6aff | #e12afb | #c800de | #a800b7 | #8a0194 | #721378 | #4b004f | | purple | #faf5ff | #f3e8ff | #e9d4ff | #dab2ff | #c27aff | #ad46ff | #9810fa | #8200db | #6e11b0 | #59168b | #3c0366 | | violet | #f5f3ff | #ede9fe | #ddd6ff | #c4b4ff | #a684ff | #8e51ff | #7f22fe | #7008e7 | #5d0ec0 | #4d179a | #2f0d68 | | indigo | #eef2ff | #e0e7ff | #c6d2ff | #a3b3ff | #7c86ff | #615fff | #4f39f6 | #432dd7 | #372aac | #312c85 | #1e1a4d | | blue | #eff6ff | #dbeafe | #bedbff | #8ec5ff | #51a2ff | #2b7fff | #155dfc | #1447e6 | #193cb8 | #1c398e | #162456 | | sky | #f0f9ff | #dff2fe | #b8e6fe | #74d4ff | #00bcff | #00a6f4 | #0084d1 | #0069a8 | #00598a | #024a70 | #052f4a | | cyan | #ecfeff | #cefafe | #a2f4fd | #53eafd | #00d3f2 | #00b8db | #0092b8 | #007595 | #005f78 | #104e64 | #053345 | | teal | #f0fdfa | #cbfbf1 | #96f7e4 | #46ecd5 | #00d5be | #00bba7 | #009689 | #00786f | #005f5a | #0b4f4a | #022f2e | | emerald | #ecfdf5 | #d0fae5 | #a4f4cf | #5ee9b5 | #00d492 | #00bc7d | #096 | #007a55 | #006045 | #004f3b | #002c22 | | jade | #eefdf5 | #d6fbe6 | #aff6cf | #6dedaf | #03da82 | #00c367 | #00a052 | #007e46 | #01633b | #075233 | #022d1c | | green | #f0fdf4 | #dcfce7 | #b9f8cf | #7bf1a8 | #05df72 | #00c950 | #00a63e | #008236 | #016630 | #0d542b | #032e15 | | spring | #f4feee | #e4fcd9 | #c9f9b4 | #9bf37d | #50e339 | #3ecc28 | #2fa61f | #25801b | #1f6518 | #21541d | #0e2e0c | | lime | #f7fee7 | #ecfcca | #d8f999 | #bbf451 | #9ae600 | #7ccf00 | #5ea500 | #497d00 | #3c6300 | #35530e | #192e03 | | chartreuse | #fbfde8 | #f5fbc6 | #ecf58f | #ddea39 | #ccd700 | #b6c000 | #979600 | #786e00 | #635700 | #54490c | #2e2704 | | yellow | #fefce8 | #fef9c2 | #fff085 | #ffdf20 | #fdc700 | #f0b100 | #d08700 | #a65f00 | #894b00 | #733e0a | #432004 | | amber | #fffbeb | #fef3c6 | #fee685 | #ffd230 | #ffb900 | #fe9a00 | #e17100 | #bb4d00 | #973c00 | #7b3306 | #461901 | | vermilion | #fff5ef | #ffe8da | #ffd0b6 | #ffae83 | #ff7831 | #fd4e18 | #ef2805 | #c61d03 | #9f1c08 | #802212 | #450e07 | | orange | #fff7ed | #ffedd4 | #ffd6a7 | #ffb86a | #ff8904 | #ff6900 | #f54900 | #ca3500 | #9f2d00 | #7e2a0c | #441306 | | stone | #fbfaf8 | #f6f5f3 | #e9e5e2 | #d8d3cf | #a89f98 | #7c7068 | #5a524a | #473f38 | #2b2522 | #1e1916 | #0d0a08 | | neutral | #fafafa | #f5f5f5 | #e5e5e5 | #d4d4d4 | #a1a1a1 | #737373 | #525252 | #404040 | #262626 | #171717 | #0a0a0a | | zinc | #fafafa | #f4f4f6 | #e4e3e9 | #d5d3da | #a09eab | #72707d | #53515e | #403e48 | #28262c | #18181c | #09090b | | gray | #f9fafb | #f2f4f7 | #e4e6ed | #d0d4de | #97a0b2 | #687185 | #485468 | #344056 | #1d283b | #0f172a | #030713 | | slate | #f8fafc | #f0f4fa | #e0e7f2 | #c8d4e5 | #8e9fbc | #607291 | #43536f | #2f3f5b | #1c2840 | #0e162d | #020619 | ### Base colors `--i-color-{family}` without a shade is the 500 shade, for example `--i-color-blue`. Theme colors are built from the palette: `--i-color-info` is `--i-color-cyan` and `--i-color-danger` is `--i-color-red-600`. ```css .tag { color: var(--i-color-teal-800); background-color: var(--i-color-teal-100); } ``` ### Text and background classes `.color-{family}-{shade}` sets the text color and `.background-{family}-{shade}` the background. They sit in the utilities layer, so they win over component styles. ```html

Emerald 600 text

Rose 500 text

Amber 900 on amber 100

Indigo 50 on indigo 700

``` --- ## Typography Source: https://iriscss.com/documentation/elements/typography/ Headings, paragraphs, quotes and inline text, styled with no class. The root font size starts at the size the user set in the browser and grows to 112.5% between a 576px and a 1280px wide viewport. Everything sized in `rem` grows with it. ### Headings Each level has its own size, color and space above. A heading that follows other content gets extra space on top, so sections stay apart. ```html

Heading 1

Heading 2

Heading 3

Heading 4

Heading 5
Heading 6
``` ### Heading group `hgroup` joins a heading and a subtitle. The last line turns subtle. ```html

Release notes

Everything that changed in version 2.

``` ### Inline text Inline elements keep their meaning and get a matching look. Paragraphs and list items avoid a single word on the last line where the browser supports `text-wrap: pretty`. ```html

Strong, bold, emphasis, italic, underline, strikethrough, small, highlighted, inserted, deleted, CSS, H2O and E = mc2.

``` ### Blockquote A `footer` inside the quote holds the source. ```html

Simplicity is prerequisite for reliability.

``` ### Address and rule ```html
Iris CSS
hello@example.com

Text after a horizontal rule.

``` ### Math MathML uses a math font where one is installed. ```html

a=b2+c2

``` --- ## Link Source: https://iriscss.com/documentation/elements/link/ Links take their color from the color classes and mix it toward the text color, so they stay readable. A link without a class uses the neutral base color. It underlines on hover and shows a focus ring for keyboard users. `role="link"` gets the same look. ```html

Read the getting started guide first.

``` ### Colors A [color class](https://iriscss.com/documentation/modifiers/colors/index.html.md) changes only the text color, never the background. ```html

Primary · Secondary · Contrast · Accent · Info · Success · Warning · Danger · Link

``` ### States and current page `aria-current` marks the current page or item with the hover look. `.hover`, `.active` and `.focus` show a state without interaction, and `.disabled` fades the link and blocks clicks. ```html

Current page · Hover · Focus · Disabled

``` ### Link as a button `role="button"` turns a link into a [button](https://iriscss.com/documentation/elements/button/index.html.md). ```html Get started ``` --- ## List Source: https://iriscss.com/documentation/elements/list/ Unordered, ordered and description lists, plus `menu` as a toolbar. ### Unordered Markers change at each level: square, disc, then circle. ```html ``` ### Ordered ```html
  1. Link the stylesheet
  2. Write HTML
  3. Add a class when you want a variant
``` ### Description list ```html
Classless
Plain HTML is styled with no class.
Layered
Your own CSS always wins.
``` ### Menu `menu` is a toolbar. Its items sit in a row and wrap when there is no room. ```html
  • ``` --- ## Button Source: https://iriscss.com/documentation/elements/button/ Every `button` is styled with no class. Color, style, size and state classes combine freely. Iris styles `button`, `input[type="submit"]`, `input[type="reset"]`, `input[type="button"]` and anything with `role="button"`, including links. ```html Link ``` ### Colors A color class sets `--i-variant` and `--i-variant-inverse`. The button builds its background, border, text and focus ring from them. ```html ``` For a color outside the list, set the two variables yourself. ```html ``` ### Styles `.outlined` keeps only the border and text. `.tint` is a pale tint and `.deep` a deep shade, the same in both themes. ```html ``` `.rounded` gives pill corners and `.square` removes them. ```html ``` ### Sizes The default size needs no class. `.medium` is larger than the default. ```html ``` ### States `.hover`, `.active` and `.focus` show a state without interaction, for previews and docs. `disabled`, `aria-busy="true"` and `aria-current` work as attributes. A button with `aria-current` keeps the hover look, for the selected item in a toolbar. ```html ``` ### File input The picker button of a file input is a secondary button. ```html ``` ### Group `.group` joins buttons into one control. See [group](https://iriscss.com/documentation/form/group/index.html.md) for inputs and search bars. ```html
    ``` --- ## Code Source: https://iriscss.com/documentation/elements/code/ `code`, `pre`, `kbd`, `samp` and `var`, styled with no class. ### Inline code Inline code wraps with the text. Each wrapped line keeps its own padding and corners. ```html

    Run npm run build and open dist/index.html.

    ``` ### Code block Put `code` inside `pre` for a block that keeps line breaks and scrolls sideways. ```html
    :root {
      --i-color-primary: #7c3aed;
    }
    ``` ### Keyboard Nest `kbd` elements for a key combination. The outer one stays plain. ```html

    Press Esc to close, or Ctrl + C to copy.

    ``` ### Sample and variable `samp` shows program output. `var` names a variable and keeps the text font. ```html

    The build prints Built 57 pages into dist.

    The area is width times height.

    ``` ### Light Code is dark in both themes. `.light` switches it to light colors. ```html

    Set data-theme on any element.

    <html data-theme="dark">
    ``` ### Rounded and square ```html

    .rounded and .square

    ``` --- ## Table Source: https://iriscss.com/documentation/elements/table/ Tables are full width with header, body and footer lines. Add a class for stripes, hover or a sticky header. ```html
    Plans
    PlanProjectsPrice
    Free3$0
    ProUnlimited$12
    TeamUnlimited$40
    BilledMonthly
    ``` Cells use even digit widths, so number columns line up. ### Striped ```html
    NameRole
    AdaEngineer
    GraceAdmiral
    AlanMathematician
    LinusMaintainer
    ``` ### Hover `.hover` highlights the row under the pointer. ```html
    OrderStatus
    #1042Shipped
    #1043Packing
    #1044Paid
    ``` ### Sticky header `.sticky` keeps the header in view while the page scrolls. Inside a `.table-responsive` wrapper with a max height, it sticks to the wrapper instead. ```html
    ShadeVariable
    50--i-color-blue-50
    100--i-color-blue-100
    200--i-color-blue-200
    300--i-color-blue-300
    400--i-color-blue-400
    500--i-color-blue-500
    600--i-color-blue-600
    ``` ### Sizes `.small`, `.medium` and `.large` change the cell padding and font size. ```html
    SmallCompact rows
    TableFor dense data
    LargeRoomy rows
    ``` ### Responsive Wrap a wide table in `.table-responsive` to scroll it sideways instead of the page. Keyboard users can only scroll it once it can take focus, so give it `tabindex="0"` and an `aria-label`. ```html
    MonTueWedThuFriSatSunTotal
    1,204 visits1,388 visits1,512 visits1,470 visits1,290 visits860 visits790 visits8,514 visits
    ``` --- ## Media Source: https://iriscss.com/documentation/elements/media/ Images, video, audio, iframes and SVG scale down to fit their container. ### Images Images never grow wider than their container and keep their aspect ratio. The alt text of an image that fails to load shows in italics. ```html Iris CSS logo This image failed to load ``` ### Figure A `figcaption` sits under the media in the subtle text color. ```html
    Iris CSS logo
    The Iris CSS logo.
    ``` ### Iframe An iframe without `width` or `height` fills the width at 16:9. Embedded videos need no wrapper. ```html ``` ### Audio and video `audio` fills the width. `video` scales like an image, and captions from a `track` use the page font. ```html ``` ### SVG An inline SVG without a `fill` takes the text color. ```html

    A star in the text color

    ``` --- ## Progress and meter Source: https://iriscss.com/documentation/elements/progress-and-meter/ `progress` shows how far a task has got. `meter` shows a value in a known range. ### Progress ```html 40% ``` ### Indeterminate Without a `value` the bar animates while the task runs. Users who prefer reduced motion see a still bar. ```html ``` ### Colors A [color class](https://iriscss.com/documentation/modifiers/colors/index.html.md) colors the bar. ```html ``` ### Meter The bar is green in the optimum range, yellow below it and red in the worst range. Set `low`, `high` and `optimum` to define the ranges. ```html ``` ### Sizes and styles Both take `.small`, `.medium` and `.large`, and `.rounded` or `.square`. ```html ``` --- ## Popover Source: https://iriscss.com/documentation/elements/popover/ Any element with the `popover` attribute, opened by a button with `popovertarget`. No JavaScript. The popover fades in over the page, centered by default. Clicking outside or pressing `Esc` closes it. ```html

    Popover

    Click outside or press Esc to close.

    ``` ### Placement `data-placement` anchors the popover to its button: `bottom`, `top`, `left` or `right`. It flips to the other side when there is no room. Browsers without anchor positioning keep it centered. ```html
    Below the button
    Above the button
    Before the button
    After the button
    ``` ### Older browsers Browsers without the Popover API show the content in place, as normal page content. ### Related The [navbar](https://iriscss.com/documentation/components/navbar/index.html.md) menu and the [toast](https://iriscss.com/documentation/components/toast/index.html.md) are popovers too. For a short label on hover, use a [tooltip](https://iriscss.com/documentation/components/tooltip/index.html.md). --- ## Controls Source: https://iriscss.com/documentation/form/controls/ Inputs, selects and textareas are full width, with a label above and room for helper text below. Write a plain form. Each control fills the width, and a control inside its `label` sits right under the label text. Buttons, submit buttons included, keep the width of their text. ```html
    ``` ### Select A select gets a chevron. Where the browser supports a customizable select, the option list follows the theme too. ```html ``` ### Textarea A textarea grows with its text, from 4 to 16 lines, where the browser supports `field-sizing`. A `rows` attribute keeps a fixed height. ```html ``` ### Helper text A `small` right after a control is its helper text. Link it with `aria-describedby`. ```html Letters and numbers only. ``` ### Fieldset A `fieldset` groups related controls under a `legend`. `disabled` on the fieldset turns off and fades every control inside. ```html
    Shipping
    ``` ### Side by side Put controls in a [`.grid`](https://iriscss.com/documentation/layout/container-and-grid/index.html.md#grid) to place them in columns that stack on narrow screens. ```html
    ``` ### Output `output` shows a computed value in bold with even digit widths, so it does not shift as it changes. ```html

    Total: 36

    ``` ### Disabled and read only ```html ``` ### Sizes ```html ``` ### Styles `.rounded` gives pill corners, `.square` removes them and `.outlined` makes the background transparent. ```html ``` --- ## Input types Source: https://iriscss.com/documentation/form/input-types/ Search, date and time, color, file and range inputs, each with a look that fits the rest of the form. ### Search A search input is a pill with a magnifier at the start. ```html ``` ### Date and time In Chrome and Edge, the picker button of `date`, `datetime-local`, `month` and `week` gets a calendar icon, and `time` a clock. Firefox and Safari keep their own. ```html
    ``` ### Color ```html ``` ### File The picker is a secondary [button](https://iriscss.com/documentation/elements/button/index.html.md) followed by the file name. ```html ``` ### Range The thumb turns primary while you use it, with an accent dot while you drag it. A [color class](https://iriscss.com/documentation/modifiers/colors/index.html.md) changes the primary color. ```html ``` --- ## Checkbox, radio and switch Source: https://iriscss.com/documentation/form/checkbox-radio-and-switch/ Checkboxes and radios with custom marks, and `role="switch"` to turn a checkbox into a switch. Put the input inside its `label`. The label lines up with the box and the whole label is clickable. ```html
    Notifications
    Plan
    ``` ### Switch `role="switch"` on a checkbox draws a switch. Screen readers announce it as on or off. ```html ``` ### Colors Checked boxes, radios and switches use the primary color. A [color class](https://iriscss.com/documentation/modifiers/colors/index.html.md) on the input changes it. ```html ``` ### Indeterminate A checkbox for a partly selected list shows a dash. Set `indeterminate` from a script, since there is no attribute for it. ```html ``` ```js document.getElementById("select-all").indeterminate = true; ``` ### Disabled ```html ``` --- ## Validation Source: https://iriscss.com/documentation/form/validation/ Native validation works with no script. `aria-invalid` shows the result of your own checks. ### Native validation Controls that break their `required`, `type`, `pattern` or length rules turn red with an icon. Iris uses `:user-invalid`, so a field only turns red after the user has changed it or tried to submit. Type a few letters below, then clear the field. ```html
    We never share your email.
    ``` ### Server side checks For checks the browser cannot make, set `aria-invalid` yourself. `"true"` marks an error and `"false"` a field that passed. Screen readers announce the error too. ```html Available. This name is taken. ``` ### Helper text A `small` right after the control follows its state: green when it is valid and red when it is not. It works after a `fieldset` or a `.grid` too. ### Selects, textareas and checkboxes ```html ``` --- ## Group Source: https://iriscss.com/documentation/form/group/ `.group` joins inputs, selects and buttons into one row. The children share borders and corners. The focused child moves on top, so its focus ring shows over its neighbors. Add `role="group"` and a label when the row is one control, so screen readers announce it as one. ```html
    ``` ### Buttons ```html
    ``` ### With a select ```html
    ``` ### Search A group on or inside `search` or `role="search"` gets pill ends. When `search` holds a form, put the class on the form. ```html
    ``` ### Sizes A size class on the group sizes every control inside. ```html
    ``` ### Rounded and square ```html
    ``` --- ## Accordion Source: https://iriscss.com/documentation/components/accordion/ Every `details` element is an accordion. It animates open and closed with no JavaScript. The summary gets a chevron that turns when the panel opens. Opening and closing animate where the browser supports `::details-content` and `interpolate-size`, and snap open elsewhere. ```html
    Does Iris CSS need JavaScript?

    No. Every component works with plain HTML and CSS.

    Can I use my own styles?

    Yes. Iris CSS sits in cascade layers, so your CSS always wins.

    ``` ### One open at a time Give the `details` elements the same `name` and opening one closes the others. ```html
    Shipping

    Orders ship within two working days.

    Returns

    Send it back within 30 days for a full refund.

    Warranty

    Two years on every product.

    ``` ### Summary as a button `role="button"` on the summary makes it look like a [button](https://iriscss.com/documentation/elements/button/index.html.md), with color classes and all. ```html
    Show the details

    The content opens under the button.

    ``` ### Related [Tabs](https://iriscss.com/documentation/components/tabs/index.html.md) are built on `details` too. For a menu that opens over the page, use a [dropdown](https://iriscss.com/documentation/components/dropdown/index.html.md). --- ## Alert Source: https://iriscss.com/documentation/components/alert/ A tinted message box with a colored bar on the start edge. Add `.alert` to any block element. Give it `role="alert"` for urgent messages or `role="status"` for the rest, so screen readers announce it. ```html
    Your changes were saved as a draft.
    ``` ### Colors A color class sets the bar, border, tint and text color. ```html
    A new version is available.
    Payment received.
    ``` ### Headings and links Headings and links inside an alert take its color. ```html

    Welcome to Iris CSS

    Start with plain HTML, then read the docs when you need a variant.

    ``` --- ## Avatar Source: https://iriscss.com/documentation/components/avatar/ A round picture or initials, in four sizes, with overlapping groups. Put `.avatar` on an `img`, or on a `span` with initials. ```html Iris CSS AL GH ``` ### Colors A [color class](https://iriscss.com/documentation/modifiers/colors/index.html.md) colors the initials and their background. ```html PR IN SU DA CO ``` ### Sizes ```html S D M L ``` ### Square `.square` rounds the corners only. ```html Iris CSS AL ``` ### Group `.avatar-group` overlaps the avatars, with a ring in the page color between them. ```html
    AL GH AT +4
    ``` --- ## Badge Source: https://iriscss.com/documentation/components/badge/ A small pill for counts and labels. Its size follows the text around it. ```html

    Inbox 12

    Status: Paid

    ``` ### Colors Badges are secondary by default. A [color class](https://iriscss.com/documentation/modifiers/colors/index.html.md) changes the color. ```html

    Primary Secondary Contrast Accent Info Success Warning Danger Link

    ``` ### Outlined ```html

    Primary Info Danger

    ``` ### As a link ```html

    css html

    ``` --- ## Box Source: https://iriscss.com/documentation/components/box/ A padded block with a background, rounded corners and a shadow. ```html

    A box holds anything: text, a form or a small widget.

    ``` ### Clickable box On a link the whole box is clickable and lifts on hover. ```html Documentation

    Everything about Iris CSS in one place.

    ``` ### Styles `.outlined` swaps the shadow for a border. `.rounded` and `.square` change the corners. ```html
    Outlined
    Rounded
    Square
    ``` ### Box or card A box is one plain block. A [card](https://iriscss.com/documentation/components/card/index.html.md) adds header and footer bands and size classes. --- ## Card Source: https://iriscss.com/documentation/components/card/ A padded block with a background, a shadow and optional header and footer bands. Add `.card` to any block element, usually an `article`. A direct `header` or `footer` becomes a tinted band. ```html

    Pro plan

    Unlimited projects, priority support and early access to new components.

    ``` ### Body only ```html

    A card without bands is a padded block, like a box.

    ``` ### Outlined `.outlined` swaps the background and shadow for a border, and makes the bands transparent. ```html
    Outlined

    A quiet card for secondary content.

    ``` ### Sizes `.small`, `.medium` and `.large` change the padding. ```html

    Small

    Default

    Medium

    Large

    ``` ### Rounded and square ```html

    Rounded

    Square

    ``` ### Card grid Put cards in a [`.grid`](https://iriscss.com/documentation/layout/container-and-grid/index.html.md#grid) for equal columns that wrap. ```html

    Free

    3 projects

    Pro

    Unlimited projects

    Team

    Shared workspaces

    ``` ### In a modal A [modal](https://iriscss.com/documentation/components/modal/index.html.md) dialog is always a card, with no class. --- ## Carousel Source: https://iriscss.com/documentation/components/carousel/ A row of slides that scrolls sideways and snaps to each one, with no JavaScript. Put the slides inside `.carousel`. Swipe, scroll or use the keyboard to move. Where the browser supports scroll buttons and scroll markers, the carousel also gets previous and next buttons and a dot for each slide. Give it `tabindex="0"` and an `aria-label`, so keyboard users can reach and scroll it in every browser. ```html ``` The buttons sit over the edges of the carousel. With text slides, give the carousel side padding, the same `scroll-padding-inline`, and a `--i-carousel-gap` a little wider than the padding. The buttons then sit in empty gutters beside the text, and the next slide stays out of sight. ### Images Any element can be a slide, usually a `figure`. The photos come from [Picsum](https://picsum.photos). ```html ``` ### Slide width Set `--i-carousel-item-width` on the carousel. A value of `100%` shows one slide at a time. ```html ``` --- ## Divider Source: https://iriscss.com/documentation/components/divider/ A rule with text in the middle. ```html

    or

    ``` For a rule without text, use `
    `. See [typography](https://iriscss.com/documentation/elements/typography/index.html.md#address-and-rule). --- ## Drawer Source: https://iriscss.com/documentation/components/drawer/ A [modal](https://iriscss.com/documentation/components/modal/index.html.md) that slides in from an edge of the screen. Add `.drawer` to the `dialog`. It slides in from the end edge and opens like any modal. ```html

    Filters

    ``` ### Start `.start` uses the start edge, for a side menu. ```html ``` ### Bottom sheet `.bottom` slides up from the bottom with rounded top corners. ```html

    Share this page

  • ``` --- ## Dropdown Source: https://iriscss.com/documentation/components/dropdown/ A popover list of links or choices, opened by a button. No JavaScript. ```html ``` Give the list `popover` and `.dropdown`, and point the button's `popovertarget` at its `id`. Put the list right after the button, which then shows a chevron that turns while the menu is open. Clicking outside or pressing `Esc` closes it, and the browser tells screen readers whether it is open. `aria-current` marks the selected link. Where the browser supports anchor positioning, the menu opens below the button, at least as wide as it, and flips above it near the bottom of the screen. It sits in the top layer, so no container clips it. Browsers without anchor positioning center it like any [popover](https://iriscss.com/documentation/elements/popover/index.html.md). ### Button The button keeps every [button](https://iriscss.com/documentation/elements/button/index.html.md) color, style and size. ```html ``` ### Select `.select` draws the button as a [select](https://iriscss.com/documentation/form/controls/index.html.md), for a menu of choices. List items can hold labels with checkboxes or radios. ```html ``` ### In a form Inside a `label` the select button sits under the label text like any control. `aria-invalid` on it shows a [validation](https://iriscss.com/documentation/form/validation/index.html.md) state. ```html ``` ### In a nav Inside `nav` a button without a class looks like a link. See [nav](https://iriscss.com/documentation/components/nav/index.html.md). ```html ``` ### Sizes and styles A select button takes size classes, `.rounded`, `.square` and `.outlined`. ```html ``` --- ## Footer Source: https://iriscss.com/documentation/components/footer/ A page footer with link columns that works on mobile and desktop. Add `class="footer"` to the page `footer`. Everything inside is plain HTML. The element that holds the `nav` elements becomes the column grid, and its first child is the brand when it is not a `nav`. The element right after the grid is the bottom row, for the copyright and credits. ```html ``` ### Mobile and desktop The footer measures its own width, not the screen. Columns sit side by side while they fit and wrap to new rows when they don't. Below 48rem the brand gets a row of its own, links get more room to tap and the bottom row stacks. The example above is narrower than 48rem, so it shows the phone layout. Resize the window to see both layouts in this site's own footer. On phones with a home indicator, the bottom padding grows to keep the content clear of it. ### Simple footer Without a `nav`, the footer is a plain band for a line or two of text. ```html ``` ### Sticky `.sticky` keeps the footer at the bottom of the window when the page is shorter than the screen. On longer pages it sits after the content as usual. The footer must be a direct child of `body`, which becomes a flex column. In a flex column the margins of the other children no longer collapse, so check the spacing of your page sections. ```html ``` ### Colors A color class fills the band. Text, headings and links switch to the band's text color. ```html ``` --- ## Icon Source: https://iriscss.com/documentation/components/icon/ A square box for an inline SVG or an icon font. It keeps its space while the icon loads. Iris CSS ships no icon set. Wrap any SVG or icon font glyph in `.icon`. An SVG without `fill` takes the text color. ```html

    ``` ### Sizes ```html

    ``` ### Icon and text `.icon-text` puts an icon and its label side by side. On a `div` it spans the full width. ```html

    Starred

    ``` --- ## Loader Source: https://iriscss.com/documentation/components/loader/ `aria-busy="true"` shows a spinner before the content, in the text color. The attribute also tells screen readers that the content is loading. Remove it when the work is done. Form controls cannot show a spinner, so put it on their button or label instead. ```html

    Loading your projects

    ``` ### Buttons and links A busy button or link keeps its spinner and label on one line. `aria-busy` does not stop the mouse or the keyboard, so also set `aria-disabled="true"`. The button looks disabled but keeps focus, and your script ignores it until the work is done. Announce the result in a `role="status"` region. ```html Loading ``` ### Spinner only An empty busy element shows the spinner alone. Give it `role="status"` and a label, so screen readers announce it. ```html
    ``` ### Reduced motion The spinner keeps turning when the user prefers reduced motion, since it carries meaning. See [user preferences](https://iriscss.com/documentation/accessibility/user-preferences/index.html.md). --- ## Modal Source: https://iriscss.com/documentation/components/modal/ A `dialog` drawn as a card over a dimmed page. It animates in and out, and the page stops scrolling while it is open. The dialog is a [card](https://iriscss.com/documentation/components/card/index.html.md), and a direct `header` or `footer` becomes a band. Open it with a button that has `command="show-modal"`, and close it with `command="close"`. `Esc` closes it too, and `closedby="any"` adds a click outside, where the browser supports it. No script is needed. ```html

    The project and its files are deleted for good.

    ``` `.close` on a button in the header draws an X at the end. A link with `rel="prev"` gets the same look, for a modal that has its own URL. ### Return a value Buttons in a `
    ` close the dialog and set its `returnValue` to the button value. ```html

    Which plan do you want?

    ``` ### From a script Browsers without invoker commands ignore `command`. To support them, call the dialog methods from a script. ```js const dialog = document.getElementById("modal-example"); dialog.showModal(); dialog.close(); ``` ### Related A [drawer](https://iriscss.com/documentation/components/drawer/index.html.md) is a modal that slides in from an edge. --- ## Nav and breadcrumb Source: https://iriscss.com/documentation/components/nav/ Lists inside `nav` line up in a row. Inside `aside` they stack. `nav.breadcrumb` adds dividers. Each list in a `nav` is a group. The first sits at the start and the last at the end. Links get a padded hit area, and `aria-current` marks the current page. Only the nav's own lists form the row, so a list nested in an item keeps its layout, and one class on the nav overrides it. ```html ``` ### Collapsing menu Make the link list a popover and add a `.nav-toggle` button for it. The list sits in the nav while there is room, and opens from the button below a 48rem wide nav. For a top bar with a full width panel on phones, use the [navbar](https://iriscss.com/documentation/components/navbar/index.html.md). ```html ``` ### Vertical menu Inside `aside` the lists stack, for a sidebar menu. ```html ``` ### Breadcrumb `nav.breadcrumb` puts a divider between items. Mark the last link with `aria-current="page"`. The divider flips in right to left text. ```html ``` ### Dropdown Inside a nav, a button without a class that opens a [dropdown](https://iriscss.com/documentation/components/dropdown/index.html.md#nav) looks like a link. --- ## Navbar Source: https://iriscss.com/documentation/components/navbar/ A responsive top bar that works on mobile and desktop with no JavaScript. Wrap a `nav` in `