如何在 Chakra UI 和 React JS 中创建现代卡片⚡️

2025-05-24

如何在 Chakra UI 和 React JS 中创建现代卡片⚡️

有时,打造出色的 UI 不仅需要时间,还需要专注。即使是某些卡片式设计,对结构、间距、配色等等的关注也至关重要。

如今,我们可以肯定地说,卡片已经成为网站和移动应用程序 UI 的设计趋势和主要元素,我们有来自 Revolut、Apple 和 Google 等大公司的例子,它们在其网站和应用程序上使用交互式现代卡片,为客户和用户提供使用其解决方案的绝佳体验!

因此,当我们开始设计和开发卡片时,我们需要考虑一些重要方面:

  • 卡片内容应该非常紧凑和直观,所以我们需要将其保持在单一的卡片结构中。

  • 整个卡片应该非常易于阅读和使用。这决定了UI和UX的优劣。因此,我们需要注意使其简洁通透(设计技巧:不要害怕使用留白,尽可能多地使用)。

  • 卡片应该只包含能够展现信息的重要元素,正如我上面所说,我们需要保持卡片简洁明了。例如,CTA 卡片应该包含标题、副标题、或许还有一张图片,以及一个可以触发操作的 CTA 按钮。

定义 UI 卡片流行的另一个重要方面是它们有助于响应式 UI 设计,由于它们的方形形状可以完美适合任何网格结构,因此它们可以轻松缩小到任何设备分辨率。

让我们直接看卡片示例!

在今天的示例中,我们将制作三张符合最新 UI 趋势的简单卡片。我们从 Horizo​​n UI React 卡片中汲取了一些设计灵感,您可以在他们的网站上看到更多类似的精彩免费 React 卡片。

来自 horizo​​n-ui.com 的免费 React 和 Chakra UI 卡

太好了,让我们对它们进行编码吧!

正如你已经看到的,我们今天要用来构建精美卡片的 React JS 库是 Chakra UI。此外,我们还将借助Chakra 主题工具React 图标等工具。

首先,让我们安装 Chakra UI 及其上述附加组件:



npm i @chakra-ui/react @chakra-ui/theme @chakra-ui/theme-tools react-icons


Enter fullscreen mode Exit fullscreen mode

之后,我们需要创建一个style.js文件并输入以下样式:



// @src/theme/styles.js

import { mode } from "@chakra-ui/theme-tools";

export const globalStyles = {
  colors: {
    gray: {
      700: "#1f2733",
    },
    navy: {
      50: "#d0dcfb",
      100: "#aac0fe",
      200: "#a3b9f8",
      300: "#728fea",
      400: "#3652ba",
      500: "#1b3bbb",
      600: "#24388a",
      700: "#1b254b",
      800: "#111c44",
      900: "#0b1437",
    },
    brand: {
      50: "#cbbff8",
      100: "#876cea",
      200: "#582CFF",
      300: "#542de1",
      400: "#7551FF",
      500: "#4318FF",
      600: "#300eaa",
      700: "#1c0377",
      800: "#130156",
      900: "#0e0042",
    },
  },
  styles: {
    global: (props) => ({
      body: {
        overflowX: "hidden",
        bg: mode("gray.50", "#1B254B")(props),
      },
      html: {
        fontFamily: "Helvetica, sans-serif",
      },
    }),
  },
};


Enter fullscreen mode Exit fullscreen mode

太棒了!在/theme目录下的components文件夹中,我们修改了各种 Chakra UI 组件,例如 或 。要使用它们,我们需要为每个组件创建一个包含所有样式文件(badge.jsbutton.jsbreakpoints.js)的特殊文件夹!

为以下组件创建一个特殊文件:

徽章.js



// @src/theme/components/badge.js

export const badgeStyles = {
    components: {
        Badge: {
            sizes: {
                md: {
                    width: "65px",
                    height: "25px"
                }
            },
            baseStyle: {
                textTransform: "capitalize"
            }
        }
    }
}


Enter fullscreen mode Exit fullscreen mode

按钮.js



// @src/theme/components/button.js

