Skip to main content

Component Card

· 24 min read
Docux
Curious explorer, a bit of a mad experimenter, and a bit of a contributor.

Developer Developement License: MIT AI 0%

With Infima CSS framework, I’ve created a reusable card component that you can use on your Docusaurus site. With it, you’ll be able to customize each card with different colors and sizes. This component allows you to generate all the cards available in Infima as well as “Custom” cards, and you’ll be able to create and personalize each card independently.

The component is in fact a set of small components that will admit to form the cards.

Card : composition of the master folder

  • Card component index.js (The container of alls parts)
  • CardHeader component (Header parts of cards)
  • CardBody component (Body parts of cards)
  • CardImage component (Image cover parts of cards)
  • CardFooter component (Footer parts of cards)

We will discover that it pairs wonderfully with other components present in our library but this will be the subject of a dedicated page.

Creating the Card component

Publication

This article was originally published by DocuxLab on the Docusaurus Community and is republished here with new examples.

Think of this component as the container of all card parts

First we will create the master folder in: \src\components\Card\. Next we will start by creating a new component called Card. It will be the container component of our different parts to come. Also this will give the possibility to manage className and style for each part.

The component will accept the following props:

  • shadow: if you want to show a shadow under the map.

Creating the file and adding the source code for the component.

\src\components\Card\index.js
import React, {CSSProperties} from 'react'; // CSSProperties allows inline styling with better type checking.
import clsx from 'clsx'; // clsx helps manage conditional className names in a clean and concise manner.

const Card = ({
className, // classNamees for the container card
style, // Custom styles for the container card
children, // for include others parts in
shadow, // for add shadow under your card Shadow levels: low (lw), medium (md), top-level (tl)
}) => {
const cardShadow = shadow
? `item shadow--${shadow}`
: '';
return (
<div className="card-demo">
<div className={clsx("card", className, cardShadow)} style={style}>
{children}
</div>
</div>
);
};

export default Card;

Creating the CardHeader component

Think of this component as the header of your future cards. Create the file and add the source code for the component. The component will accept the following props:

  • textAlign: The option for text alignment left right center justify
  • variant: (optional)This will be used to apply different colors to the text based on the Infima CSS utility classNamees. The default value is primary.
  • italic: Default value is false, it's for italic text render
  • noDecoration: Default value is false, it's for delete text decoration
  • transform: The option for transform text to UPPERCASE TEXT lowercase text or Capitalize Text
  • truncate: The option is for very long text that will be truncated if there is not enough space to display it in a single line on the screen. It's truncated by adding …
  • weight: The option for text weight Bold Semibold Normal Light
\src\components\Card\CardHeader\index.js
import React, {CSSProperties} from 'react'; // CSSProperties allows inline styling with better type checking.
import clsx from 'clsx'; // clsx helps manage conditional className names in a clean and concise manner.
import styles from '../styles.module.css';

const CardHeader = ({
className, // classNamees for the container card
style, // Custom styles for the container card
children, // Content to be included within the card
textAlign,
variant,
italic = false,
noDecoration = false,
transform,
truncate = false,
weight
}) => {
const text = textAlign
? `text--${textAlign}`
: '';
const textColor = variant
? `text--${variant}`
: '';
const textItalic = italic
? 'text--italic'
: '';
const textDecoration = noDecoration
? 'text-no-decoration'
: '';
const textType = transform
? `text--${transform}`
: '';
const textTruncate = truncate
? styles.truncate
: '';
const textWeight = weight
? `text--${weight}`
: '';
return (
<div
className={clsx(
'card__header',
className,
text,
textType,
textColor,
textItalic,
textDecoration,
textTruncate,
textWeight
)}
style={style}>

{children}
</div>
);
}

export default CardHeader;

Creating the CardBody component

Think of this component as the body of your futurs cards. Creating the file and adding the source code for the component.The component will accept the following props:

  • textAlign: The option for text alignment left right center justify
  • variant: (optional)This will be used to apply different colors to the text based on the Infima CSS utility classNamees. The default value is primary.
  • italic: Default value is false, it's for italic text render
  • noDecoration: Default value is false, it's for delete text decoration
  • transform: The option for transform text to UPPERCASE TEXT lowercase text or Capitalize Text
  • truncate: The option is for very long text that will be truncated if there is not enough space to display it in a single line on the screen. It's truncated by adding …
  • weight: The option for text weight Bold Semibold Normal Light
\src\components\Card\CardBody\index.js
import React, {CSSProperties} from 'react';
import clsx from 'clsx';
import styles from '../styles.module.css';

