Getting Started with TailwindCSS: A Complete Guide
Learn how to set up and use TailwindCSS in your projects. This comprehensive guide covers installation, configuration, and best practices.
Beautiful, responsive blog components built with TailwindCSS. Perfect for blog layouts, post cards, and content sections. Copy, paste, and customize for React, Vue, or HTML.
Clean and simple blog post card with image, title, excerpt, and metadata.
Learn how to set up and use TailwindCSS in your projects. This comprehensive guide covers installation, configuration, and best practices.
<article class="max-w-md mx-auto bg-white border border-gray-200 rounded-lg shadow-sm hover:shadow-lg transition-shadow group">
<div class="aspect-[16/10] bg-gray-200 rounded-t-lg overflow-hidden">
<img src="https://images.unsplash.com/photo-1499750310107-5fef28a66643?w=400&h=250&fit=crop" alt="Blog post" class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300">
</div>
<div class="p-6">
<div class="flex items-center gap-3 mb-3">
<span class="text-xs text-violet font-semibold uppercase tracking-wide">Technology</span>
<span class="text-xs text-gray-500">•</span>
<span class="text-xs text-gray-500">5 min read</span>
</div>
<h3 class="text-lg font-bold mb-2 group-hover:text-violet transition-colors line-clamp-2">
Getting Started with TailwindCSS: A Complete Guide
</h3>
<p class="text-gray-600 text-sm mb-4 leading-relaxed line-clamp-3">
Learn how to set up and use TailwindCSS in your projects. This comprehensive guide covers installation, configuration, and best practices.
</p>
<div class="flex items-center justify-between text-sm text-gray-500">
<div class="flex items-center gap-2">
<div class="w-6 h-6 bg-gray-300 rounded-full flex items-center justify-center text-xs font-bold">
J
</div>
<span>John Doe</span>
</div>
<span>Dec 15, 2024</span>
</div>
</div>
</article>
<template>
<article class="max-w-md mx-auto bg-white border border-gray-200 rounded-lg shadow-sm hover:shadow-lg transition-shadow group">
<div class="aspect-[16/10] bg-gray-200 rounded-t-lg overflow-hidden">
<img :src="post.image" :alt="post.title" class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300">
</div>
<div class="p-6">
<div class="flex items-center gap-3 mb-3">
<span class="text-xs text-violet font-semibold uppercase tracking-wide">{{ post.category }}</span>
<span class="text-xs text-gray-500">•</span>
<span class="text-xs text-gray-500">{{ post.readTime }} min read</span>
</div>
<h3 class="text-lg font-bold mb-2 group-hover:text-violet transition-colors line-clamp-2">
{{ post.title }}
</h3>
<p class="text-gray-600 text-sm mb-4 leading-relaxed line-clamp-3">
{{ post.excerpt }}
</p>
<div class="flex items-center justify-between text-sm text-gray-500">
<div class="flex items-center gap-2">
<div class="w-6 h-6 bg-gray-300 rounded-full flex items-center justify-center text-xs font-bold">
{{ post.author.charAt(0).toUpperCase() }}
</div>
<span>{{ post.author }}</span>
</div>
<span>{{ formatDate(post.date) }}</span>
</div>
</div>
</article>
</template>
<script setup>
const props = defineProps({
post: {
type: Object,
required: true
}
})
const formatDate = (date) => {
return new Date(date).toLocaleDateString('en-US', {
year: 'numeric',
month: 'short',
day: 'numeric'
})
}
</script>
import React from 'react'
const MinimalBlogCard = ({ post }) => {
const formatDate = (date) => {
return new Date(date).toLocaleDateString('en-US', {
year: 'numeric',
month: 'short',
day: 'numeric'
})
}
return (
<article className="max-w-md mx-auto bg-white border border-gray-200 rounded-lg shadow-sm hover:shadow-lg transition-shadow group">
<div className="aspect-[16/10] bg-gray-200 rounded-t-lg overflow-hidden">
<img
src={post.image}
alt={post.title}
className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300"
/>
</div>
<div className="p-6">
<div className="flex items-center gap-3 mb-3">
<span className="text-xs text-violet font-semibold uppercase tracking-wide">
{post.category}
</span>
<span className="text-xs text-gray-500">•</span>
<span className="text-xs text-gray-500">{post.readTime} min read</span>
</div>
<h3 className="text-lg font-bold mb-2 group-hover:text-violet transition-colors line-clamp-2">
{post.title}
</h3>
<p className="text-gray-600 text-sm mb-4 leading-relaxed line-clamp-3">
{post.excerpt}
</p>
<div className="flex items-center justify-between text-sm text-gray-500">
<div className="flex items-center gap-2">
<div className="w-6 h-6 bg-gray-300 rounded-full flex items-center justify-center text-xs font-bold">
{post.author.charAt(0).toUpperCase()}
</div>
<span>{post.author}</span>
</div>
<span>{formatDate(post.date)}</span>
</div>
</div>
</article>
)
}
export default MinimalBlogCard
Sleek card design with glassmorphism effect and modern typography, perfect for blog grids and featured posts.
Explore the latest design trends that are shaping the digital landscape, from AI-powered interfaces to sustainable UX practices.
Sarah Chen
Design Lead
<article class="max-w-sm mx-auto bg-white/70 backdrop-blur-md rounded-3xl shadow-xl hover:shadow-2xl transition-all duration-500 overflow-hidden group border border-white/20">
<div class="relative overflow-hidden">
<img src="https://images.unsplash.com/photo-1486312338219-ce68d2c6f44d?w=400&h=200&fit=crop" alt="Modern blog post" class="w-full h-48 object-cover group-hover:scale-110 transition-transform duration-700">
<div class="absolute inset-0 bg-gradient-to-t from-black/20 to-transparent"></div>
<div class="absolute top-4 left-4">
<div class="inline-flex items-center px-3 py-1 rounded-full text-xs font-semibold bg-white/90 backdrop-blur-sm text-slate-700">
<svg class="w-3 h-3 mr-1.5 text-violet" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
8 min read
</div>
</div>
</div>
<div class="p-6">
<div class="flex items-center gap-2 mb-3">
<span class="px-2 py-1 bg-violet/10 text-violet rounded-lg text-xs font-medium">Design</span>
<span class="text-xs text-slate-400">•</span>
<span class="text-xs text-slate-500">March 15, 2024</span>
</div>
<h3 class="text-lg font-bold mb-3 text-slate-800 leading-tight group-hover:text-violet transition-colors">
The Future of Web Design: Trends to Watch in 2024
</h3>
<p class="text-sm text-slate-600 mb-4 leading-relaxed">
Explore the latest design trends that are shaping the digital landscape, from AI-powered interfaces to sustainable UX practices.
</p>
<div class="flex items-center justify-between">
<div class="flex items-center gap-3">
<div class="relative">
<img src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=32&h=32&fit=crop&crop=face" alt="Author" class="w-8 h-8 rounded-full ring-2 ring-white shadow-sm">
<div class="absolute -bottom-0.5 -right-0.5 w-3 h-3 bg-green-400 border-2 border-white rounded-full"></div>
</div>
<div>
<p class="text-sm font-medium text-slate-700">Sarah Chen</p>
<p class="text-xs text-slate-500">Design Lead</p>
</div>
</div>
<button class="group/btn inline-flex items-center gap-1.5 px-4 py-2 bg-gradient-to-r from-violet to-purple-600 text-white text-sm font-medium rounded-xl hover:from-violet/90 hover:to-purple-600/90 transition-all shadow-lg hover:shadow-xl transform hover:-translate-y-0.5">
Read More
<svg class="w-3 h-3 group-hover/btn:translate-x-0.5 transition-transform" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
</svg>
</button>
</div>
</div>
</article>
<template>
<article class="max-w-sm mx-auto bg-white/70 backdrop-blur-md rounded-3xl shadow-xl hover:shadow-2xl transition-all duration-500 overflow-hidden group border border-white/20">
<div class="relative overflow-hidden">
<img :src="post.image" :alt="post.title" class="w-full h-48 object-cover group-hover:scale-110 transition-transform duration-700">
<div class="absolute inset-0 bg-gradient-to-t from-black/20 to-transparent"></div>
<div class="absolute top-4 left-4">
<div class="inline-flex items-center px-3 py-1 rounded-full text-xs font-semibold bg-white/90 backdrop-blur-sm text-slate-700">
<svg class="w-3 h-3 mr-1.5 text-violet" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
{{ post.readTime }} min read
</div>
</div>
</div>
<div class="p-6">
<div class="flex items-center gap-2 mb-3">
<span class="px-2 py-1 bg-violet/10 text-violet rounded-lg text-xs font-medium">{{ post.category }}</span>
<span class="text-xs text-slate-400">•</span>
<span class="text-xs text-slate-500">{{ formatDate(post.date) }}</span>
</div>
<h3 class="text-lg font-bold mb-3 text-slate-800 leading-tight group-hover:text-violet transition-colors">
{{ post.title }}
</h3>
<p class="text-sm text-slate-600 mb-4 leading-relaxed">
{{ post.excerpt }}
</p>
<div class="flex items-center justify-between">
<div class="flex items-center gap-3">
<div class="relative">
<img :src="post.author.avatar" :alt="post.author.name" class="w-8 h-8 rounded-full ring-2 ring-white shadow-sm">
<div class="absolute -bottom-0.5 -right-0.5 w-3 h-3 bg-green-400 border-2 border-white rounded-full"></div>
</div>
<div>
<p class="text-sm font-medium text-slate-700">{{ post.author.name }}</p>
<p class="text-xs text-slate-500">{{ post.author.role }}</p>
</div>
</div>
<button @click="$emit('readMore', post)" class="group/btn inline-flex items-center gap-1.5 px-4 py-2 bg-gradient-to-r from-violet to-purple-600 text-white text-sm font-medium rounded-xl hover:from-violet/90 hover:to-purple-600/90 transition-all shadow-lg hover:shadow-xl transform hover:-translate-y-0.5">
Read More
<svg class="w-3 h-3 group-hover/btn:translate-x-0.5 transition-transform" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
</svg>
</button>
</div>
</div>
</article>
</template>
<script setup>
const props = defineProps({
post: {
type: Object,
required: true
}
})
defineEmits(['readMore'])
const formatDate = (date) => {
return new Date(date).toLocaleDateString('en-US', {
year: 'numeric',
month: 'short',
day: 'numeric'
})
}
</script>
import React from 'react'
const ModernBlogGridCard = ({ post, onReadMore }) => {
const formatDate = (date) => {
return new Date(date).toLocaleDateString('en-US', {
year: 'numeric',
month: 'short',
day: 'numeric'
})
}
return (
<article className="max-w-sm mx-auto bg-white/70 backdrop-blur-md rounded-3xl shadow-xl hover:shadow-2xl transition-all duration-500 overflow-hidden group border border-white/20">
<div className="relative overflow-hidden">
<img src={post.image} alt={post.title} className="w-full h-48 object-cover group-hover:scale-110 transition-transform duration-700" />
<div className="absolute inset-0 bg-gradient-to-t from-black/20 to-transparent"></div>
<div className="absolute top-4 left-4">
<div className="inline-flex items-center px-3 py-1 rounded-full text-xs font-semibold bg-white/90 backdrop-blur-sm text-slate-700">
<svg className="w-3 h-3 mr-1.5 text-violet" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
{post.readTime} min read
</div>
</div>
</div>
<div className="p-6">
<div className="flex items-center gap-2 mb-3">
<span className="px-2 py-1 bg-violet/10 text-violet rounded-lg text-xs font-medium">{post.category}</span>
<span className="text-xs text-slate-400">•</span>
<span className="text-xs text-slate-500">{formatDate(post.date)}</span>
</div>
<h3 className="text-lg font-bold mb-3 text-slate-800 leading-tight group-hover:text-violet transition-colors">
{post.title}
</h3>
<p className="text-sm text-slate-600 mb-4 leading-relaxed">
{post.excerpt}
</p>
<div className="flex items-center justify-between">
<div className="flex items-center gap-3">
<div className="relative">
<img src={post.author.avatar} alt={post.author.name} className="w-8 h-8 rounded-full ring-2 ring-white shadow-sm" />
<div className="absolute -bottom-0.5 -right-0.5 w-3 h-3 bg-green-400 border-2 border-white rounded-full"></div>
</div>
<div>
<p className="text-sm font-medium text-slate-700">{post.author.name}</p>
<p className="text-xs text-slate-500">{post.author.role}</p>
</div>
</div>
<button
onClick={() => onReadMore && onReadMore(post)}
className="group/btn inline-flex items-center gap-1.5 px-4 py-2 bg-gradient-to-r from-violet to-purple-600 text-white text-sm font-medium rounded-xl hover:from-violet/90 hover:to-purple-600/90 transition-all shadow-lg hover:shadow-xl transform hover:-translate-y-0.5"
>
Read More
<svg className="w-3 h-3 group-hover/btn:translate-x-0.5 transition-transform" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M9 5l7 7-7 7" />
</svg>
</button>
</div>
</div>
</article>
)
}
export default ModernBlogGridCard
Horizontal layout perfect for blog lists and feeds with clean typography and subtle hover effects.
Discover advanced React patterns that will help you build maintainable and scalable applications. Learn about component composition, state management strategies, and performance optimization techniques.
Michael Rodriguez
Senior Frontend Developer
<article class="max-w-4xl mx-auto group">
<div class="flex flex-col sm:flex-row gap-6 p-6 bg-white hover:bg-gray-50 rounded-xl transition-all duration-300 border border-gray-100 hover:border-gray-200 hover:shadow-md">
<div class="sm:w-48 w-full flex-shrink-0">
<div class="aspect-[4/3] rounded-lg overflow-hidden bg-gray-100">
<img src="https://images.unsplash.com/photo-1555066931-4365d14bab8c?w=300&h=200&fit=crop" alt="Blog post thumbnail" class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-500">
</div>
</div>
<div class="flex-1 min-w-0">
<div class="flex items-center gap-3 mb-3">
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800">Development</span>
<span class="text-sm text-gray-500">March 20, 2024</span>
<span class="text-sm text-gray-400">•</span>
<span class="text-sm text-gray-500">12 min read</span>
</div>
<h3 class="text-xl font-semibold text-gray-900 mb-3 group-hover:text-violet transition-colors leading-tight">
Building Scalable React Applications: Advanced Patterns and Best Practices
</h3>
<p class="text-gray-600 mb-4 leading-relaxed">
Discover advanced React patterns that will help you build maintainable and scalable applications. Learn about component composition, state management strategies, and performance optimization techniques.
</p>
<div class="flex items-center justify-between">
<div class="flex items-center gap-3">
<img src="https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=40&h=40&fit=crop&crop=face" alt="Author" class="w-10 h-10 rounded-full">
<div>
<p class="text-sm font-medium text-gray-900">Michael Rodriguez</p>
<p class="text-xs text-gray-500">Senior Frontend Developer</p>
</div>
</div>
<div class="flex items-center gap-4 text-sm text-gray-500">
<button class="flex items-center gap-1 hover:text-gray-700 transition-colors">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"></path>
</svg>
24
</button>
<button class="flex items-center gap-1 hover:text-gray-700 transition-colors">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z"></path>
</svg>
8
</button>
</div>
</div>
</div>
</div>
</article>
<template>
<article class="max-w-4xl mx-auto group">
<div class="flex flex-col sm:flex-row gap-6 p-6 bg-white hover:bg-gray-50 rounded-xl transition-all duration-300 border border-gray-100 hover:border-gray-200 hover:shadow-md">
<div class="sm:w-48 w-full flex-shrink-0">
<div class="aspect-[4/3] rounded-lg overflow-hidden bg-gray-100">
<img :src="post.thumbnail" :alt="post.title" class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-500">
</div>
</div>
<div class="flex-1 min-w-0">
<div class="flex items-center gap-3 mb-3">
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800">{{ post.category }}</span>
<span class="text-sm text-gray-500">{{ formatDate(post.publishedAt) }}</span>
<span class="text-sm text-gray-400">•</span>
<span class="text-sm text-gray-500">{{ post.readTime }} min read</span>
</div>
<h3 class="text-xl font-semibold text-gray-900 mb-3 group-hover:text-violet transition-colors leading-tight">
{{ post.title }}
</h3>
<p class="text-gray-600 mb-4 leading-relaxed">
{{ post.excerpt }}
</p>
<div class="flex items-center justify-between">
<div class="flex items-center gap-3">
<img :src="post.author.avatar" :alt="post.author.name" class="w-10 h-10 rounded-full">
<div>
<p class="text-sm font-medium text-gray-900">{{ post.author.name }}</p>
<p class="text-xs text-gray-500">{{ post.author.role }}</p>
</div>
</div>
<div class="flex items-center gap-4 text-sm text-gray-500">
<button @click="toggleLike" class="flex items-center gap-1 hover:text-gray-700 transition-colors">
<HeartIcon class="w-4 h-4" />
{{ post.likes }}
</button>
<button class="flex items-center gap-1 hover:text-gray-700 transition-colors">
<ChatBubbleLeftIcon class="w-4 h-4" />
{{ post.comments }}
</button>
</div>
</div>
</div>
</div>
</article>
</template>
<script setup>
import { HeartIcon, ChatBubbleLeftIcon } from '@heroicons/vue/24/outline'
const props = defineProps({
post: {
type: Object,
required: true
}
})
const emit = defineEmits(['like'])
const formatDate = (date) => {
return new Date(date).toLocaleDateString('en-US', {
year: 'numeric',
month: 'short',
day: 'numeric'
})
}
const toggleLike = () => {
emit('like', props.post.id)
}
</script>
import React from 'react'
import { HeartIcon, ChatBubbleLeftIcon } from '@heroicons/react/24/outline'
const BlogListItem = ({ post, onLike }) => {
const formatDate = (date) => {
return new Date(date).toLocaleDateString('en-US', {
year: 'numeric',
month: 'short',
day: 'numeric'
})
}
const handleLike = () => {
if (onLike) onLike(post.id)
}
return (
<article className="max-w-4xl mx-auto group">
<div className="flex flex-col sm:flex-row gap-6 p-6 bg-white hover:bg-gray-50 rounded-xl transition-all duration-300 border border-gray-100 hover:border-gray-200 hover:shadow-md">
<div className="sm:w-48 w-full flex-shrink-0">
<div className="aspect-[4/3] rounded-lg overflow-hidden bg-gray-100">
<img src={post.thumbnail} alt={post.title} className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-500" />
</div>
</div>
<div className="flex-1 min-w-0">
<div className="flex items-center gap-3 mb-3">
<span className="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800">{post.category}</span>
<span className="text-sm text-gray-500">{formatDate(post.publishedAt)}</span>
<span className="text-sm text-gray-400">•</span>
<span className="text-sm text-gray-500">{post.readTime} min read</span>
</div>
<h3 className="text-xl font-semibold text-gray-900 mb-3 group-hover:text-violet transition-colors leading-tight">
{post.title}
</h3>
<p className="text-gray-600 mb-4 leading-relaxed">
{post.excerpt}
</p>
<div className="flex items-center justify-between">
<div className="flex items-center gap-3">
<img src={post.author.avatar} alt={post.author.name} className="w-10 h-10 rounded-full" />
<div>
<p className="text-sm font-medium text-gray-900">{post.author.name}</p>
<p className="text-xs text-gray-500">{post.author.role}</p>
</div>
</div>
<div className="flex items-center gap-4 text-sm text-gray-500">
<button onClick={handleLike} className="flex items-center gap-1 hover:text-gray-700 transition-colors">
<HeartIcon className="w-4 h-4" />
{post.likes}
</button>
<button className="flex items-center gap-1 hover:text-gray-700 transition-colors">
<ChatBubbleLeftIcon className="w-4 h-4" />
{post.comments}
</button>
</div>
</div>
</div>
</div>
</article>
)
}
export default BlogListItem
Large hero-style blog post with overlay content and prominent call-to-action button.
Explore the latest JavaScript features that are transforming web development. From async patterns to new syntax improvements, discover what's new in ES2024.
Jennifer Walsh
JavaScript Specialist
<article class="max-w-4xl mx-auto">
<div class="relative rounded-2xl overflow-hidden shadow-2xl group">
<div class="aspect-[2/1] bg-gradient-to-r from-gray-900 to-gray-600">
<img src="https://images.unsplash.com/photo-1519389950473-47ba0277781c?w=800&h=400&fit=crop" alt="Featured blog post" class="w-full h-full object-cover mix-blend-overlay">
</div>
<div class="absolute inset-0 bg-gradient-to-t from-black/80 via-black/40 to-black/20"></div>
<div class="absolute inset-0 p-8 md:p-12 flex flex-col justify-end">
<div class="max-w-3xl">
<div class="flex items-center gap-4 mb-6">
<span class="inline-flex items-center px-3 py-1.5 rounded-full text-sm font-semibold bg-orange-500 text-white">
Featured Article
</span>
<span class="text-white/80 text-sm">April 5, 2024 • 15 min read</span>
</div>
<h2 class="text-3xl md:text-5xl font-bold text-white mb-4 leading-tight">
The Complete Guide to Modern JavaScript: ES2024 Features and Beyond
</h2>
<p class="text-xl text-white/90 mb-8 leading-relaxed">
Explore the latest JavaScript features that are transforming web development. From async patterns to new syntax improvements, discover what's new in ES2024.
</p>
<div class="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-6">
<div class="flex items-center gap-4">
<img src="https://images.unsplash.com/photo-1494790108755-2616b612b786?w=50&h=50&fit=crop&crop=face" alt="Author" class="w-12 h-12 rounded-full border-3 border-white">
<div>
<p class="text-white font-semibold text-lg">Jennifer Walsh</p>
<p class="text-white/70">JavaScript Specialist</p>
</div>
</div>
<button class="inline-flex items-center px-8 py-4 bg-white text-gray-900 font-bold rounded-xl hover:bg-gray-100 transition-all shadow-lg hover:shadow-xl transform hover:-translate-y-1 group-hover:scale-105">
Read Full Article
<svg class="w-5 h-5 ml-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 8l4 4m0 0l-4 4m4-4H3"></path>
</svg>
</button>
</div>
</div>
</div>
</div>
</article>
<template>
<article class="max-w-4xl mx-auto">
<div class="relative rounded-2xl overflow-hidden shadow-2xl group">
<div class="aspect-[2/1] bg-gradient-to-r from-gray-900 to-gray-600">
<img :src="featuredPost.heroImage" :alt="featuredPost.title" class="w-full h-full object-cover mix-blend-overlay">
</div>
<div class="absolute inset-0 bg-gradient-to-t from-black/80 via-black/40 to-black/20"></div>
<div class="absolute inset-0 p-8 md:p-12 flex flex-col justify-end">
<div class="max-w-3xl">
<div class="flex items-center gap-4 mb-6">
<span class="inline-flex items-center px-3 py-1.5 rounded-full text-sm font-semibold bg-orange-500 text-white">
Featured Article
</span>
<span class="text-white/80 text-sm">{{ formatDate(featuredPost.publishedAt) }} • {{ featuredPost.readTime }} min read</span>
</div>
<h2 class="text-3xl md:text-5xl font-bold text-white mb-4 leading-tight">
{{ featuredPost.title }}
</h2>
<p class="text-xl text-white/90 mb-8 leading-relaxed">
{{ featuredPost.excerpt }}
</p>
<div class="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-6">
<div class="flex items-center gap-4">
<img :src="featuredPost.author.avatar" :alt="featuredPost.author.name" class="w-12 h-12 rounded-full border-3 border-white">
<div>
<p class="text-white font-semibold text-lg">{{ featuredPost.author.name }}</p>
<p class="text-white/70">{{ featuredPost.author.role }}</p>
</div>
</div>
<button @click="$emit('readArticle', featuredPost)" class="inline-flex items-center px-8 py-4 bg-white text-gray-900 font-bold rounded-xl hover:bg-gray-100 transition-all shadow-lg hover:shadow-xl transform hover:-translate-y-1 group-hover:scale-105">
Read Full Article
<ArrowRightIcon class="w-5 h-5 ml-2" />
</button>
</div>
</div>
</div>
</div>
</article>
</template>
<script setup>
import { ArrowRightIcon } from '@heroicons/vue/24/outline'
const props = defineProps({
featuredPost: {
type: Object,
required: true
}
})
defineEmits(['readArticle'])
const formatDate = (date) => {
return new Date(date).toLocaleDateString('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric'
})
}
</script>
import React from 'react'
import { ArrowRightIcon } from '@heroicons/react/24/outline'
const FeaturedBlogHero = ({ featuredPost, onReadArticle }) => {
const formatDate = (date) => {
return new Date(date).toLocaleDateString('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric'
})
}
const handleReadClick = () => {
if (onReadArticle) onReadArticle(featuredPost)
}
return (
<article className="max-w-4xl mx-auto">
<div className="relative rounded-2xl overflow-hidden shadow-2xl group">
<div className="aspect-[2/1] bg-gradient-to-r from-gray-900 to-gray-600">
<img src={featuredPost.heroImage} alt={featuredPost.title} className="w-full h-full object-cover mix-blend-overlay" />
</div>
<div className="absolute inset-0 bg-gradient-to-t from-black/80 via-black/40 to-black/20"></div>
<div className="absolute inset-0 p-8 md:p-12 flex flex-col justify-end">
<div className="max-w-3xl">
<div className="flex items-center gap-4 mb-6">
<span className="inline-flex items-center px-3 py-1.5 rounded-full text-sm font-semibold bg-orange-500 text-white">
Featured Article
</span>
<span className="text-white/80 text-sm">{formatDate(featuredPost.publishedAt)} • {featuredPost.readTime} min read</span>
</div>
<h2 className="text-3xl md:text-5xl font-bold text-white mb-4 leading-tight">
{featuredPost.title}
</h2>
<p className="text-xl text-white/90 mb-8 leading-relaxed">
{featuredPost.excerpt}
</p>
<div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-6">
<div className="flex items-center gap-4">
<img src={featuredPost.author.avatar} alt={featuredPost.author.name} className="w-12 h-12 rounded-full border-3 border-white" />
<div>
<p className="text-white font-semibold text-lg">{featuredPost.author.name}</p>
<p className="text-white/70">{featuredPost.author.role}</p>
</div>
</div>
<button onClick={handleReadClick} className="inline-flex items-center px-8 py-4 bg-white text-gray-900 font-bold rounded-xl hover:bg-gray-100 transition-all shadow-lg hover:shadow-xl transform hover:-translate-y-1 group-hover:scale-105">
Read Full Article
<ArrowRightIcon className="w-5 h-5 ml-2" />
</button>
</div>
</div>
</div>
</div>
</article>
)
}
export default FeaturedBlogHero
Compact summary card with key metrics, reading progress, and social engagement features.
Published
2 days ago
Master CSS Grid with practical examples and advanced techniques that will transform your layout skills.
<article class="max-w-lg mx-auto">
<div class="bg-gradient-to-br from-white to-gray-50 rounded-2xl p-6 shadow-lg hover:shadow-xl transition-all duration-500 border border-gray-100 group">
<div class="flex items-start justify-between mb-4">
<div class="flex items-center gap-3">
<div class="w-12 h-12 rounded-xl bg-gradient-to-br from-violet to-purple-600 flex items-center justify-center shadow-lg">
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 20H5a2 2 0 01-2-2V6a2 2 0 012-2h10a2 2 0 012 2v1m2 13a2 2 0 01-2-2V7m2 13a2 2 0 002-2V9a2 2 0 00-2-2h-2m-4-3H9M7 16h6M7 8h6v4H7V8z"></path>
</svg>
</div>
<div>
<p class="text-sm text-gray-500">Published</p>
<p class="text-sm font-semibold text-gray-900">2 days ago</p>
</div>
</div>
<div class="flex items-center gap-2">
<span class="px-2 py-1 bg-green-100 text-green-800 text-xs font-medium rounded-full">Tutorial</span>
<button class="p-2 hover:bg-gray-100 rounded-full transition-colors">
<svg class="w-4 h-4 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 5a2 2 0 012-2h10a2 2 0 012 2v16l-7-3.5L5 21V5z"></path>
</svg>
</button>
</div>
</div>
<h3 class="text-lg font-bold text-gray-900 mb-3 leading-tight group-hover:text-violet transition-colors">
Advanced CSS Grid Techniques for Modern Layouts
</h3>
<p class="text-gray-600 text-sm mb-4 leading-relaxed">
Master CSS Grid with practical examples and advanced techniques that will transform your layout skills.
</p>
<!-- Reading Progress -->
<div class="mb-4">
<div class="flex items-center justify-between text-xs text-gray-500 mb-2">
<span>Reading Progress</span>
<span>6 min read</span>
</div>
<div class="w-full bg-gray-200 rounded-full h-1.5">
<div class="bg-violet h-1.5 rounded-full transition-all duration-500" style="width: 35%"></div>
</div>
</div>
<!-- Stats -->
<div class="flex items-center justify-between py-4 border-t border-gray-100">
<div class="flex items-center gap-4">
<div class="flex items-center gap-1 text-sm text-gray-500">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"></path>
</svg>
1.2k
</div>
<div class="flex items-center gap-1 text-sm text-gray-500">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"></path>
</svg>
89
</div>
<div class="flex items-center gap-1 text-sm text-gray-500">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z"></path>
</svg>
12
</div>
</div>
<button class="px-4 py-2 bg-violet text-white text-sm font-medium rounded-lg hover:bg-violet/90 transition-colors">
Continue Reading
</button>
</div>
</div>
</article>
<template>
<article class="max-w-lg mx-auto">
<div class="bg-gradient-to-br from-white to-gray-50 rounded-2xl p-6 shadow-lg hover:shadow-xl transition-all duration-500 border border-gray-100 group">
<div class="flex items-start justify-between mb-4">
<div class="flex items-center gap-3">
<div class="w-12 h-12 rounded-xl bg-gradient-to-br from-violet to-purple-600 flex items-center justify-center shadow-lg">
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 20H5a2 2 0 01-2-2V6a2 2 0 012-2h10a2 2 0 012 2v1m2 13a2 2 0 01-2-2V7m2 13a2 2 0 002-2V9a2 2 0 00-2-2h-2m-4-3H9M7 16h6M7 8h6v4H7V8z"></path>
</svg>
</div>
<div>
<p class="text-sm text-gray-500">Published</p>
<p class="text-sm font-semibold text-gray-900">{{ post.publishedAgo }}</p>
</div>
</div>
<div class="flex items-center gap-2">
<span class="px-2 py-1 bg-green-100 text-green-800 text-xs font-medium rounded-full">{{ post.tag }}</span>
<button class="p-2 hover:bg-gray-100 rounded-full transition-colors">
<svg class="w-4 h-4 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 5a2 2 0 012-2h10a2 2 0 012 2v16l-7-3.5L5 21V5z"></path>
</svg>
</button>
</div>
</div>
<h3 class="text-lg font-bold text-gray-900 mb-3 leading-tight group-hover:text-violet transition-colors">
{{ post.title }}
</h3>
<p class="text-gray-600 text-sm mb-4 leading-relaxed">
{{ post.excerpt }}
</p>
<!-- Reading Progress -->
<div class="mb-4">
<div class="flex items-center justify-between text-xs text-gray-500 mb-2">
<span>Reading Progress</span>
<span>{{ post.readTime }} min read</span>
</div>
<div class="w-full bg-gray-200 rounded-full h-1.5">
<div class="bg-violet h-1.5 rounded-full transition-all duration-500" :style="{ width: post.progress + '%' }"></div>
</div>
</div>
<!-- Stats -->
<div class="flex items-center justify-between py-4 border-t border-gray-100">
<div class="flex items-center gap-4">
<div class="flex items-center gap-1 text-sm text-gray-500">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"></path>
</svg>
{{ post.views }}
</div>
<div class="flex items-center gap-1 text-sm text-gray-500">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"></path>
</svg>
{{ post.likes }}
</div>
<div class="flex items-center gap-1 text-sm text-gray-500">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z"></path>
</svg>
{{ post.comments }}
</div>
</div>
<button class="px-4 py-2 bg-violet text-white text-sm font-medium rounded-lg hover:bg-violet/90 transition-colors">
Continue Reading
</button>
</div>
</div>
</article>
</template>
<script setup>
const props = defineProps({
post: {
type: Object,
required: true
}
})
</script>
import React from 'react'
import { HeartIcon, ChatBubbleLeftIcon } from '@heroicons/react/24/outline'
const BlogPostSummary = ({ post, onContinue }) => {
const formatDate = (date) => {
return new Date(date).toLocaleDateString('en-US', {
year: 'numeric',
month: 'short',
day: 'numeric'
})
}
return (
<article className="max-w-lg mx-auto">
<div className="bg-gradient-to-br from-white to-gray-50 rounded-2xl p-6 shadow-lg hover:shadow-xl transition-all duration-500 border border-gray-100 group">
<div className="flex items-start justify-between mb-4">
<div className="flex items-center gap-3">
<div className="w-12 h-12 rounded-xl bg-gradient-to-br from-violet to-purple-600 flex items-center justify-center shadow-lg">
<svg className="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M19 20H5a2 2 0 01-2-2V6a2 2 0 012-2h10a2 2 0 012 2v1m2 13a2 2 0 01-2-2V7m2 13a2 2 0 002-2V9a2 2 0 00-2-2h-2m-4-3H9M7 16h6M7 8h6v4H7V8z" />
</svg>
</div>
<div>
<p className="text-sm text-gray-500">Published</p>
<p className="text-sm font-semibold text-gray-900">{post.publishedAgo}</p>
</div>
</div>
<div className="flex items-center gap-2">
<span className="px-2 py-1 bg-green-100 text-green-800 text-xs font-medium rounded-full">{post.tag}</span>
<button className="p-2 hover:bg-gray-100 rounded-full transition-colors">
<svg className="w-4 h-4 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M5 5a2 2 0 012-2h10a2 2 0 012 2v16l-7-3.5L5 21V5z" />
</svg>
</button>
</div>
</div>
<h3 className="text-lg font-bold text-gray-900 mb-3 leading-tight group-hover:text-violet transition-colors">
{post.title}
</h3>
<p className="text-gray-600 text-sm mb-4 leading-relaxed">
{post.excerpt}
</p>
<!-- Reading Progress -->
<div className="mb-4">
<div className="flex items-center justify-between text-xs text-gray-500 mb-2">
<span>Reading Progress</span>
<span>{post.readTime} min read</span>
</div>
<div className="w-full bg-gray-200 rounded-full h-1.5">
<div className="bg-violet h-1.5 rounded-full transition-all duration-500" style={{ width: post.progress + '%' }}></div>
</div>
</div>
<!-- Stats -->
<div className="flex items-center justify-between py-4 border-t border-gray-100">
<div className="flex items-center gap-4">
<div className="flex items-center gap-1 text-sm text-gray-500">
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z" />
</svg>
{post.views}
</div>
<div className="flex items-center gap-1 text-sm text-gray-500">
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z" />
</svg>
{post.likes}
</div>
<div className="flex items-center gap-1 text-sm text-gray-500">
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z" />
</svg>
{post.comments}
</div>
</div>
<button onClick={() => onContinue && onContinue(post)} className="px-4 py-2 bg-violet text-white text-sm font-medium rounded-lg hover:bg-violet/90 transition-colors">
Continue Reading
</button>
</div>
</div>
</article>
)
}
export default BlogPostSummary
Pro Tip: Use the minimal blog card for listing posts and the featured hero for highlighting your best content. Both components are optimized for readability and engagement.
We use cookies to improve your experience and analytics. You can accept all cookies or reject non-essential ones.