import { mode } from "@chakra-ui/theme-tools";
export const buttonStyles = {
  components: {
    Button: {
      variants: {
        primary: {
          fontSize: "10px",
          bg: "blue.400",
          color: "#fff",
          _hover: { bg: "blue.300" },
          _focus: { bg: "blue.300" },
          _active: { bg: "blue.300" },
        },
        navy: {
          fontSize: "10px",
          bg: "navy.900",
          color: "#fff",
          _hover: { bg: "navy.900" },
          _focus: { bg: "navy.900" },
          _active: { bg: "navy.900" },
        },
        "no-effects": {
          _hover: "none",
          _active: "none",
          _focus: "none",
        },
        danger: () => ({
          color: "white",
          bg: "red.500",
          fontSize: "10px",
          _hover: "red.400",
          _focus: "red.400",
          _active: "red.400",
        }),
        outlined: (props) => ({
          color: mode("blue.400", "white")(props),
          bg: "transparent",
          fontSize: "10px",
          border: "1px solid",
          borderColor: { bg: mode("blue.400", "white")(props)},
          _hover: { bg: mode("blue.50", "transparent")(props) },
          _focus: { bg: mode("blue.50", "transparent")(props) },
          _active: { bg: mode("blue.50", "transparent")(props) },
        }),
        dark: (props) => ({
          color: "white",
          bg: mode("gray.700", "blue.500")(props),
          fontSize: "10px",
          _hover: { bg: mode("gray.700", "blue.500")(props) },
          _focus: { bg: mode("gray.700", "blue.600")(props) },
          _active: { bg: mode("gray.700", "blue.400")(props) },
        }),
        light: (props) => ({
          color: mode("gray.700", "gray.700")(props),
          bg: mode("gray.100", "white")(props),
          fontSize: "10px",
          _hover: { bg: mode("gray.50", "white")(props) },
          _focus: { bg: mode("gray.50", "white")(props) },
          _active: { bg: mode("gray.50", "white")(props) },
        }),
      },
      baseStyle: {
        fontWeight: "bold",
        borderRadius: "8px",
        fontSize: "10px",
      },
    },
  },
};


Enter fullscreen mode Exit fullscreen mode

修改完常规样式后,设置其他断点以提高响应式准确性也会很有帮助。使用以下代码创建breakpoints.js文件:



// @src/theme/theme.js

import { extendTheme } from "@chakra-ui/react";
import { globalStyles } from "./styles";
import { breakpoints } from "./foundations/breakpoints";
import { buttonStyles } from "./components/button";
import { badgeStyles } from "./components/badge";
export default extendTheme(
  { breakpoints }, // Breakpoints
  globalStyles, // Global styles
  buttonStyles, // Button styles
  badgeStyles, // Badge styles
);


Enter fullscreen mode Exit fullscreen mode

此后,在index.js中,将主题添加到成分:



// @src/index.js

import React from 'react';
import ReactDOM from 'react-dom'; 
import App from 'App';   
import { ChakraProvider } from "@chakra-ui/react";
// Custom Chakra theme
import theme from "theme/theme.js";

ReactDOM.render(
  <ChakraProvider theme={theme} resetCss={false} position="relative">
    <App />
  </ChakraProvider>,
  document.getElementById("root")
);


Enter fullscreen mode Exit fullscreen mode

太棒了!让我们开始编写 Chakra UI + React 卡片的结构吧!⚡️

我们需要做的就是为每个文件创建一个特殊的文件并粘贴以下代码:

Chakra UI - 个人资料卡

个人资料卡 Chakra UI - Horizo​​n UI



// @src/components/Profile.js

import React from "react";
// Chakra imports
import { Flex, Image, Text, useColorModeValue } from "@chakra-ui/react";

function Profile() {
let boxBg = useColorModeValue("white !important", "#111c44 !important");
let mainText = useColorModeValue("gray.800", "white");
let secondaryText = useColorModeValue("gray.400", "gray.400");

return (
<Flex
borderRadius='20px'
bg={boxBg}
p='20px'
h='345px'
w={{ base: "315px", md: "345px" }}
alignItems='center'
direction='column'>
<Image
src='https://i.ibb.co/xmP2pS6/Profile.png'
maxW='100%'
borderRadius='20px'
/>
<Flex flexDirection='column' mb='30px'>
<Image
src='https://i.ibb.co/B3gYTYs/Profile-Image.png'
border='5px solid red'
mx='auto'
borderColor={boxBg}
width='68px'
height='68px'
mt='-38px'
borderRadius='50%'
/>
<Text
fontWeight='600'
color={mainText}
textAlign='center'
fontSize='xl'>
Adela Parkson
</Text>
<Text
color={secondaryText}
textAlign='center'
fontSize='sm'
fontWeight='500'>
Product Designer
</Text>
</Flex>
<Flex justify='space-between' w='100%' px='36px'>
<Flex flexDirection='column'>
<Text
fontWeight='600'
color={mainText}
fontSize='xl'
textAlign='center'>
17
</Text>
<Text color={secondaryText} fontWeight='500'>
Posts
</Text>
</Flex>
<Flex flexDirection='column'>
<Text
fontWeight='600'
color={mainText}
fontSize='xl'
textAlign='center'>
9.7k
</Text>
<Text color={secondaryText} fontWeight='500'>
Followers
</Text>
</Flex>
<Flex flexDirection='column'>
<Text
fontWeight='600'
fontSize='xl'
color={mainText}
textAlign='center'>
274
</Text>
<Text color={secondaryText} fontWeight='500'>
Following
</Text>
</Flex>
</Flex>
</Flex>
);
}