const CardBody = ({
className, // classNamees for the container card
style, // Custom styles for the container card
children, // Content to be included within the card
textAlign,
variant,
italic = false,
noDecoration = false,
transform,
truncate = false,
weight
}) => {
const text = textAlign
? `text--${textAlign}`
: '';
const textColor = variant
? `text--${variant}`
: '';
const textItalic = italic
? 'text--italic'
: '';
const textDecoration = noDecoration
? 'text-no-decoration'
: '';
const textType = transform
? `text--${transform}`
: '';
const textTruncate = truncate
? styles.truncate
: '';
const textWeight = weight
? `text--${weight}`
: '';
return (
<div
className={clsx(
'card__body',
className,
text,
textType,
textColor,
textItalic,
textDecoration,
textTruncate,
textWeight
)}
style={style}>
{children}
</div>
);
}

export default CardBody;


Creating the CardImage component

Think of this component as the image cover of your futurs cards. Creating the file and adding the source code for the component. This component is optionnal, you can use image html and add className={clsx("card__image")}

\src\components\Card\CardImage\index.js
import React, {CSSProperties} from 'react';
import clsx from 'clsx';
import useBaseUrl from '@docusaurus/useBaseUrl'; // Import the useBaseUrl function from Docusaurus

const CardImage = ({className, style, cardImageUrl, alt, title}) => {

const generatedCardImageUrl = useBaseUrl(cardImageUrl);

return (

<img
className={clsx("card__image", className)}
style={style}
src={generatedCardImageUrl}
alt={alt}
title={title}/>

);
}

export default CardImage;



Creating the CardFooter component

Think of this component as the Footer of your futurs cards. Creating the file and adding the source code for the component.The component will accept the following props:

  • textAlign: The option for text alignment left right center justify
  • variant: (optional)This will be used to apply different colors to the text based on the Infima CSS utility classNamees. The default value is primary.
  • italic: Default value is false, it's for italic text render
  • noDecoration: Default value is false, it's for delete text decoration
  • transform: The option for transform text to UPPERCASE TEXT lowercase text or Capitalize Text
  • truncate: The option is for very long text that will be truncated if there is not enough space to display it in a single line on the screen. It's truncated by adding …
  • weight: The option for text weight Bold Semibold Normal Light
\src\components\Card\CardFooter\index.js
import React, {CSSProperties} from 'react';
import clsx from 'clsx';
import styles from '../styles.module.css';

const CardFooter = ({
className,
style,
children,
textAlign,
variant,
italic = false,
noDecoration = false,
transform,
truncate = false,
weight
}) => {
const text = textAlign
? `text--${textAlign}`
: '';
const textColor = variant
? `text--${variant}`
: '';
const textItalic = italic
? 'text--italic'
: '';
const textDecoration = noDecoration
? 'text-no-decoration'
: '';
const textType = transform
? `text--${transform}`
: '';
const textTruncate = truncate
? styles.truncate
: '';
const textWeight = weight
? `text--${weight}`
: '';
return (
<div
className={clsx(
'card__footer',
className,
text,
textType,
textColor,
textItalic,
textDecoration,
textTruncate,
textWeight
)}
style={style}>
{children}
</div>
);
}

export default CardFooter;


MDX Component Scope

To follow the Docusaurus documentation, we create a theme folder that will host the MDXComponents file. This gives us src\theme\MDXComponents.*. You may already have a src\theme folder or an MDXComponents file if so - merge the changes described here with yours.

src\theme\MDXComponents.js
 import React from 'react';
// Importing the original mapper + our components according to the Docusaurus
// doc
import MDXComponents from '@theme-original/MDXComponents';
import Card from '@site/src/components/Card/Card';
import CardBody from '@site/src/components/Card/CardBody';
import CardFooter from '@site/src/components/Card/CardFooter';
import CardHeader from '@site/src/components/Card/CardHeader';
import CardImage from '@site/src/components/Card/CardImage';

export default {
// Reusing the default mapping
...MDXComponents,
Card,
CardHeader,
CardBody,
CardFooter,
CardImage
};

Using the Cards Component in an MDX File

Basic card

Lorem Ipsum

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis ipsum suspendisse ultrices gravida.

<Card shadow='tl'>
<CardHeader >
<h3>Lorem Ipsum</h3>
</CardHeader>

<CardBody>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua. Quis ipsum suspendisse ultrices
gravida.
</CardBody>

<CardFooter>

<button className="button button--secondary button--block">See All</button>

</CardFooter>

</Card>

Feed card

Docux

Curious explorer, a bit of a mad experimenter, and a bit of a contributor. @docuxlab.com

Docux Card component

Welcome to DocuxLab, your space for tech discoveries, development tutorials, and tips to enhance your digital projects. Here, we break down code, explore web trends, and share practical resources for all tech enthusiasts.

Explore our articles, guides, and interactive demos designed to help you stay at the forefront of innovation. Whether you are a beginner developer or an experienced pro, DocuxLab is here to inspire and support you in your digital projects.

<Card className='margin-bottom--lg'>
<CardHeader style={{ backgroundColor: '#205d3b' , color:'black'} }>
<div className="avatar avatar--vertical">
<img
className="avatar__photo avatar__photo--xl"
src="https://avatars.githubusercontent.com/u/97809069?v=4"/>
<div className="avatar__intro">
<div className="avatar__name">Docux</div>
<small className="avatar__subtitle">
Curious explorer, a bit of a mad experimenter, and a bit of a contributor.
<a style={{ color:'white'} } href="https://docuxlab.com/">@docuxlab.com</a>
</small>
</div>
</div>
</CardHeader>
<CardBody
style={{ backgroundColor: 'black' , color:'silver'}}
className="padding-vert--md"
textAlign='center'
Transform='uppercase'>
<h3>Docux Card component</h3>

Welcome to DocuxLab, your space for tech discoveries, development tutorials, and
tips to enhance your digital projects. Here, we break down code, explore web
trends, and share practical resources for all tech enthusiasts. Explore our
articles, guides, and interactive demos designed to help you stay at the
forefront of innovation. Whether you are a beginner developer or an experienced
pro, DocuxLab is here to inspire and support you in your digital projects.
</CardBody>

<CardFooter
style={{ backgroundColor: '#205d3b' , color:'black'}}
className='text--center'>
<div className="button-group button-group--block">
<button className="button button--secondary button--sm">Like</button>
<button className="button button--secondary button--sm">Comment</button>
<button className="button button--secondary button--sm">Share</button>
</div>
</CardFooter>

</Card>

Mega Feed card

Docux

Curious explorer, a bit of a mad experimenter, and a bit of a contributor. @docuxlab.com

New Discovery

Amazing discovery! I've found an incredible website: avonture.be. This comprehensive resource offers in-depth tutorials, practical examples, and expert insights into various development topics.

<Card>
<CardHeader
className='padding-top--lg'
style={{ backgroundColor: 'rgb(33 126 209)' , color:'black'}}>
<div className="avatar avatar--vertical">
<img
className="avatar__photo avatar__photo--xl"
src="https://avatars.githubusercontent.com/u/97809069?v=4"/>
<div className="avatar__intro">
<div className="avatar__name">Docux</div>
<small className="avatar__subtitle">
Curious explorer, a bit of a mad experimenter, and a bit of a contributor.
<a style={{ color:'white'} } href="https://docuxlab.com/">@docuxlab.com</a>
</small>
</div>
</div>
</CardHeader>

<CardImage
style={{ backgroundColor: 'rgb(33 126 209)' , color:'black'}}
cardImageUrl="/img/learn-docker-in-avonture-blog.webp"/>

<CardBody
style={{ backgroundColor: '#fefacb' , color:'#8f600b'}}
className="padding-vert--md"
textAlign='center'
Transform='uppercase'>
<h3>New feature</h3>

