Tailwind CSS Font Weight
Font weight in CSS defines the thickness or boldness of typography within your application. This property allows you to distinguish text hierarchies, focus attention, and maintain consistency across your design system.
In this guide, we will explore Tailwind CSS font weight utilities, how to apply them conditionally, and the process for creating custom weights—enabling you to craft text that aligns with your application's design:
Class | Properties | Example |
---|---|---|
font-thin | font-weight: 100; | <div className="font-thin"></div> |
font-extralight | font-weight: 200; | <div className="font-extralight"></div> |
font-light | font-weight: 300; | <div className="font-light"></div> |
font-normal | font-weight: 400; | <div className="font-normal"></div> |
font-medium | font-weight: 500; | <div className="font-medium"></div> |
font-semibold | font-weight: 600; | <div className="font-semibold"></div> |
font-bold | font-weight: 700; | <div className="font-bold"></div> |
font-extrabold | font-weight: 800; | <div className="font-extrabold"></div> |
font-black | font-weight: 900; | <div className="font-black"></div> |
Overview of Font Weight
When working with font weights in Tailwind CSS, you tap into a collection of utilities that represent predefined CSS font-weight values. These values range from thin (lighter) to extrabold or black (heaviest). This section focuses on applying standard font weight utilities to text.
Adding Font Weight
To set the font weight of a particular text element, simply add the corresponding utility class to your element.
The utility classes font-light
, font-semibold
, and font-extrabold
are applied in the below example. Tailwind automatically maps these utilities to CSS's font-weight values without additional configuration.
// Filename: App.jsx export default function App() { return ( <div className="h-screen w-screen flex flex-col gap-6 justify-center bg-blue-50"> <p className="font-light text-gray-800 text-lg text-center"> This is a light font. </p> <p className="font-normal text-gray-800 text-lg text-center"> This is a normal font. </p> <p className="font-extrabold text-gray-800 text-lg text-center"> This is a extrabold font. </p> </div> ); }
States and Responsiveness
Hover and Focus States
State-dependent utilities such as hover, focus, and active enable you to modify typography appearance dynamically. Each state is declared with a colon prefix.
In this example, the text transitions from font-light
(300
) to font-extrabold
(800
) when the user hovers over it.
// Filename: App.jsx export default function App() { return ( <div className="h-screen w-screen flex justify-center items-center bg-gray-100"> <p className="font-light hover:font-extrabold text-center text-lg px-10"> Hover over me to adjust my font weight to extra bold! </p> </div> ); } // CSS Applied by Tailwind: // font-light --> font-weight: 300; // hover:font-extrabold --> Hover state font-weight: 800;
Breakpoint Modifiers
Media query breakpoints in Tailwind make font-weight modifications highly adaptable for responsive designs. You can specify distinct font-weight utilities for each screen size to satisfy complex layout requirements.
On smaller screens, the text weight starts as medium (500) but progresses to bold (700) for devices with larger resolutions.
// Filename: App.jsx export default function App() { return ( <div className="h-screen w-screen bg-teal-50 flex justify-center items-center"> <p className="text-lg sm:font-medium lg:font-semibold xl:font-bold text-teal-800 text-center px-10"> Font weights adapt as screen sizes change. </p> </div> ); } // CSS Applied by Tailwind: // sm:font-medium --> Medium font-weight (500) on sm (640px) breakpoint; // lg:font-semibold --> Semibold font-weight (600) on lg (1024px) breakpoint; // xl:font-bold --> Bold font-weight (700) on xl (1280px) breakpoint.
Custom Font Weight
While the default font-weight values in Tailwind encompass most design needs, you might occasionally encounter requirements for custom typography rules. Tailwind lets you extend its configuration effortlessly.
Extending the Theme
To create custom font weights, modify the theme configuration in your tailwind.config.js
file. By extending the fontWeight
key, you define unique weights and reuse them across your project.
New utilities—font-hairline
and font-ultraheavy
—are now part of your Tailwind project and can be applied like this:
import tailwindConfig from "./tailwind.config.js"; tailwind.config = tailwindConfig; // Filename: App.jsx export default function App() { return ( <div className="h-screen w-screen bg-white flex flex-col justify-center items-center"> <p className="font-hairline text-sm text-gray-600"> Hairline Text Weight (100) </p> <p className="font-ultraheavy text-lg text-black"> Ultraheavy Text Weight (950) </p> </div> ); } // CSS Applied by Tailwind // font-hairline --> font-weight: 100; // font-ultraheavy --> font-weight: 950;
Using Arbitrary Values
Sometimes, you may want to apply font-weight values without defining explicit utilities. Tailwind supports arbitrary value classes, which can be directly embedded within elements for instant styling.
// Filename: App.jsx export default function App() { return ( <div className="h-screen w-screen flex justify-center items-center"> <p className="font-[850] text-lg text-center px-10 "> Arbitrary font weight is 850 here. </p> </div> ); } // CSS Applied Automatically: // font-[850] --> font-weight: 850;
Real World Examples
Product Review Ratings Component with Variable Font Weights
This component displays user reviews with different font weights to emphasize ratings and review content.
export default function ProductReviews() { const reviews = [ { id: 1, rating: 5, title: "Excellent Product!", review: "The best purchase I've made this year. Absolutely worth every penny.", author: "John Smith", date: "2023-10-15", avatar: "https://images.unsplash.com/photo-1472099645785-5658abf4ff4e" }, { id: 2, rating: 4, title: "Good but could be better", review: "Really satisfied with the quality, minor improvements needed.", author: "Emma Wilson", date: "2023-10-14", avatar: "https://images.unsplash.com/photo-1438761681033-6461ffad8d80" }, { id: 3, rating: 5, title: "Outstanding Service", review: "Quick delivery and excellent customer support!", author: "Michael Brown", date: "2023-10-13", avatar: "https://images.unsplash.com/photo-1500648767791-00dcc994a43e" }, { id: 4, rating: 3, title: "Decent Product", review: "Met my basic expectations but nothing extraordinary.", author: "Sarah Davis", date: "2023-10-12", avatar: "https://images.unsplash.com/photo-1494790108377-be9c29b29330" }, { id: 5, rating: 5, title: "Highly Recommended", review: "Exceeded my expectations in every way possible!", author: "David Lee", date: "2023-10-11", avatar: "https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d" }, { id: 6, rating: 4, title: "Great Value", review: "Excellent price-to-quality ratio, would buy again.", author: "Lisa Johnson", date: "2023-10-10", avatar: "https://images.unsplash.com/photo-1438761681033-6461ffad8d80" } ]; return ( <div className="max-w-4xl mx-auto p-6"> <h2 className="text-3xl font-extrabold mb-8">Customer Reviews</h2> <div className="space-y-6"> {reviews.map((review) => ( <div key={review.id} className="bg-white p-6 rounded-lg shadow-md"> <div className="flex items-center mb-4"> <img src={review.avatar} alt={review.author} className="w-12 h-12 rounded-full mr-4" /> <div> <h3 className="font-bold text-lg">{review.author}</h3> <p className="text-gray-500 font-medium">{review.date}</p> </div> </div> <h4 className="font-semibold text-xl mb-2">{review.title}</h4> <div className="flex mb-2"> {[...Array(review.rating)].map((_, i) => ( <span key={i} className="text-yellow-400">★</span> ))} </div> <p className="font-normal text-gray-700">{review.review}</p> </div> ))} </div> </div> ); }
Team Member Directory with Hierarchical Font Weights
This component showcases team members with different font weights to establish visual hierarchy.
export default function TeamDirectory() { const team = [ { id: 1, name: "Alexandra Chen", role: "Chief Executive Officer", department: "Executive", image: "https://images.unsplash.com/photo-1573496359142-b8d87734a5a2", email: "alexandra@company.com" }, { id: 2, name: "Marcus Rodriguez", role: "Technical Lead", department: "Engineering", image: "https://images.unsplash.com/photo-1506794778202-cad84cf45f1d", email: "marcus@company.com" }, { id: 3, name: "Sophie Williams", role: "Design Director", department: "Design", image: "https://images.unsplash.com/photo-1487412720507-e7ab37603c6f", email: "sophie@company.com" }, { id: 4, name: "James Patterson", role: "Marketing Manager", department: "Marketing", image: "https://images.unsplash.com/photo-1519345182560-3f2917c472ef", email: "james@company.com" }, { id: 5, name: "Elena Martinez", role: "Product Manager", department: "Product", image: "https://images.unsplash.com/photo-1573497019940-1c28c88b4f3e", email: "elena@company.com" }, { id: 6, name: "Richard Kim", role: "Sales Director", department: "Sales", image: "https://images.unsplash.com/photo-1500648767791-00dcc994a43e", email: "richard@company.com" } ]; return ( <div className="bg-gray-100 min-h-screen p-8"> <div className="max-w-6xl mx-auto"> <h2 className="text-4xl font-black mb-2">Our Team</h2> <p className="text-xl font-light mb-8 text-gray-600">Meet the people behind our success</p> <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6"> {team.map((member) => ( <div key={member.id} className="bg-white rounded-xl shadow-lg overflow-hidden"> <img src={member.image} alt={member.name} className="w-full h-48 object-cover" /> <div className="p-6"> <h3 className="font-extrabold text-xl mb-1">{member.name}</h3> <p className="font-semibold text-indigo-600 mb-2">{member.role}</p> <p className="font-medium text-gray-500 mb-4">{member.department}</p> <p className="font-normal text-gray-600">{member.email}</p> </div> </div> ))} </div> </div> </div> ); }
Blog Post Preview with Typography Hierarchy
This component displays blog post previews with varying font weights for better readability.
export default function BlogPreviews() { const posts = [ { id: 1, title: "The Future of Web Development", excerpt: "Exploring upcoming trends and technologies that will shape the future of web development.", category: "Technology", readTime: "8 min read", image: "https://images.unsplash.com/photo-1461749280684-dccba630e2f6", date: "Oct 15, 2023" }, { id: 2, title: "Mastering CSS Grid Layout", excerpt: "A comprehensive guide to creating complex layouts using CSS Grid.", category: "Development", readTime: "12 min read", image: "https://images.unsplash.com/photo-1517180102446-f3ece451e9d8", date: "Oct 14, 2023" }, { id: 3, title: "UI Design Principles", excerpt: "Essential principles every designer should know for creating effective user interfaces.", category: "Design", readTime: "10 min read", image: "https://images.unsplash.com/photo-1561736778-92e52a7769ef", date: "Oct 13, 2023" }, { id: 4, title: "Optimizing Website Performance", excerpt: "Tips and techniques for improving your website's loading speed and performance.", category: "Performance", readTime: "15 min read", image: "https://images.unsplash.com/photo-1460925895917-afdab827c52f", date: "Oct 12, 2023" }, { id: 5, title: "Responsive Design Best Practices", excerpt: "Learn how to create websites that look great on all devices.", category: "Design", readTime: "9 min read", image: "https://images.unsplash.com/photo-1523437113738-bbd3cc89fb19", date: "Oct 11, 2023" }, { id: 6, title: "JavaScript Framework Comparison", excerpt: "An in-depth comparison of popular JavaScript frameworks in 2023.", category: "Development", readTime: "14 min read", image: "https://images.unsplash.com/photo-1555099962-4199c345e5dd", date: "Oct 10, 2023" } ]; return ( <div className="bg-gray-50 min-h-screen p-8"> <div className="max-w-7xl mx-auto"> <h2 className="text-4xl font-black mb-12 text-center">Latest Articles</h2> <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8"> {posts.map((post) => ( <article key={post.id} className="bg-white rounded-2xl shadow-md overflow-hidden"> <img src={post.image} alt={post.title} className="w-full h-48 object-cover" /> <div className="p-6"> <div className="flex items-center justify-between mb-4"> <span className="font-medium text-indigo-600">{post.category}</span> <span className="font-normal text-gray-500">{post.date}</span> </div> <h3 className="font-extrabold text-xl mb-2">{post.title}</h3> <p className="font-normal text-gray-600 mb-4">{post.excerpt}</p> <div className="flex items-center"> <span className="font-medium text-gray-500">{post.readTime}</span> </div> </div> </article> ))} </div> </div> </div> ); }
Feature Comparison Table with Weight Emphasis
This component shows a pricing comparison table using font weights to highlight important information.
export default function FeatureComparison() { const features = [ { id: 1, name: "Basic", price: "$9", period: "monthly", description: "Perfect for individuals", features: [ "1 User", "5GB Storage", "Basic Support", "Basic Analytics", "Limited API Access", "Community Forum" ], recommended: false }, { id: 2, name: "Pro", price: "$29", period: "monthly", description: "Best for small teams", features: [ "5 Users", "20GB Storage", "Priority Support", "Advanced Analytics", "Full API Access", "Team Collaboration" ], recommended: true }, { id: 3, name: "Enterprise", price: "$99", period: "monthly", description: "For large organizations", features: [ "Unlimited Users", "100GB Storage", "24/7 Support", "Custom Analytics", "Custom Integration", "Dedicated Account Manager" ], recommended: false } ]; return ( <div className="bg-gray-50 py-12 px-4"> <div className="max-w-7xl mx-auto"> <h2 className="text-4xl font-black text-center mb-12">Pricing Plans</h2> <div className="grid grid-cols-1 md:grid-cols-3 gap-8"> {features.map((plan) => ( <div key={plan.id} className={`rounded-lg p-8 ${ plan.recommended ? "bg-indigo-600 text-white ring-4 ring-indigo-500" : "bg-white" }`} > <h3 className="font-extrabold text-2xl mb-2">{plan.name}</h3> <div className="mb-4"> <span className="font-black text-4xl">{plan.price}</span> <span className="font-normal">/{plan.period}</span> </div> <p className="font-medium mb-6">{plan.description}</p> <ul className="space-y-4"> {plan.features.map((feature, index) => ( <li key={index} className="flex items-center"> <svg className="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" > <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" /> </svg> <span className="font-normal">{feature}</span> </li> ))} </ul> <button className={`w-full mt-8 py-3 px-6 rounded-lg font-semibold ${ plan.recommended ? "bg-white text-indigo-600" : "bg-indigo-600 text-white" }`} > Choose Plan </button> </div> ))} </div> </div> </div> ); }
Statistics Dashboard with Font Weight Variations
This component displays statistics with different font weights to create visual hierarchy.
export default function StatisticsDashboard() { const statistics = [ { id: 1, title: "Total Revenue", value: "$142,384", change: "+12.5%", icon: "https://images.unsplash.com/photo-1526304640581-d334cdbbf45e", isPositive: true }, { id: 2, title: "Active Users", value: "8,749", change: "+25.8%", icon: "https://images.unsplash.com/photo-1517245386807-bb43f82c33c4", isPositive: true }, { id: 3, title: "Conversion Rate", value: "4.2%", change: "-2.4%", icon: "https://images.unsplash.com/photo-1551288049-bebda4e38f71", isPositive: false }, { id: 4, title: "Avg. Order Value", value: "$86.24", change: "+6.3%", icon: "https://images.unsplash.com/photo-1526304640581-d334cdbbf45e", isPositive: true }, { id: 5, title: "Customer Support", value: "98.7%", change: "+1.2%", icon: "https://images.unsplash.com/photo-1517245386807-bb43f82c33c4", isPositive: true }, { id: 6, title: "Churn Rate", value: "1.8%", change: "-0.5%", icon: "https://images.unsplash.com/photo-1551288049-bebda4e38f71", isPositive: true } ]; return ( <div className="bg-gray-100 p-8"> <div className="max-w-7xl mx-auto"> <h2 className="text-3xl font-black mb-8">Dashboard Overview</h2> <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6"> {statistics.map((stat) => ( <div key={stat.id} className="bg-white rounded-xl p-6 shadow-md"> <div className="flex items-center justify-between mb-4"> <h3 className="font-medium text-gray-500">{stat.title}</h3> <img src={stat.icon} alt={stat.title} className="w-8 h-8 rounded-full" /> </div> <div className="flex items-baseline justify-between"> <span className="font-extrabold text-2xl">{stat.value}</span> <span className={`font-semibold ${ stat.isPositive ? "text-green-500" : "text-red-500" }`} > {stat.change} </span> </div> </div> ))} </div> </div> </div> ); }
Customization Examples
Dynamic Blog Post Headers with Custom Font Weights
This example demonstrates how to create a blog post header with different font weights for title and subtitle.
// App.js import tailwindConfig from "./tailwind.config.js"; tailwind.config = tailwindConfig; export default function BlogHeader() { return ( <div className="max-w-4xl mx-auto p-8 bg-gradient-to-r from-gray-50 to-gray-100"> <div className="space-y-4"> <span className="text-sm font-ultra-thin text-gray-600"> FEATURED ARTICLE </span> <h1 className="text-5xl font-super-bold text-gray-800"> Understanding Modern Web Architecture </h1> <p className="text-xl text-gray-700 leading-relaxed"> Explore the fundamentals of contemporary web development and learn how different components interact to create seamless user experiences. </p> </div> </div> ) }
Product Price Card with Weight Variations
This example shows how to implement a product pricing card with different font weights for various text elements.
// App.js import tailwindConfig from "./tailwind.config.js"; tailwind.config = tailwindConfig; export default function PriceCard() { return ( <div className="w-80 rounded-xl shadow-lg bg-white p-6"> <img src="https://images.unsplash.com/photo-1460925895917-afdab827c52f" alt="Premium Plan" className="w-full h-48 object-cover rounded-t-lg" /> <div className="space-y-4 mt-4"> <h2 className="text-2xl font-price text-indigo-700"> Premium Package </h2> <div className="flex items-baseline"> <span className="text-4xl font-price text-gray-900">$99</span> <span className="text-gray-500 font-feature">/month</span> </div> <ul className="space-y-2"> {['Feature 1', 'Feature 2', 'Feature 3'].map((feature) => ( <li key={feature} className="font-feature text-gray-600"> ✓ {feature} </li> ))} </ul> <button className="w-full bg-indigo-600 text-white font-cta py-3 rounded-lg"> Subscribe Now </button> </div> </div> ) }
Statistics Dashboard Card with Variable Weights
This example showcases a statistics card using different font weights for numbers and labels.
// App.js import tailwindConfig from "./tailwind.config.js"; tailwind.config = tailwindConfig; export default function StatsCard() { return ( <div className="grid grid-cols-2 gap-6 p-6 bg-white rounded-2xl shadow-xl max-w-2xl"> <div className="col-span-2"> <h2 className="text-xl font-stats text-gray-800 mb-4"> Monthly Performance </h2> </div> {[ { label: 'Total Revenue', value: '$52,389', trend: '+12.3%' }, { label: 'Active Users', value: '2,847', trend: '+8.1%' }, { label: 'Conversion Rate', value: '3.24%', trend: '+2.4%' }, { label: 'Avg. Session', value: '4m 32s', trend: '-0.5%' } ].map((stat) => ( <div key={stat.label} className="bg-gray-50 p-4 rounded-lg"> <p className="text-sm font-label text-gray-500">{stat.label}</p> <p className="text-2xl font-stats text-gray-900 mt-1"> {stat.value} </p> <span className={`text-sm font-trend ${ stat.trend.startsWith('+') ? 'text-green-600' : 'text-red-600' }`}> {stat.trend} </span> </div> ))} </div> ) }
Best Practices
Maintain Design Consistency
When implementing font weight in your project, it's essential to maintain a consistent typographic hierarchy. In Tailwind CSS, you have access to utility classes such as font-light
, font-medium
, and font-bold
, among others. These predefined classes help ensure uniformity across your application when applied systematically.
For example, use lighter font weights like font-light
for auxiliary text such as descriptions or metadata, reserving heavier weights like font-bold
or font-extrabold
for headings and sections that require visual emphasis. By sticking to this principle, you create predictable rules that make the UI easier to navigate.
export default function ConsistentTypography() { return ( <div className="bg-gray-100 p-8 h-screen"> <h1 className="text-4xl font-bold text-gray-800">Article Title</h1> <p className="text-lg font-light text-gray-600 mt-2"> Published on Oct 17th, 2023 </p> <p className="font-normal text-gray-700 mt-4 leading-relaxed"> Understanding how to implement consistent design patterns is critical for achieving well-organized applications. Use font weights to visually group content into meaningful hierarchies. </p> </div> ); }
Leverage Utility Combinations
Tailwind CSS emphasizes utility-first design principles, allowing you to combine font weights with layout properties such as padding, margins, and colors. For example, combining font-extrabold
with vibrant text colors can draw attention to specific calls to action or critical details in your UI.
Combining font-light
for subtler text and font-semibold
for action buttons creates visual contrast, guiding users' attention throughout the component.
export default function HighlightStrategicElements() { return ( <div className="bg-white p-8 rounded-lg shadow-md h-screen"> <h2 className="font-extrabold text-blue-600 text-xl"> Limited Offer! </h2> <p className="font-light text-gray-700 mt-4"> Sign up today and enjoy benefits tailored just for you. </p> <button className="bg-blue-600 text-white font-semibold py-2 px-4 rounded-lg mt-6"> Register Now </button> </div> ); }
Accessibility Considerations
Enhance Readability for All Users
Accessible typography depends heavily on selecting font weights that do not compromise text readability. Tailwind CSS enables you to experiment while remaining mindful of user needs. For example, avoid weights that are either excessively thin or overly bold for body copy, as this can overwhelm readers.
Striking an appropriate balance between font weight and spacing ensures your content is accessible to a broader audience.
export default function ReadableContent() { return ( <div className="bg-gray-50 p-8 h-screen"> <h2 className="font-bold text-lg text-gray-800 mb-2"> Accessible Design in Focus </h2> <p className="font-normal text-gray-700 leading-relaxed"> To create inclusive experiences, prioritize readability over purely visual enhancements. Users with low vision might find overly light font weights difficult to read, while heavy weights could blur together on certain devices. </p> <p className="font-light text-gray-500 mt-4"> Ensure ample white space around heavier typography to improve usability. </p> </div> ); }
Focus on High Contrast Typography
Pairing font weights with appropriate color contrast can help users with visual impairments read content comfortably. For example, utilities like text-gray-800
and text-gray-100
work effectively with different font weights to provide sufficient contrast.
By intentionally maximizing contrast between text and background, you create visually inclusive designs for everyone.
export default function HighContrastContent() { return ( <section className="bg-gray-900 text-white p-6 h-screen"> <h1 className="font-extrabold text-3xl">Readability First</h1> <p className="font-medium text-gray-300 mt-4"> Ensure contrast ratios meet WCAG guidelines by testing combinations of background hues, font weights, and color brightness. Accessible designs prioritize visibility for all users. </p> </section> ); }
Debugging Common Issues
Resolve Nested Typography Issues in Complex Components
In deeply nested components, inherited styles may apply font weights. To avoid this issue, if the parent element contains a font weight, specifically add a new weight to the child.
export default function NestedTypography() { return ( <aside className="font-semibold p-8 bg-blue-50 space-y-3 h-screen"> <p> This paragraph reflects inherited weight from the parent container. </p> <p className="font-light"> This paragraph adjusts weight independently for unique emphasis. </p> </aside> ); }