export default Profile;

Enter fullscreen mode Exit fullscreen mode




Chakra UI - 团队卡

Teams Card Chakra UI - Horizo​​n UI



// @src/components/Teams.js

import React from "react";
// Chakra imports
import {
Avatar,
AvatarGroup,
Badge,
Flex,
Button,
Icon,
Image,
Text,
DarkMode,
useColorModeValue,
} from "@chakra-ui/react";
// Assets
import { MdPeople } from "react-icons/md";
import { IoEllipsisHorizontalSharp } from "react-icons/io5";

function Teams() {
let boxBg = useColorModeValue("white !important", "#111c44 !important");
let mainText = useColorModeValue("gray.800", "white");
let iconBox = useColorModeValue("gray.100", "whiteAlpha.200");
let iconColor = useColorModeValue("brand.200", "white");
return (
<Flex
borderRadius='20px'
bg={boxBg}
p='20px'
h='345px'
w={{ base: "315px", md: "345px" }}
alignItems='center'
direction='column'>
<Flex w='100%' mb='18px'>
<Flex
w='38px'
h='38px'
align='center'
justify='center'
borderRadius='50%'
me='12px'
bg={iconBox}>
<Icon w='24px' h='24px' as={MdPeople} color={iconColor} />
</Flex>
<Text
my='auto'
fontWeight='600'
color={mainText}
textAlign='center'
fontSize='xl'
me='auto'>
Teams
</Text>
<Button
w='38px'
h='38px'
align='center'
justify='center'
borderRadius='12px'
me='12px'
bg={iconBox}>
<Icon
w='24px'
h='24px'
as={IoEllipsisHorizontalSharp}
color={iconColor}
/>
</Button>
</Flex>
<Image
src='https://i.ibb.co/KVwmVGW/Teams-Image.png'
maxW='100%'
borderRadius='20px'
mb='10px'
/>
<Text
fontWeight='600'
color={mainText}
textAlign='start'
fontSize='xl'
w='100%'>
Simmmple Web
</Text>
<Flex mt='auto' justify='space-between' w='100%' align='center'>
<DarkMode>
<Badge
borderRadius='9px'
size='md'
colorScheme='green'
color='green.400'
textAlign='center'
display='flex'
justifyContent='center'
alignItems='center'>
Design
</Badge>
</DarkMode>
<AvatarGroup
size='sm'
max={4}
color={iconColor}
fontSize='9px'
fontWeight='700'>
<Avatar src='https://i.ibb.co/CmxNdhQ/avatar1.png' />
<Avatar src='https://i.ibb.co/cFWc59B/avatar2.png' />
<Avatar src='https://i.ibb.co/vLQJVFy/avatar3.png' />
<Avatar src='https://i.ibb.co/8mcrvQk/avatar4.png' />
<Avatar src='https://i.ibb.co/CmxNdhQ/avatar1.png' />
<Avatar src='https://i.ibb.co/cFWc59B/avatar2.png' />
<Avatar src='https://i.ibb.co/vLQJVFy/avatar3.png' />
<Avatar src='https://i.ibb.co/8mcrvQk/avatar4.png' />
</AvatarGroup>
</Flex>
</Flex>
);
}

export default Teams;

Enter fullscreen mode Exit fullscreen mode




Chakra UI - 产品卡

产品 Chakra UI 卡 - Horizo​​n UI



// @src/components/Product.js

import React from "react";
// Chakra imports
import {
Avatar,
AvatarGroup,
Box,
Flex,
Button,
Icon,
Image,
Text,
useColorModeValue,
} from "@chakra-ui/react";
// Assets
import { MdTimer, MdVideoLibrary } from "react-icons/md";
import { IoEllipsisHorizontalSharp } from "react-icons/io5";

