Components
Card
The card is extremely versatile and can be used on its own, or as a building block for accordions, dialogs and more.
Full supportSupported since v111.Full supportSupported since v151.Full supportSupported since v18.
Anatomy
Overline
Headline
Subhead
Explain more about the topic shown in the headline and subhead through supporting text.
.ui-cardContainer element.
<hgroup>The card header.
.ui-contentThe card content.
.ui-actionsA group of actions, such as buttons.
Variants
Change the card variant with the .ui-text, .ui-outlined, .ui-tonal, and .ui-elevated classes.
Text
Outlined
Tonal
Elevated
<!-- .ui-text class optional --><div class="ui-card ui-text"> <div class="ui-content">Text</div></div>
<div class="ui-card ui-outlined"> <div class="ui-content">Outlined</div></div>
<div class="ui-card ui-tonal"> <div class="ui-content">Tonal</div></div>
<div class="ui-card ui-elevated"> <div class="ui-content">Elevated</div></div>Why does a text variant exist?
It really doesn't make sense to use the text variant unless you really need to. The accordion group is a great example where Open Props UI leverages the text variant of the.ui-card component.Header
Using the <hgroup>.
Blog
My ultra-great blog post
Please read it.
<div class="ui-card ui-outlined"> <hgroup> <p>Blog</p> <h3>My ultra-great blog post</h3> <p>Please read it.</p> </hgroup></div>Actions
Using the .ui-actions class.
There are some basic styles here to get you going, but for more advanced use-cases (which always happen), you might want to add your own styles.
Notice how the buttons are made to align with the text above.
Trying other button types too. Look at that!
Icon buttons work too!
<div class="ui-card ui-outlined"> <div class="ui-content"> Notice how the buttons are made to align with the text above. </div> <div class="ui-actions"> <button class="ui-button">Cancel</button> <button class="ui-button">Save</button> </div></div>
<div class="ui-card ui-outlined"> <div class="ui-content">Trying other button types too. Look at that!</div> <div class="ui-actions"> <button class="ui-button ui-outlined">Cancel</button> <button class="ui-button ui-filled">Save</button> </div></div>
<div class="ui-card ui-outlined"> <div class="ui-content">Icon buttons work too!</div> <div class="ui-actions"> <button class="ui-icon-button" aria-label="Favorite"> <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" > <path fill="currentColor" d="M3.384 7.13c2.972-4.17 9.167-4.174 12.146-.008l.465.65l.417-.593c2.955-4.195 9.16-4.236 12.17-.081A7.48 7.48 0 0 1 28 16.583L16.732 28.681a1 1 0 0 1-1.464 0L3.992 16.54a7.46 7.46 0 0 1-.608-9.41m10.52 1.155c-2.181-3.05-6.716-3.046-8.892.007a5.46 5.46 0 0 0 .446 6.887L16.002 26.53l10.534-11.31a5.48 5.48 0 0 0 .427-6.95c-2.205-3.044-6.751-3.013-8.916.06l-1.229 1.744a1 1 0 0 1-1.63.006z" /> </svg> </button> <button class="ui-icon-button" aria-label="Share"> <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" > <path fill="currentColor" d="M14 3a1 1 0 1 1 0 2H7.5A2.5 2.5 0 0 0 5 7.5v17A2.5 2.5 0 0 0 7.5 27h17a2.5 2.5 0 0 0 2.5-2.5V19a1 1 0 1 1 2 0v5.5a4.5 4.5 0 0 1-4.5 4.5h-17A4.5 4.5 0 0 1 3 24.5v-17A4.5 4.5 0 0 1 7.5 3zm5.58-.907a1 1 0 0 1 1.067.146l10 8.5a1 1 0 0 1 0 1.523l-10 8.5A1 1 0 0 1 18.999 20v-3.96c-3.193.258-5.636 1.722-7.34 3.213a15.6 15.6 0 0 0-2.115 2.26c-.234.307-.407.56-.52.733c-.085.13-.136.215-.152.243l-.006.006l.001.001A1 1 0 0 1 7 22.036c0-.222-.003-.444.003-.666c.011-.406.042-.982.12-1.67c.155-1.37.5-3.218 1.265-5.08s1.967-3.776 3.855-5.225C13.948 8.086 16.161 7.2 19 7.032V3a1 1 0 0 1 .58-.907M20.998 8a1 1 0 0 1-1 1c-2.925 0-5.018.814-6.539 1.98c-1.533 1.177-2.551 2.763-3.224 4.4a16.5 16.5 0 0 0-.957 3.38c.318-.33.672-.672 1.062-1.013C12.462 15.891 15.687 14 19.999 14a1 1 0 0 1 1 1v2.838l7.456-6.338L21 5.161z" /> </svg> </button> </div></div>Alignment
Align actions to the end with the .ui-align-end class.
Buttons aligned to the end. Works too!
Again, buttons are aligned to the end!
Icon buttons aligned to the end!
<div class="ui-card ui-outlined"> <div class="ui-content">Buttons aligned to the end. Works too!</div> <div class="ui-actions ui-align-end"> <button class="ui-button">Cancel</button> <button class="ui-button">Save</button> </div></div>
<div class="ui-card ui-outlined"> <div class="ui-content">Again, buttons are aligned to the end!</div> <div class="ui-actions ui-align-end"> <button class="ui-button ui-outlined">Cancel</button> <button class="ui-button ui-filled">Save</button> </div></div>
<div class="ui-card ui-outlined"> <div class="ui-content">Icon buttons aligned to the end!</div> <div class="ui-actions ui-align-end"> <button class="ui-icon-button" aria-label="Favorite"> <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" > <path fill="currentColor" d="M3.384 7.13c2.972-4.17 9.167-4.174 12.146-.008l.465.65l.417-.593c2.955-4.195 9.16-4.236 12.17-.081A7.48 7.48 0 0 1 28 16.583L16.732 28.681a1 1 0 0 1-1.464 0L3.992 16.54a7.46 7.46 0 0 1-.608-9.41m10.52 1.155c-2.181-3.05-6.716-3.046-8.892.007a5.46 5.46 0 0 0 .446 6.887L16.002 26.53l10.534-11.31a5.48 5.48 0 0 0 .427-6.95c-2.205-3.044-6.751-3.013-8.916.06l-1.229 1.744a1 1 0 0 1-1.63.006z" /> </svg> </button> <button class="ui-icon-button" aria-label="Share"> <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" > <path fill="currentColor" d="M14 3a1 1 0 1 1 0 2H7.5A2.5 2.5 0 0 0 5 7.5v17A2.5 2.5 0 0 0 7.5 27h17a2.5 2.5 0 0 0 2.5-2.5V19a1 1 0 1 1 2 0v5.5a4.5 4.5 0 0 1-4.5 4.5h-17A4.5 4.5 0 0 1 3 24.5v-17A4.5 4.5 0 0 1 7.5 3zm5.58-.907a1 1 0 0 1 1.067.146l10 8.5a1 1 0 0 1 0 1.523l-10 8.5A1 1 0 0 1 18.999 20v-3.96c-3.193.258-5.636 1.722-7.34 3.213a15.6 15.6 0 0 0-2.115 2.26c-.234.307-.407.56-.52.733c-.085.13-.136.215-.152.243l-.006.006l.001.001A1 1 0 0 1 7 22.036c0-.222-.003-.444.003-.666c.011-.406.042-.982.12-1.67c.155-1.37.5-3.218 1.265-5.08s1.967-3.776 3.855-5.225C13.948 8.086 16.161 7.2 19 7.032V3a1 1 0 0 1 .58-.907M20.998 8a1 1 0 0 1-1 1c-2.925 0-5.018.814-6.539 1.98c-1.533 1.177-2.551 2.763-3.224 4.4a16.5 16.5 0 0 0-.957 3.38c.318-.33.672-.672 1.062-1.013C12.462 15.891 15.687 14 19.999 14a1 1 0 0 1 1 1v2.838l7.456-6.338L21 5.161z" /> </svg> </button> </div></div>API
Card API
| Type | Modifiers | Default | Description |
|---|---|---|---|
| Alignment | default, .ui-actions.ui-align-end | - | Alignment for the actions. |
| Variants | .ui-elevated, .ui-outlined, .ui-text, .ui-tonal | - | The variant to use. |
Parts
| Part | Description |
|---|---|
.ui-card | Container element. |
<hgroup> | The card header. |
.ui-content | The card content. |
.ui-actions | A group of actions, such as buttons. |
Browser support
Full supportSupported since v111.Full supportSupported since v151.Full supportSupported since v18.
See also the full browser support guide.
Installation
@layer components.root { :where(.ui-card) { --_bg-tonal: var(--surface-tonal); --_bg-elevated: var(--surface-elevated); --_bg-surface: var(--surface-default); --_border-color: var(--border-color); --_card-bg-color: var(--_bg-surface); --_card-border-color: transparent; --_card-border-width: 0;
--_card-shadow: none; --_shadow-light: var(--shadow-3); --_shadow-dark: var(--shadow-4); --_shadow-elevated: var(--_shadow-light);
@container style(--color-scheme: dark) { --_shadow-elevated: var(--_shadow-dark); }
background-color: var(--_card-bg-color); border-color: var(--_card-border-color); border-radius: var(--border-radius); border-style: solid; border-width: var(--_card-border-width); box-shadow: var(--_card-shadow); display: flex; flex-direction: column; gap: var(--size-3); overflow: hidden; padding-inline: 0; position: relative;
/* Variants */ &.ui-text { --_card-bg-color: transparent; --_card-border-color: transparent; --_card-border-width: 0; --_card-shadow: none; }
&.ui-tonal { --_card-bg-color: var(--_bg-tonal); --_card-border-width: 1px; }
&.ui-elevated { --_card-bg-color: var(--_bg-elevated); --_card-shadow: var(--_shadow-elevated); }
&.ui-outlined { --_card-bg-color: var(--_bg-surface); --_card-border-color: var(--_border-color); --_card-border-width: 1px; }
& > :where(hgroup, .ui-content) { padding-inline: var(--size-3);
&:last-child { padding-block-end: var(--size-3); } }
/* Header */ & > hgroup { padding-block: var(--size-3) 0;
/* Top paragraph */ & > p:first-of-type:first-child { font-size: var(--font-size-0); line-height: 1.3; }
:where(h1, h2, h3, h4, h5, h6):last-child { margin-block-end: 0; }
/* Bottom paragraph */ & > p:last-of-type:last-child:not(:first-child) { font-size: var(--font-size-1); } }
/* Content */ & > .ui-content:where(:only-child, :first-child) { padding-block: var(--size-3) var(--size-4); }
/* Actions */ & > .ui-actions { display: flex; gap: var(--size-2); margin-block: var(--size-2) 0; padding-block-end: var(--size-2); padding-inline: var(--size-3);
&:has(.ui-button:first-child[class="ui-button"]) { padding-inline: var(--size-1) var(--size-3); }
&:has(.ui-button:not([class="ui-button"])) { padding-block-end: var(--size-2); }
/* Alignment */ &.ui-align-end { justify-content: end;
&:has(.ui-button:first-child[class="ui-button"]) { padding-inline: var(--size-3) var(--size-1); } } } }}