Examples
Basic cards
Basic cards typically have a <CardTitle>
, <CardBody>
and <CardFooter>
. You may omit these components as needed, but it is recommended to at least include a <CardBody>
to provide details about the card item.
Modifiers
You can further modify the styling of the card's content by using the properties outlined below. In this example, you can enable each modifier by selecting its respective checkbox.
Most modifiers can be used in combination with each other, except for isCompact
and isLarge
, since they are contradictory.
Modifier | Description |
---|---|
isCompact | Modifies the card to include compact styling. Should not be used with isLarge. |
isFlat | Modifies the card to include flat styling. |
isRounded | Modifies the card to include rounded border styling. |
isLarge | Modifies the card to be large. Should not be used with isCompact. |
isFullHeight | Modifies the card so that it fills the total available height of its container. |
isPlain | Modifies the card to include plain styling, which removes the border and background. |
Header images and actions
You can include header images within <CardHeaderMain>
and header actions within <CardActions>
. The following example includes an image using the Brand component, and also includes a kebab dropdown and a checkbox in <CardActions>
.
<CardActions>
includes the hasNoOffset
property, which is false
by default. When hasNoOffset
is false
, a negative margin is applied to help align default-sized card titles with <CardActions>
.
You may use hasNoOffset
to remove this negative margin, which better aligns <CardActions>
in implementations that use large card titles or tall header images, for example.
Select the "actions hasNoOffset" checkbox in the example below to illustrate this behavior.
Title inline with images and actions
Moving <CardTitle>
within the <CardHeader>
will style it inline with any images or actions.
Card header without title
<CardActions>
can be placed in the card header even without a <CardTitle>
.
Images can also be placed in the card header within <CardHeaderMain>
without a <CardTitle>
.
With HTML heading element
You may use the component
property to place the card's title within an HTML heading element.
Header within an <h4> element
With multiple body sections
You may use multiple body sections to visually separate blocks of content.
With a primary body section that fills
<CardBody>
sections will fill the available height of the card when isFilled
equals {true}
, which is the default value. Set isFilled
to {false}
to disable this behavior for one or more body sections. The remaining available height of the card will be split between any <CardBody>
section that does not set isFilled
to {false}
.
A common use case of this is to set all but one body section to isFilled={false}
so that a primary body section fills the available space of the card as seen in the example below. This example has 3 <CardBody>
sections, two of which set isFilled
to {false}
. The third <CardBody>
fills the remaining height of the card.
Selectable cards
Selectable cards can only be selected one at a time, and are intended for use with primary-detail layout.
Legacy selectable cards
The following example shows a legacy implementation of selectable cards. This example uses the isSelectable
property instead of isSelectableRaised
, which is the current recommendation for implementation. isSelectable
applies selectable styling, but does not apply raised styling on hover and selection as isSelectableRaised
does.
Selectable card accessibility features
The following cards demonstrate how the hasSelectableInput
and onSelectableInputChange
properties improve accessibility for selectable cards.
The first card sets hasSelectableInput
to true, which renders a checkbox input that is only visible to, and navigable by, screen readers. This input communicates to assistive technology users that a card is selectable, and if so, also communicates the current selection state.
By default, this input will have an aria-label that corresponds to the <CardTitle>
. If this isn't defined, then you must pass a custom aria-label using the selectableInputAriaLabel
property.
The first card passes an onChange callback to onSelectableInputChange
to enable the selection/deselection of the associated card via checkbox input.
The second card does not set hasSelectableInput
to true, so neither the input nor the selection state is communicated to users of assistive technologies.
We recommend navigating this example using a screen reader to best understand both cards.
Expandable cards
A card can be made expandable using the isExpanded
property. In the collapsed state, only the card header is shown, and the user can click the caret to view the rest of the card content.
Place any content that you want to be hidden within the <CardExpandableContent>
component.
Expandable with icon
An image can be placed in the card header to show users an icon beside the expansion caret.
Props
Card
Name | Type | Default | Description |
---|---|---|---|
children | React.ReactNode | null | Content rendered inside the Card |
className | string | '' | Additional classes added to the Card |
component | unknown | 'article' | Sets the base component to render. defaults to article |
hasSelectableInput | boolean | false | Flag indicating that the card should render a hidden input to make it selectable |
id | string | '' | ID of the Card. Also passed back in the CardHeader onExpand callback. |
isCompact | boolean | false | Modifies the card to include compact styling. Should not be used with isLarge. |
isDisabledRaised | boolean | false | Modifies a raised selectable card to have disabled styling |
isExpanded | boolean | false | Flag indicating if a card is expanded. Modifies the card to be expandable. |
isFlat | boolean | false | Modifies the card to include flat styling |
isFullHeight | boolean | false | Cause component to consume the available height of its container |
Deprecated: isHoverable | boolean | false | to make a card hoverable, use isSelectable or isSelectableRaised. |
isLarge | boolean | false | Modifies the card to be large. Should not be used with isCompact. |
isPlain | boolean | false | Modifies the card to include plain styling; this removes border and background |
isRounded | boolean | false | Modifies the card to include rounded styling |
isSelectable | boolean | false | Modifies the card to include selectable styling |
isSelectableRaised | boolean | false | Specifies the card is selectable, and applies the new raised styling on hover and select |
isSelected | boolean | false | Modifies the card to include selected styling |
onSelectableInputChange | (labelledBy: string, event: React.FormEvent<HTMLInputElement>) => void | () => {} | Callback that executes when the selectable input is changed |
ouiaId | number | string | Value to overwrite the randomly generated data-ouia-component-id. | |
ouiaSafe | boolean | true | Set the value of data-ouia-safe. Only set to true when the component is in a static state, i.e. no animations are occurring. At all other times, this value must be false. |
selectableInputAriaLabel | string | Aria label to apply to the selectable input if one is rendered |
CardActions
Name | Type | Default | Description |
---|---|---|---|
children | React.ReactNode | null | Content rendered inside the Card Action |
className | string | '' | Additional classes added to the Action |
hasNoOffset | boolean | false | Flag indicating that the actions have no offset |
CardHeader
Name | Type | Default | Description |
---|---|---|---|
children | React.ReactNode | null | Content rendered inside the CardHeader |
className | string | '' | Additional classes added to the CardHeader |
id | string | ID of the card header. | |
isToggleRightAligned | boolean | Whether to right-align expandable toggle button | |
onExpand | (event: React.MouseEvent, id: string) => void | Callback expandable card | |
toggleButtonProps | any | Additional props for expandable toggle button |
CardHeaderMain
Name | Type | Default | Description |
---|---|---|---|
children | React.ReactNode | null | Content rendered inside the Card Head Main |
className | string | '' | Additional classes added to the Card Head Main |
CardTitle
Name | Type | Default | Description |
---|---|---|---|
children | React.ReactNode | null | Content rendered inside the CardTitle |
className | string | '' | Additional classes added to the CardTitle |
component | unknown | 'div' | Sets the base component to render. defaults to div |
CardBody
Name | Type | Default | Description |
---|---|---|---|
children | React.ReactNode | null | Content rendered inside the Card Body |
className | string | '' | Additional classes added to the Card Body |
component | unknown | 'div' | Sets the base component to render. defaults to div |
isFilled | boolean | true | Enables the body Content to fill the height of the card |
CardFooter
Name | Type | Default | Description |
---|---|---|---|
children | React.ReactNode | null | Content rendered inside the Card Footer |
className | string | '' | Additional classes added to the Footer |
component | unknown | 'div' | Sets the base component to render. defaults to div |
CardExpandableContent
Name | Type | Default | Description |
---|---|---|---|
children | React.ReactNode | null | Content rendered inside the Card Body |
className | string | '' | Additional classes added to the Card Body |
CSS variables
.pf-c-card | --pf-c-card--BackgroundColor | #fff | ||
.pf-c-card | --pf-c-card--BoxShadow | 0 0.0625rem 0.125rem 0 rgba(3, 3, 3, 0.12), 0 0 0.125rem 0 rgba(3, 3, 3, 0.06) | ||
.pf-c-card | --pf-c-card--first-child--PaddingTop | 1.5rem | ||
.pf-c-card | --pf-c-card--child--PaddingRight | 1.5rem | ||
.pf-c-card | --pf-c-card--child--PaddingBottom | 1.5rem | ||
.pf-c-card | --pf-c-card--child--PaddingLeft | 1.5rem | ||
.pf-c-card | --pf-c-card--c-divider--child--PaddingTop | 1.5rem | ||
.pf-c-card | --pf-c-card__title--FontFamily | '"RedHatDisplay", "Overpass", overpass, helvetica, arial, sans-serif' | ||
.pf-c-card | --pf-c-card__title--FontSize | 1rem | ||
.pf-c-card | --pf-c-card__title--FontWeight | 700 | ||
.pf-c-card | --pf-c-card__title--not--last-child--PaddingBottom | 1rem | ||
.pf-c-card | --pf-c-card__body--FontSize | 1rem | ||
.pf-c-card | --pf-c-card__footer--FontSize | 1rem | ||
.pf-c-card | --pf-c-card__actions--PaddingLeft | 1rem | ||
.pf-c-card | --pf-c-card__actions--child--MarginLeft | 0.5rem | ||
.pf-c-card | --pf-c-card__header-toggle--MarginTop | calc(0.375rem * -1) | ||
.pf-c-card | --pf-c-card__header-toggle--MarginRight | 0.25rem | ||
.pf-c-card | --pf-c-card__header-toggle--MarginBottom | calc(0.375rem * -1) | ||
.pf-c-card | --pf-c-card__header-toggle--MarginLeft | calc(1rem * -1) | ||
.pf-c-card | --pf-c-card__header-toggle-icon--Transition | all 250ms cubic-bezier(.42, 0, .58, 1) | ||
.pf-c-card | --pf-c-card--m-expanded__header-toggle-icon--Rotate | 90deg | ||
.pf-c-card | --pf-c-card--m-hoverable--hover--BoxShadow | 0 0.5rem 1rem 0 rgba(3, 3, 3, 0.16), 0 0 0.375rem 0 rgba(3, 3, 3, 0.08) | ||
.pf-c-card | --pf-c-card--m-selectable--hover--BoxShadow | 0 0.5rem 1rem 0 rgba(3, 3, 3, 0.16), 0 0 0.375rem 0 rgba(3, 3, 3, 0.08) | ||
.pf-c-card | --pf-c-card--m-selectable--focus--BoxShadow | 0 0.5rem 1rem 0 rgba(3, 3, 3, 0.16), 0 0 0.375rem 0 rgba(3, 3, 3, 0.08) | ||
.pf-c-card | --pf-c-card--m-selectable--active--BoxShadow | 0 0.5rem 1rem 0 rgba(3, 3, 3, 0.16), 0 0 0.375rem 0 rgba(3, 3, 3, 0.08) | ||
.pf-c-card | --pf-c-card--m-selectable--m-selected--BoxShadow | 0 0.5rem 1rem 0 rgba(3, 3, 3, 0.16), 0 0 0.375rem 0 rgba(3, 3, 3, 0.08) | ||
.pf-c-card | --pf-c-card--m-selectable--m-selected--before--Height | 3px | ||
.pf-c-card | --pf-c-card--m-selectable--m-selected--before--BackgroundColor | #06c | ||
.pf-c-card | --pf-c-card--m-hoverable-raised--hover--BoxShadow | 0 0.25rem 0.5rem 0rem rgba(3, 3, 3, 0.12), 0 0 0.25rem 0 rgba(3, 3, 3, 0.06) | ||
.pf-c-card | --pf-c-card--m-hoverable-raised--hover--before--BackgroundColor | #73bcf7 | ||
.pf-c-card | --pf-c-card--m-selectable-raised--before--Right | 0 | ||
.pf-c-card | --pf-c-card--m-selectable-raised--before--Bottom | 0 | ||
.pf-c-card | --pf-c-card--m-selectable-raised--before--Left | 0 | ||
.pf-c-card | --pf-c-card--m-flat--m-selectable-raised--before--Right | calc(-1 * 1px) | ||
.pf-c-card | --pf-c-card--m-flat--m-selectable-raised--before--Bottom | calc(-1 * 1px) | ||
.pf-c-card | --pf-c-card--m-flat--m-selectable-raised--before--Left | calc(-1 * 1px) | ||
.pf-c-card | --pf-c-card--m-selectable-raised--before--Height | 4px | ||
.pf-c-card | --pf-c-card--m-selectable-raised--before--BackgroundColor | transparent | ||
.pf-c-card | --pf-c-card--m-selectable-raised--before--Transition | none | ||
.pf-c-card | --pf-c-card--m-selectable-raised--before--ScaleY | 1 | ||
.pf-c-card | --pf-c-card--m-selectable-raised--before--TranslateY | 0 | ||
.pf-c-card | --pf-c-card--m-selectable-raised--hover--BoxShadow | 0 0.25rem 0.5rem 0rem rgba(3, 3, 3, 0.12), 0 0 0.25rem 0 rgba(3, 3, 3, 0.06) | ||
.pf-c-card | --pf-c-card--m-selectable-raised--hover--before--BackgroundColor | #73bcf7 | ||
.pf-c-card | --pf-c-card--m-selectable-raised--focus--BoxShadow | 0 0.25rem 0.5rem 0rem rgba(3, 3, 3, 0.12), 0 0 0.25rem 0 rgba(3, 3, 3, 0.06) | ||
.pf-c-card | --pf-c-card--m-selectable-raised--focus--before--BackgroundColor | #73bcf7 | ||
.pf-c-card | --pf-c-card--m-selectable-raised--active--BoxShadow | 0 0.25rem 0.5rem 0rem rgba(3, 3, 3, 0.12), 0 0 0.25rem 0 rgba(3, 3, 3, 0.06) | ||
.pf-c-card | --pf-c-card--m-selectable-raised--active--before--BackgroundColor | #73bcf7 | ||
.pf-c-card | --pf-c-card--m-selectable-raised--m-selected-raised--before--BackgroundColor | #06c | ||
.pf-c-card | --pf-c-card--m-selectable-raised--m-selected-raised--BoxShadow | 0 0.5rem 1rem 0 rgba(3, 3, 3, 0.16), 0 0 0.375rem 0 rgba(3, 3, 3, 0.08) | ||
.pf-c-card | --pf-c-card--m-selectable-raised--m-selected-raised--TranslateY--base | -0.5rem | ||
.pf-c-card | --pf-c-card--m-selectable-raised--m-selected-raised--TranslateY | -0.5rem | ||
.pf-c-card | --pf-c-card--m-flat--m-selectable-raised--m-selected-raised--TranslateY | calc(-0.5rem + 1px) | ||
.pf-c-card | --pf-c-card--m-rounded--m-selectable-raised--m-selected-raised--TranslateY | calc(-0.5rem + 3px) | ||
.pf-c-card | --pf-c-card--m-selectable-raised--m-selected-raised--ZIndex | 100 | ||
.pf-c-card | --pf-c-card--m-selectable-raised--m-selected-raised--Transition | transform .25s linear, box-shadow .25s linear | ||
.pf-c-card | --pf-c-card--m-selectable-raised--m-selected-raised--before--Transition | transform .25s linear | ||
.pf-c-card | --pf-c-card--m-selectable-raised--m-selected-raised--before--TranslateY | calc(-0.5rem * -1) | ||
.pf-c-card | --pf-c-card--m-selectable-raised--m-selected-raised--before--ScaleY | 2 | ||
.pf-c-card | --pf-c-card--m-non-selectable-raised--BackgroundColor | #fafafa | ||
.pf-c-card | --pf-c-card--m-non-selectable-raised--before--BackgroundColor | #d2d2d2 | ||
.pf-c-card | --pf-c-card--m-non-selectable-raised--before--ScaleY | 2 | ||
.pf-c-card | --pf-c-card--m-flat--m-non-selectable-raised--before--BorderColor | #d2d2d2 | ||
.pf-c-card | --pf-c-card--m-compact__body--FontSize | 0.875rem | ||
.pf-c-card | --pf-c-card--m-compact__footer--FontSize | 0.875rem | ||
.pf-c-card | --pf-c-card--m-compact--first-child--PaddingTop | 1rem | ||
.pf-c-card | --pf-c-card--m-compact--child--PaddingRight | 1rem | ||
.pf-c-card | --pf-c-card--m-compact--child--PaddingBottom | 1rem | ||
.pf-c-card | --pf-c-card--m-compact--child--PaddingLeft | 1rem | ||
.pf-c-card | --pf-c-card--m-compact--c-divider--child--PaddingTop | 1rem | ||
.pf-c-card | --pf-c-card--m-compact__title--not--last-child--PaddingBottom | 0.5rem | ||
.pf-c-card | --pf-c-card--m-display-lg__title--FontSize | 1.25rem | ||
.pf-c-card | --pf-c-card--m-display-lg--first-child--PaddingTop | 2rem | ||
.pf-c-card | --pf-c-card--m-display-lg--child--PaddingRight | 2rem | ||
.pf-c-card | --pf-c-card--m-display-lg--child--PaddingBottom | 2rem | ||
.pf-c-card | --pf-c-card--m-display-lg--child--PaddingLeft | 2rem | ||
.pf-c-card | --pf-c-card--m-display-lg--c-divider--child--PaddingTop | 2rem | ||
.pf-c-card | --pf-c-card--m-display-lg__title--not--last-child--PaddingBottom | 1.5rem | ||
.pf-c-card | --pf-c-card--m-flat--BorderWidth | 1px | ||
.pf-c-card | --pf-c-card--m-flat--BorderColor | #d2d2d2 | ||
.pf-c-card | --pf-c-card--m-rounded--BorderRadius | 3px | ||
.pf-c-card | --pf-c-card--m-full-height--Height | 100% | ||
.pf-c-card | --pf-c-card--m-plain--BoxShadow | none | ||
.pf-c-card | --pf-c-card--m-plain--BackgroundColor | transparent | ||
.pf-c-card | --pf-c-card__header--m-toggle-right--toggle--MarginRight | calc(0.375rem * -1) | ||
.pf-c-card | --pf-c-card__header--m-toggle-right--toggle--MarginLeft | 0.25rem | ||
.pf-c-card | --pf-c-card__header--m-toggle-right--actions--MarginRight | 0 | ||
.pf-c-card | --pf-c-card__input--focus--BorderWidth | 2px | ||
.pf-c-card | --pf-c-card__input--focus--BorderColor | #06c | ||
.pf-c-card.pf-m-hoverable-raised:hover | --pf-c-card--BoxShadow | 0 0.25rem 0.5rem 0rem rgba(3, 3, 3, 0.12), 0 0 0.25rem 0 rgba(3, 3, 3, 0.06) | ||
.pf-c-card.pf-m-hoverable-raised:hover | --pf-c-card--m-selectable-raised--before--BackgroundColor | #73bcf7 | ||
.pf-c-card.pf-m-selectable-raised:hover | --pf-c-card--BoxShadow | 0 0.25rem 0.5rem 0rem rgba(3, 3, 3, 0.12), 0 0 0.25rem 0 rgba(3, 3, 3, 0.06) | ||
.pf-c-card.pf-m-selectable-raised:hover | --pf-c-card--m-selectable-raised--before--BackgroundColor | #73bcf7 | ||
.pf-c-card.pf-m-selectable-raised:focus | --pf-c-card--BoxShadow | 0 0.25rem 0.5rem 0rem rgba(3, 3, 3, 0.12), 0 0 0.25rem 0 rgba(3, 3, 3, 0.06) | ||
.pf-c-card.pf-m-selectable-raised:focus | --pf-c-card--m-selectable-raised--before--BackgroundColor | #73bcf7 | ||
.pf-c-card.pf-m-selectable-raised:active | --pf-c-card--BoxShadow | 0 0.25rem 0.5rem 0rem rgba(3, 3, 3, 0.12), 0 0 0.25rem 0 rgba(3, 3, 3, 0.06) | ||
.pf-c-card.pf-m-selectable-raised:active | --pf-c-card--m-selectable-raised--before--BackgroundColor | #73bcf7 | ||
.pf-c-card.pf-m-selectable-raised.pf-m-selected-raised | --pf-c-card--m-selectable-raised--before--BackgroundColor | #06c | ||
.pf-c-card.pf-m-selectable-raised.pf-m-selected-raised | --pf-c-card--m-selectable-raised--before--Transition | transform .25s linear | ||
.pf-c-card.pf-m-selectable-raised.pf-m-selected-raised | --pf-c-card--m-selectable-raised--before--TranslateY | calc(-0.5rem * -1) | ||
.pf-c-card.pf-m-selectable-raised.pf-m-selected-raised | --pf-c-card--m-selectable-raised--before--ScaleY | 2 | ||
.pf-c-card.pf-m-non-selectable-raised | --pf-c-card--BackgroundColor | #fafafa | ||
.pf-c-card.pf-m-non-selectable-raised | --pf-c-card--BoxShadow | none | ||
.pf-c-card.pf-m-non-selectable-raised | --pf-c-card--m-flat--BorderColor | #d2d2d2 | ||
.pf-c-card.pf-m-non-selectable-raised | --pf-c-card--m-selectable-raised--before--BackgroundColor | #d2d2d2 | ||
.pf-c-card.pf-m-non-selectable-raised | --pf-c-card--m-selectable-raised--before--ScaleY | 2 | ||
.pf-c-card.pf-m-compact | --pf-c-card__body--FontSize | 0.875rem | ||
.pf-c-card.pf-m-compact | --pf-c-card__footer--FontSize | 0.875rem | ||
.pf-c-card.pf-m-compact | --pf-c-card--first-child--PaddingTop | 1rem | ||
.pf-c-card.pf-m-compact | --pf-c-card--child--PaddingRight | 1rem | ||
.pf-c-card.pf-m-compact | --pf-c-card--child--PaddingBottom | 1rem | ||
.pf-c-card.pf-m-compact | --pf-c-card--child--PaddingLeft | 1rem | ||
.pf-c-card.pf-m-compact | --pf-c-card--c-divider--child--PaddingTop | 1rem | ||
.pf-c-card.pf-m-compact | --pf-c-card__title--not--last-child--PaddingBottom | 0.5rem | ||
.pf-c-card.pf-m-display-lg | --pf-c-card__title--FontSize | 1.25rem | ||
.pf-c-card.pf-m-display-lg | --pf-c-card--first-child--PaddingTop | 2rem | ||
.pf-c-card.pf-m-display-lg | --pf-c-card--child--PaddingRight | 2rem | ||
.pf-c-card.pf-m-display-lg | --pf-c-card--child--PaddingBottom | 2rem | ||
.pf-c-card.pf-m-display-lg | --pf-c-card--child--PaddingLeft | 2rem | ||
.pf-c-card.pf-m-display-lg | --pf-c-card--c-divider--child--PaddingTop | 2rem | ||
.pf-c-card.pf-m-display-lg | --pf-c-card__title--not--last-child--PaddingBottom | 1.5rem | ||
.pf-c-card.pf-m-flat | --pf-c-card--BoxShadow | none | ||
.pf-c-card.pf-m-flat | --pf-c-card--m-selectable-raised--before--Right | calc(-1 * 1px) | ||
.pf-c-card.pf-m-flat | --pf-c-card--m-selectable-raised--before--Bottom | calc(-1 * 1px) | ||
.pf-c-card.pf-m-flat | --pf-c-card--m-selectable-raised--before--Left | calc(-1 * 1px) | ||
.pf-c-card.pf-m-flat | --pf-c-card--m-selectable-raised--m-selected-raised--TranslateY | calc(-0.5rem + 1px) | ||
.pf-c-card.pf-m-plain | --pf-c-card--BoxShadow | none | ||
.pf-c-card.pf-m-plain | --pf-c-card--BackgroundColor | transparent | ||
.pf-c-card.pf-m-rounded | --pf-c-card--m-selectable-raised--m-selected-raised--TranslateY | calc(-0.5rem + 3px) | ||
.pf-c-card__header .pf-c-card__title | --pf-c-card--first-child--PaddingTop | 0 | ||
.pf-c-card__header .pf-c-card__title | --pf-c-card__title--not--last-child--PaddingBottom | 0 | ||
.pf-c-card__header.pf-m-toggle-right | --pf-c-card__header-toggle--MarginRight | calc(0.375rem * -1) | ||
.pf-c-card__header.pf-m-toggle-right | --pf-c-card__header-toggle--MarginLeft | 0.25rem | ||
.pf-c-card__header.pf-m-toggle-right .pf-c-card__actions | --pf-c-card__header-toggle--MarginRight | 0 | ||
.pf-c-card__actions.pf-m-no-offset | --pf-c-card__header-toggle--MarginTop | 0 | ||
.pf-c-card__actions.pf-m-no-offset | --pf-c-card__header-toggle--MarginBottom | 0 | ||
.pf-c-card__expandable-content | --pf-c-card--first-child--PaddingTop | 0 |
View source on GitHub