作ったcomponentは以下。
イメージがトップに置かれていて、その下にlast updated dateがあり、その下にカードのタイトルとカードに関する記述。そして、一番下にリンクを2つ。
もともとは自分のポートフォリオサイトにあるプロジェクト用にカードのコンポーネントを試していたので、リンクを2つ設置しています。
あとは必要ないけれど、tilt animationをreact-parallax-tilt
というライブラリで加えています。
フォルダ構成はシンプルにcomponents/Card/index.tsx
を作って、style-componentsは別ファイルにして、importして使っています。
propsとしてカードのtitle, date, imageをCard componentに渡すようにしました。
Card/index.tsx
import { CardType } from "../../Types";
import {
CardWrapper,
CardImage,
CardTextWrapper,
CardTextDate,
CardTextTitle,
CardTextBody,
CardStatWrapper,
CardStats,
LinkText
} from "./CardStyles";
import Tilt from "react-parallax-tilt";
export const Card = ({ title, date, imgUrl }: CardType) => {
return (
<Tilt>
<CardWrapper>
<CardImage background={imgUrl} />
<CardTextWrapper>
<CardTextDate>{date} days ago</CardTextDate>
<CardTextTitle>{title}</CardTextTitle>
<CardTextBody>
Lorem ipsum dolor sit amet consectetur, Ducimus, repudiandae
temporibus omnis illum maxime quod deserunt eligendi dolor
</CardTextBody>
</CardTextWrapper>
<CardStatWrapper>
{/* <CardStats>
<div>
1<sup>m</sup>
</div>
<div>read</div>
</CardStats> */}
<CardStats>
<LinkText href="#">website</LinkText>
</CardStats>
<CardStats>
<LinkText href="#">github</LinkText>
</CardStats>
</CardStatWrapper>
</CardWrapper>
</Tilt>
);
};
Card/CardStyles.ts
import styled from "styled-components";
export const CardWrapper = styled.div`
display: grid;
grid-template-columns: 300px;
grid-template-rows: 210px 210px 80px;
grid-template-areas: "image" "text" "stats";
border-radius: 18px;
background: #000;
box-shadow: 5px 5px 15px rgba(0, 0, 0, 0.9);
text-align: center;
`;
export const CardImage = styled.div<{ background: string }>`
grid-area: image;
background-image: url(${({ background }) => background});
border-top-left-radius: 15px;
border-top-right-radius: 15px;
background-size: cover;
`;
export const CardTextWrapper = styled.div`
grid-area: text;
margin: 25px;
`;
export const CardTextDate = styled.span`
color: rgb(255, 7, 110);
font-size: 13px;
`;
export const CardTextTitle = styled.h2`
margin-top: 0px;
font-size: 2rem;
box-sizing: border-box;
min-width: 0px;
line-height: 1.2;
margin: 0px;
background: linear-gradient(
110.78deg,
rgb(118, 230, 80) -1.13%,
rgb(249, 214, 73) 15.22%,
rgb(240, 142, 53) 32.09%,
rgb(236, 81, 87) 48.96%,
rgb(255, 24, 189) 67.94%,
rgb(26, 75, 255) 85.34%,
rgb(98, 216, 249) 99.57%
);
background-clip: text;
-webkit-background-clip: text;
color: transparent;
`;
export const CardTextBody = styled.p`
color: grey;
font-size: 15px;
font-weight: 300;
`;
export const CardStatWrapper = styled.div`
grid-area: stats;
display: grid;
/* grid-template-columns: 1fr 1fr 1fr; */
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr;
border-bottom-left-radius: 15px;
border-bottom-right-radius: 15px;
background: #5930e5;
`;
export const CardStats = styled.div`
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
color: white;
padding: 10px;
`;
export const LinkText = styled.a`
color: #fff;
text-decoration: none;
`;
codesandbox