React Tailwind Blog Card Component

Marketing evolves over time. If your business is online, you need some form of marketing.

Blogging is considered a key part of this strategy.

Despite recent updates from Google and advancements in language model software, blogging remains one of the best sources of marketing.

Today, I will share a responsive blog card component UI with 2 variants built with React and Tailwind CSS. To use these UI components in your project, all you need to do is copy and paste.

Blog Section UI | Vertrical Card

This is what our blog card section looks like:

Blog Card Sectio UI

Blog Card Component Code | Variant 1

If you are only interested in the blog card component, you can use the code below.

import { FC } from 'react' interface BlogPost { title: string shortDescription: string cover: string slug: string publishDate: string estimatedTimeToRead: string } interface BlogCardProps { post: BlogPost } const BlogCard: FC<BlogCardProps> = ({ post }) => { const { title, shortDescription, cover, slug, publishDate, estimatedTimeToRead, } = post return ( <div key={slug} className="flex transform flex-col gap-3 rounded-lg border bg-[#F4F4F5] p-3 transition-transform hover:scale-105" > <figure className="relative h-40 w-full overflow-hidden bg-gray-200"> <img className="absolute inset-0 h-full w-full rounded-md object-cover" src={cover} alt="demo" /> </figure> <a href={`/${slug}`}> <h3 className="mb-2 text-xl font-bold text-gray-600 transition-colors duration-200 hover:text-blue-600"> {title} </h3> <p className="text-gray-700">{shortDescription}</p> <p className="mt-4 text-sm font-semibold text-gray-600"> {formatDate(publishDate)} | {estimatedTimeToRead} </p> </a> </div> ) } export default BlogCard

Horizontal Blog Card Section | Variant 2

To make our landing/home page look elegant, I built another variant of blog component that is a bit different than the first one / Vertical card.

In this Blog Card component, we show images horizontally with card data. We are also scaling the blog card image on hover.

Horizontal Blog Card UI

This is the desktop view of Horizontal Blog Card.

Horizontal Blog Card UI

Horizontal Blog Card Code | Variant 2

Types and props are exactly same as previous blog card component, only the UI is different.

import { FC } from 'react' import { formatDate } from '../utils' interface BlogPost { title: string shortDescription: string cover: string slug: string publishDate: string estimatedTimeToRead: string } interface BlogCardProps { post: BlogPost } const BlogCard: FC<BlogCardProps> = ({ post }) => { const { title, shortDescription, cover, slug, publishDate, estimatedTimeToRead, } = post return ( <div key={slug} className="flex flex-col gap-3 rounded-lg border bg-[#F4F4F5] p-3 lg:flex-row" > <figure className="relative mt-1 h-24 min-w-40 overflow-hidden bg-gray-200"> <img className="absolute inset-0 h-full w-full rounded-md object-cover transition-transform duration-300 hover:scale-125" src={cover} alt="demo" /> </figure> <a href={`/${slug}`}> <h3 className="mb-2 text-xl font-bold text-gray-600 transition-colors duration-200 hover:text-blue-600"> {title} </h3> <p className="text-gray-700">{shortDescription}</p> <p className="mt-4 text-sm font-semibold text-gray-600"> {formatDate(publishDate)} | {estimatedTimeToRead} </p> </a> </div> ) } export default BlogCard

To format the date in the desired format, I have built a utility function formatDate. That convert '2024-07-14' into 14th July 2024. Use it if you need it.

function formatDate(dateString: string): string { const date = new Date(dateString) const day = date.getDate() const month = date.toLocaleString('default', { month: 'long' }) const year = date.getFullYear() const daySuffix = getDaySuffix(day) return `${day}${daySuffix} ${month} ${year}` } function getDaySuffix(day: number): string { if (day > 3 && day < 21) return 'th' switch (day % 10) { case 1: return 'st' case 2: return 'nd' case 3: return 'rd' default: return 'th' } }

Best Practices for a Blog App

Typically, we don't have just one blog card in our app. We usually have a section that displays multiple blogs.

To render multiple blogs, I've built a BlogList component that renders a list of BlogCard components to make it easier to use throughout our app.

Blog Section Component

The BlogList || BlogSection component is built using TypeScript and accepts two props

  1. prop: posts, which is an array of blogs.
  2. type, that is either horizontal or vertical

In return, we render blog card components on the basis of the provided type.

import { FC } from 'react' import VerticalBlogCard from './VerticalBlogCard' import HorizontalBlogCard from './HorizontalBlogCard' interface BlogPost { title: string shortDescription: string cover: string slug: string publishDate: string estimatedTimeToRead: string } interface BlogListProps { posts: BlogPost[] type?: 'vertical' | 'horizontal' } const BlogList: FC<BlogListProps> = ({ posts, type = 'vertical' }) => { const isVertical = type === 'vertical' if (isVertical) { return ( <div className="grid gap-6 sm:grid-cols-2 md:grid-cols-3"> {posts.map((post) => ( <VerticalBlogCard key={post.slug} post={post} /> ))} </div> ) } else { return ( <div className="grid gap-6 sm:grid-cols-2"> {posts.map((post) => ( <HorizontalBlogCard key={post.slug} post={post} /> ))} </div> ) } } export default BlogList

How to Use It

Here's how we can use the BlogSection component by passing an array of posts, and type of blog card variants.

import BlogList from './components/BlogList' const posts = [ { title: 'React Tailwind Newsletter Component', shortDescription: 'Learn how to build a responsive newsletter component using React and Tailwind CSS.', cover: 'https://plus.unsplash.com/premium_photo-1673984261110-d1d931e062c0?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D', slug: 'react-tailwind-newsletter-component', publishDate: '2024-07-14', estimatedTimeToRead: '5 min read', }, { title: 'Advanced JavaScript Concepts', shortDescription: 'Deep dive into closures, prototypes, and asynchronous programming in JavaScript.', cover: 'https://images.unsplash.com/photo-1493612276216-ee3925520721?q=80&w=1964&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D', slug: 'advanced-javascript-concepts', publishDate: '2024-05-25', estimatedTimeToRead: '10 min read', }, { title: 'Introduction to TypeScript', shortDescription: 'An introductory guide to TypeScript, covering the basics and helping you get started with typed JavaScript.', cover: 'https://plus.unsplash.com/premium_photo-1663100722417-6e36673fe0ed?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D', slug: 'introduction-to-typescript', publishDate: '2024-02-10', estimatedTimeToRead: '7 min read', }, { title: 'Building a REST API with Node.js', shortDescription: 'Step-by-step guide to creating a RESTful API using Node.js and Express.', cover: 'https://images.unsplash.com/photo-1560732488-6b0df240254a?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D', slug: 'building-a-rest-api-with-node-js', publishDate: '2024-04-15', estimatedTimeToRead: '12 min read', }, { title: 'CSS Grid Layout: A Complete Guide', shortDescription: 'Master CSS Grid Layout with this comprehensive guide covering all the essentials and advanced techniques.', cover: 'https://images.unsplash.com/photo-1501594907352-04cda38ebc29?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D', slug: 'css-grid-layout-complete-guide', publishDate: '2024-03-20', estimatedTimeToRead: '15 min read', }, { title: 'Getting Started with Next.js', shortDescription: 'A beginner’s guide to building server-rendered React applications with Next.js.', cover: 'https://plus.unsplash.com/premium_photo-1680404114169-e254afa55a16?q=80&w=1964&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D', slug: 'getting-started-with-next-js', publishDate: '2024-06-10', estimatedTimeToRead: '8 min read', }, ] function App() { return ( <> <Navbar /> <Header title={title} description={description} /> <div className="mx-auto max-w-6xl px-3"> <CategoryList categories={categories} /> <SectionHeading title="Popular Articles" subtitle="Diverse Range of articles related to html css and javascript" /> <BlogList posts={posts} /> <SectionHeading title="Latest Articles" subtitle="Diverse Range of articles related to html css and javascript" /> <BlogList posts={posts} type="horizontal" /> <Faq items={Faqs} /> <Newsletter /> </div> <Footer /> </> ) } export default App

You can also find the React Tailwind Section Heading Component, which you have seen in the UI and code above.

Feel free to find me on LinkedIn if you have any component requests or suggestions.


Flexy UI Newsletter

Build better and faster UIs.Get the latest components and hooks directly in your inbox. No spam!