function Product() {
let boxBg = useColorModeValue("white !important", "#111c44 !important");
let secondaryBg = useColorModeValue("gray.50", "whiteAlpha.100");
let mainText = useColorModeValue("gray.800", "white");
let iconBox = useColorModeValue("gray.100", "whiteAlpha.200");
let iconColor = useColorModeValue("brand.200", "white");
return (
<Flex
borderRadius='20px'
bg={boxBg}
h='345px'
w={{ base: "315px", md: "345px" }}
direction='column'>
<Box p='20px'>
<Flex w='100%' mb='10px'>
<Image src='https://i.ibb.co/ZWxRPRq/Venus-Logo.png' me='auto' />
<Button
w='38px'
h='38px'
align='center'
justify='center'
borderRadius='12px'
me='12px'
bg={iconBox}>
<Icon
w='24px'
h='24px'
as={IoEllipsisHorizontalSharp}
color={iconColor}
/>
</Button>
</Flex>
<Box>
<Text fontWeight='600' color={mainText} w='100%' fontSize='2xl'>
Venus Product
</Text>
<AvatarGroup
size='sm'
max={4}
color={iconColor}
fontSize='9px'
fontWeight='700'>
<Avatar src='https://i.ibb.co/CmxNdhQ/avatar1.png' />
<Avatar src='https://i.ibb.co/cFWc59B/avatar2.png' />
<Avatar src='https://i.ibb.co/vLQJVFy/avatar3.png' />
<Avatar src='https://i.ibb.co/8mcrvQk/avatar4.png' />
<Avatar src='https://i.ibb.co/CmxNdhQ/avatar1.png' />
<Avatar src='https://i.ibb.co/cFWc59B/avatar2.png' />
<Avatar src='https://i.ibb.co/vLQJVFy/avatar3.png' />
<Avatar src='https://i.ibb.co/8mcrvQk/avatar4.png' />
</AvatarGroup>
</Box>
</Box>
<Flex
bg={secondaryBg}
w='100%'
p='20px'
borderBottomLeftRadius='inherit'
borderBottomRightRadius='inherit'
height='100%'
direction='column'>
<Text
fontSize='sm'
color='gray.500'
lineHeight='24px'
pe='40px'
fontWeight='500'
mb='auto'>
You have the opportunity to play this game of life you need to
appreciate every moment.
</Text>
<Flex>
<Flex me='25px'>
<Icon as={MdTimer} w='20px' h='20px' me='6px' color='green.400' />
<Text color={mainText} fontSize='sm' my='auto' fontWeight='500'>
85 mins
</Text>
</Flex>
<Flex>
<Icon
as={MdVideoLibrary}
w='20px'
h='20px'
me='6px'
color='red.500'
/>
<Text color={mainText} fontSize='sm' my='auto' fontWeight='500'>
Video Format
</Text>
</Flex>
</Flex>
</Flex>
</Flex>
);
}

export default Product;

Enter fullscreen mode Exit fullscreen mode




恭喜!🎉

Chakra UI 现代卡片和组件

太棒了!现在,我们将在App.js中导入之前创建的卡片组件!导入代码如下:



// Components Import
import Product from "./components/Product";
import Profile from "./components/Profile";
import Teams from "./components/Teams";

Enter fullscreen mode Exit fullscreen mode




结论和资源⭐️

在本文中,我们成功使用 Chakra UI 构建了完整且完全响应式的卡片。希望本文对您有所帮助,也希望您觉得本文有趣!

在这里您可以找到包含上述卡片的今天项目的 .zip 文件!

另外,我强烈推荐你看看并尝试一下Horizo​​n UI,你会发现更多像本文中提到的精彩卡片、现代图表以及许多其他令人惊叹的 UI 元素。它们都包含在一个功能完善、响应式、适用于所有设备的管理面板中!而且它还是免费开源的! ⚡️

感谢阅读!

Horizo​​n UI - 最时尚的免费 Chakra UI 管理模板

文章来源:https://dev.to/fredy/how-to-create-modern-cards-in-chakra-ui-react-js-j1b
PREV
我在 Github 的一个代码库上获得了 1200+⭐️ 的星!以下是一些对我有帮助的简单技巧!
NEXT
寻找远程编程工作的热门网站