Amazing discovery! I've found an incredible website:
[avonture.be](https://www.avonture.be/). This comprehensive resource offers
in-depth tutorials, practical examples, and expert insights into various
development topics.

</CardBody>

<CardFooter
style={{ backgroundColor: '#2887bf' , color:'black'}}
className='text--center'>
<div className="button-group button-group--block">
<button className="button button--secondary button--sm">Like</button>
<button className="button button--secondary button--sm">Comment</button>
<button className="button button--secondary button--sm">Share</button>
</div>
</CardFooter>

</Card>

Photo card

 <Card className='margin-bottom--lg'>

<CardImage cardImageUrl="/img/docux.webp"/>

<CardFooter
style={{ backgroundColor: '#07ac2aff' , color:'#eeff00ff' }}
className='text--center'>
<div className="button-group button-group--block">
<button className="button button--primary button--sm">Like</button>
<button className="button button--secondary button--sm">Comment</button>
<button className="button button--info button--sm">Share</button>
</div>
</CardFooter>

</Card>

Photo card Avatar

 <Card className='margin-bottom--lg'>

<CardImage cardImageUrl="/img/learn-docusaurus-and-react.webp"/>

<CardFooter
style={{ backgroundColor: 'white' , color:'black'}}
className='text--center'>
<div className="avatar">
<img
className="avatar__photo avatar__photo--xs"
src="https://avatars.githubusercontent.com/u/97809069?v=4"/>
<div className="avatar__intro">
<div className="avatar__name">Learn Docusaurus</div>

</div>
</div>

</CardFooter>

</Card>

Other Post card

The Infima CSS framework provides a set of utility classNames that can be used to style card in Docusaurus. This article will cover how to create a reusable card component for your Docusaurus site that can be customized with different colors and sizes.

<Card shadow='tl'>
<CardBody
style={{ backgroundColor: 'white' , color:'black'}}
className="padding-vert--md "
Transform='uppercase'>
A must-visit site for developers looking to expand their knowledge and skills!
</CardBody>
<CardFooter style={{ backgroundColor: '#7a9f3d' , color:'#d7de3d'}}>

<div className="avatar padding-top--md">
<img
className="avatar__photo"
src="https://avatars.githubusercontent.com/u/97809069?v=4"/>
<div className="avatar__intro">
<div className="avatar__name">Docux</div>
<small className="avatar__subtitle">
Curious explorer, a bit of a mad experimenter, and a bit of a contributor.
</small>
</div>
</div>
</CardFooter>
</Card>

Multi demo card

Docux

Curious explorer, a bit of a mad experimenter, and a bit of a contributor. @docuxlab.com

DocuxLab

A must-visit site for developers looking to expand their knowledge and skills!

Docux

Curious explorer, a bit of a mad experimenter, and a bit of a contributor. @docuxlab.com

DocuxLab

A must-visit site for developers looking to expand their knowledge and skills!

Docux Card component

Welcome to DocuxLab, your space for tech discoveries, development tutorials, and tips to enhance your digital projects. Here, we break down code, explore web trends, and share practical resources for all tech enthusiasts. Explore our articles, guides, and interactive demos designed to help you stay at the forefront of innovation. Whether you are a beginner developer or an experienced pro, DocuxLab is here to inspire and support you in your digital projects.

Why truncate in styles.module.css

The truncate functionality uses CSS Modules to provide better encapsulation and avoid conflicts with global styles. Here's a detailed breakdown of how the .truncate p CSS works:

\src\components\Card\styles.module.css
.truncate p {
display: -webkit-box;
-webkit-line-clamp: 3;
line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
margin-bottom: 0;
word-wrap: break-word;
max-height: 4.5em; /* 3 lines × 1.5em line-height */
line-height: 1.5em;
}

Detailed CSS Properties Explanation:

1. display: -webkit-box;

  • Enables the WebKit flexible box model (legacy syntax)
  • Required for -webkit-line-clamp to function properly
  • Foundation of the multi-line truncation system

2. -webkit-line-clamp: 3; and line-clamp: 3;

  • Limits display to 3 lines maximum
  • -webkit-line-clamp: WebKit version (Safari, Chrome)
  • line-clamp: Modern standard version
  • Both included for cross-browser compatibility

3. -webkit-box-orient: vertical;

  • Defines the orientation of "boxes" vertically
  • Specifies that lines stack vertically
  • Mandatory when using -webkit-line-clamp

4. overflow: hidden;

  • Hides any content that exceeds the container
  • Essential for concealing additional lines (beyond the 3rd)

5. text-overflow: ellipsis;

  • Adds ellipsis (...) at the end of truncated text
  • Only works with overflow: hidden
  • Provides the visual "..." effect

6. margin-bottom: 0;

  • Removes bottom margin from paragraphs
  • Prevents unwanted spacing after truncated text

7. word-wrap: break-word;

  • Allows long words to break when necessary
  • Prevents words from overflowing container width

8. max-height: 4.5em; and line-height: 1.5em;

  • Fallback for browsers that don't support line-clamp
  • 4.5em = 3 lines × 1.5em per line
  • Provides height limitation if line-clamp fails

Why Target .truncate p?

The selector specifically targets paragraphs <p> inside elements with the .truncate class. This approach provides:

  • Precision: Only text content gets truncated
  • Preservation: Headings <h1>, <h2>, <h3> remain intact
  • Flexibility: You can have non-truncated content in the same CardBody

basic Example:

<CardBody truncate> {/* = <true> */}
<h3>Complete Title</h3> {/* ← Not truncated */}

<p> {/* ← Will be truncated */}
Very long text that will be automatically
truncated after 3 lines with ellipsis
at the end...
</p>
</CardBody>

Docux Card component

Welcome to DocuxLab, your space for tech discoveries, development tutorials, and tips to enhance your digital projects. Here, we break down code, explore web trends, and share practical resources for all tech enthusiasts. Explore our articles, guides, and interactive demos designed to help you stay at the forefront of innovation. Whether you are a beginner developer or an experienced pro, DocuxLab is here to inspire and support you in your digital projects.

This modern CSS technique provides effective multi-line truncation that works across different browsers and maintains clean, readable layouts in your card components.

Tricks and Tips

The columns are made according to the infima grid, they are hard coded on this page so that the card component is independent. But if you want to use an easy and quick system for managing your columns while using the Infima grid system look at our component Columns component

This article is part of the infima components series:

Related posts

Retour en haut