Card components are a way to group and display related information into a container. Sometimes users can interact with them by clicking or tapping to see more details.
In this article, we will learn how to build reusable, customizable, and responsive card component using Chakra UI.
Sandbox
The completed project is on CodeSandbox. Fork it and run the code.
The source code is also available on GitHub.
Prerequisites
The knowledge of Chakra UI is needed to get the most out of this article.
While we created the demo with Next.js, it is not a requirement, and we can transfer the knowledge to work with any frontend framework compatible with Chakra UI.
Getting Started
We create a Next.js project by running the command below in our terminal.
1npx create-next-app airbnb-cards-demo
Next, we navigate into the project directory.
1cd airbnb-cards-demo
We run the command below to install Chakra UI.
1npm i @chakra-ui/react @emotion/react@^11 @emotion/styled@^11 framer-motion@^6
Finally, we need to integrate Chakra UI into our application by adding ChakraProvider
to the root of our application in the _app.js
file.
pages/_app.js
1import { ChakraProvider } from '@chakra-ui/react'2function MyApp({ Component, pageProps }) {3 return (4 <ChakraProvider>5 <Component {...pageProps} />6 </ChakraProvider>7 )8}9export default MyApp
Creating the Custom Theme
Since we are modeling the cards after Airbnb, it is only proper we use the colors they used for their card component.
To do this, we create a theme/index.js
file in the root directory and add the snippet below.
1import { extendTheme } from "@chakra-ui/react";23const theme = extendTheme({4 colors: {5 black: "#000",6 white: "#fff",7 gray: {8 50: "#717171",9 100: "#222222",10 },11 },12});1314export default theme;
We can extend Chakra UI’s default theme using the extendTheme
function. We add white, black, and the shades of gray we need.
Creating the Card Component
An Airbnb card consists of the following:
- an image of the property
- the name of the property
- the property’s distance
- the property’s price
- the date
We will need to create a card component that contains all of this information.
We begin by creating a components/Card.js
file in the root and adding the code below:
1import { Box, Image, Heading, Text, Flex, Stack } from "@chakra-ui/react";23export default function Card({ img, name, distance, date, price }) {4 return (5 <Box w="full">6 <Image7 h="337px"8 w="full"9 borderRadius="12px"10 mb="10px"11 src={`/images/${img}`}12 alt="A house"13 fontSize="16px"14 objectFit="cover"15 />16 <Stack spacing="0">17 <Flex justifyContent="space-between">18 <Heading19 as="h2"20 fontWeight="bold"21 color="gray.100"22 fontSize="16px"23 isTruncated24 >25 {name}26 </Heading>27 <Text as="span" color="gray.100" ml="4">28 ${price}/night29 </Text>30 </Flex>31 <Flex justifyContent="space-between">32 <Text as="span" color="gray.50">33 {distance} kilometers away34 </Text>35 <Text as="span" color="gray.50">36 {date}37 </Text>38 </Flex>39 </Stack>40 </Box>41 );42}
In the code above:
- We create the
Card
component. It acceptsname
,img
,distance
,date
, andprice
through props. - The
Image
component takes in theimg
prop for thesrc
. We set*objectFit*
tocover
to prevent the images from shrinking and getting distorted in reaction to the dimension of its parent. - We pass in the
name
,distance
,date
,price
to their respective Chakra UI components.
The Properties’ Data
The code snippet below is a sample of the data we will pass to the card component through props.
1const data = [2 {3 name: "Lagos, Nigeria",4 distance: "3,619",5 date: "Mar 13 – 20",6 price: "213",7 img: "1.jpg",8 },9 {10 name: "Delta, Nigeria",11 distance: "3,619",12 date: "Mar 13 – 20",13 price: "213",14 img: "2.jpg",15 },16 //more data objects below17]
Setting up the Grid
Next, let’s set up the grid to lay out the cards.
To do that, we update the pages/index.js
file with the code below:
1import Head from "next/head";2import { Heading, SimpleGrid } from "@chakra-ui/react";3import Card from "@components/Card";4import data from "data/index";56export default function Home() {7 return (8 <div>9 <Head>10 <title>Chakra UI Airbnb Card</title>11 </Head>1213 <Heading as="h1" mb="10">14 Chakra UI Airbnb15 </Heading>1617 <SimpleGrid minChildWidth="300px" spacing="10" minH="full">18 {data.map((house, i) => (19 <Card20 key={i}21 name={house.name}22 img={house.img}23 distance={house.distance}24 date={house.date}25 price={house.price}26 />27 ))}28 </SimpleGrid>29 </div>30 );31}
In the code above, we use:
Head
to add the metadata for the demo.Heading
to set the heading of the demo.SimpleGrid
to easily add a responsive grid layout for the cards. We iterate through the properties’data
and render the card for each property.
Creating the Layout Component
Finally, we need to give the demo a layout to bring it all together.
1import { Box } from "@chakra-ui/react";23export default function Layout({ children }) {4 return (5 <Box maxW="1500px" p={["6"]} mx="auto" my="10">6 {children}7 </Box>8 );9}
We set the max-width of the app to 1500px and the horizontal margin to auto. By doing so, we vertically center the app.
Next, we use the layout in our pages/_app.js
file by updating it with the code below:
1import { ChakraProvider, ScaleFade } from "@chakra-ui/react";2import Layout from "@layout/index";3import theme from "theme/index";45function MyApp({ Component, pageProps, router }) {6 return (7 <ChakraProvider theme={theme}>8 <Layout>9 <ScaleFade key={router.route} initialScale={0.9} in="true">10 <Component {...pageProps} />11 </ScaleFade>12 </Layout>13 </ChakraProvider>14 );15}16export default MyApp;
Besides adding the layout, we also use the ScaleFade
component to add a nice transition to the demo.
The image below shows the completed demo.
Conclusion
Our components must not just be functional. They must also be responsive and pleasing to the eye. Chakra UI empowers us to create accessible, responsive, and appealing user interfaces.
This article taught us how to build a Grid of Airbnb-inspired cards using Chakra UI.
You may find these resources helpful: