Menu

Tailwind CSS Text Decoration Thickness

Text decoration thickness in CSS specifies the width of underlines, overlines, or line-through decorations on text. This property is ideal for enhancing the visual appearance and emphasis of text, offering you control to create both subtle and bold styles. Tailwind CSS provides a suite of utilities that allows developers to easily set and customize text decoration thickness without writing custom CSS, making styling consistent, reusable, and efficient.

ClassPropertiesExample
decoration-autotext-decoration-thickness: auto;<div className="decoration-auto"></div>
decoration-from-fonttext-decoration-thickness: from-font;<div className="decoration-from-font"></div>
decoration-0text-decoration-thickness: 0px;<div className="decoration-0"></div>
decoration-1text-decoration-thickness: 1px;<div className="decoration-1"></div>
decoration-2text-decoration-thickness: 2px;<div className="decoration-2"></div>
decoration-4text-decoration-thickness: 4px;<div className="decoration-4"></div>
decoration-8text-decoration-thickness: 8px;<div className="decoration-8"></div>

Adding the Text Decoration Thickness

Tailwind CSS makes it straightforward to apply thickness controls to text decorations. You can modify the width of underlines or overlines using predefined classes for various utilities, ensuring readability and aesthetics.

Setting the Text Decoration Thickness

Tailwind's predefined classes for text decoration thickness- decoration-2, decoration-4, etc. let you adjust widths of decoration lines. Here's an example:

This is a live editor. Play around with it!
export default function CustomTextDecoration() {
  return (
    <div className="h-screen w-screen flex items-center justify-center bg-gray-100">
      <h1 className="underline decoration-pink-500 decoration-4 text-lg text-center px-20">
        This text has a 'decoration-4' underline.
      </h1>
    </div>
  );
}

// decoration-4 -> Sets thickness to 4px.

In the above code snippet, a decoration-4 class is used to specify a moderately thick underline. Adjust the class to create aesthetic variances in your applications.

States and Responsiveness

Tailwind doesn't just stop at static styling—you can conditionally apply text-decoration-thickness based on hover, focus, or even screen widths.

Hover and Focus States

With hover or focus modifiers, you can dynamically change the thickness on hover and focus states to grab the user's attention.

This is a live editor. Play around with it!
export default function InteractiveUnderline() {
  return (
    <div className="h-screen w-screen flex items-center justify-center bg-gray-200">
      <p className="underline decoration-black decoration-2 hover:decoration-4 text-lg text-center px-20 font-medium">
        Hover over me to see the difference
      </p>
    </div>
  );
}

// decoration-2 -> Default thickness (2px).
// hover:decoration-4 -> Increase thickness on hover.

Breakpoint Modifiers

To create designs that work across devices, Tailwind offers breakpoint-specific modifiers- sm, md, etc. You can use these modifiers on the decoration-* utilities to target different breakpoints. For example, thin lines on small screens and thicker decorations for larger displays:

This is a live editor. Play around with it!
export default function VariableThickness() {
  return (
    <div className="h-screen w-screen bg-gray-50 flex flex-col justify-around items-center">
      <p className="underline decoration-sky-500 decoration-2 sm:decoration-4 lg:decoration-8 text-lg text-center px-20">
        Resize the window to see underline adjust
      </p>
    </div>
  );
}

// decoration-2 -> Default thickness for screens < 640px.
// sm:decoration-4 -> Medium thickness for screens >= 640px.
// lg:decoration-8 -> Thicker decorations for screens >= 1024px.

Custom Text Decoration Thickness

Beyond using Tailwind's default utilities, you can define unique thickness values to meet your design requirements.

Extending the Theme

The theme.extend key in your Tailwind configuration file allows you to define custom thicknesses. Once extended, the custom classes become directly available in your markup.

This is a live editor. Play around with it!
import tailwindConfig from "./tailwind.config.js";
tailwind.config = tailwindConfig;

export default function CustomConfigText() {
  return (
    <div className="h-screen w-screen flex justify-center items-center bg-gray-300">
      <p className="underline decoration-purple-700 decoration-extraBold text-lg text-center px-12 leading-loose">
        This line has a custom 'decoration-extraBold' thickness
      </p>
    </div>
  );
}

// decoration-extraBold -> Sets underline to 12px (defined in config).

Using Arbitrary Values

If custom values are required for one-off decorators, Tailwind lets you use arbitrary values- decoration-[value], ensuring flexibility during rapid prototyping. With arbitrary values, you can bypass predefined constraints while maintaining readability and precision in your design outcomes.

This is a live editor. Play around with it!
export default function ArbitraryValueText() {
  return (
    <div className="h-screen w-screen flex justify-center items-center bg-gray-50">
      <p className="underline decoration-gray-700 decoration-[10px] text-lg leading-loose px-12 text-center">
        This line has an arbitrary thickness value of 10px.
      </p>
    </div>
  );
}

// decoration-[10px] -> Manually sets underline thickness to 10px.

Real World Examples

Product Category Navigation with Hover Effects

This component showcases a horizontal category navigation with varying text decoration thickness on hover states.

This is a live editor. Play around with it!
export default function CategoryNav() {
  const categories = [
    { id: 1, name: "Electronics", count: "2,456" },
    { id: 2, name: "Fashion", count: "1,832" },
    { id: 3, name: "Sports", count: "1,567" },
    { id: 4, name: "Books", count: "4,123" },
    { id: 5, name: "Automotive", count: "987" }
  ];

return (
<nav className="bg-gray-50 p-6 w-[40rem]">
<ul className="flex gap-4 justify-between max-w-4xl mx-auto">
{categories.map((category) => (
<li key={category.id}>
<a
href={`#${category.name}`}
className="text-gray-700 hover:text-blue-600 decoration-blue-500 hover:underline hover:decoration-2 transition-all" >
{category.name}
<span className="ml-2 text-sm text-gray-500">({category.count})</span>
</a>
</li>
))}
</ul>
</nav>
);
}

Featured Article Cards with Emphasized Titles

A grid of article cards featuring titles with custom text decoration thickness.

This is a live editor. Play around with it!
export default function FeaturedArticles() {
  const articles = [
    {
      id: 1,
      title: "The Future of AI",
      category: "Technology",
      image: "https://images.unsplash.com/photo-1620712943543-bcc4688e7485",
      author: "Jane Smith",
      readTime: "5 min"
    },
    {
      id: 2,
      title: "Sustainable Living",
      category: "Lifestyle",
      image: "https://images.unsplash.com/photo-1542601906990-b4d3fb778b09",
      author: "John Doe",
      readTime: "8 min"
    },
  ];

return (
<div className="grid gap-6 p-8">
{articles.map((article) => (
<article key={article.id} className="bg-white rounded-lg shadow-md">
<img 
            src={article.image} 
            alt={article.title}
            className="w-full h-48 object-cover rounded-t-lg"
          />
<div className="p-4">
<h2 className="text-xl font-bold underline decoration-4 decoration-yellow-400 mb-2">
{article.title}
</h2>
<p className="text-gray-600">{article.category}</p>
<div className="mt-4 flex justify-between text-sm text-gray-500">
<span>{article.author}</span>
<span>{article.readTime} read</span>
</div>
</div>
</article>
))}
</div>
);
}

Price Comparison Table with Highlighted Features

A pricing table that uses text decoration thickness to emphasize important features.

This is a live editor. Play around with it!
export default function PricingTable() {
  const plans = [
    {
      id: 1,
      name: "Basic",
      price: "$9",
      features: ["1 User", "5GB Storage", "Basic Support", "Email Access", "API Access", "Documentation"]
    },
    {
      id: 2,
      name: "Pro",
      price: "$29",
      features: ["5 Users", "20GB Storage", "Priority Support", "Email Access", "API Access", "Documentation"]
    },
    {
      id: 3,
      name: "Enterprise",
      price: "$99",
      features: ["Unlimited Users", "100GB Storage", "24/7 Support", "Email Access", "API Access", "Documentation"]
    }
  ];

return (
<div className="flex flex-wrap justify-center gap-8 p-10">
{plans.map((plan) => (
<div key={plan.id} className="bg-white w-72 p-6 rounded-xl shadow-lg">
<h3 className="text-2xl font-bold underline decoration-indigo-500 decoration-[3px]">
{plan.name}
</h3>
<p className="text-4xl font-bold mt-4">{plan.price}<span className="text-sm">/mo</span></p>
<ul className="mt-6 space-y-3">
{plan.features.map((feature, index) => (
<li key={index} className="flex items-center">
<span className="text-green-500 mr-2">✓</span>
{feature}
</li>
))}
</ul>
</div>
))}
</div>
);
}

Team Member Directory with Role Highlights

A grid of team members with decorated role titles.

This is a live editor. Play around with it!
export default function TeamDirectory() {
  const team = [
    {
      id: 1,
      name: "Alex Johnson",
      role: "CEO",
      image: "https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d",
      department: "Executive"
    },
    {
      id: 2,
      name: "Sarah Wilson",
      role: "CTO",
      image: "https://images.unsplash.com/photo-1494790108377-be9c29b29330",
      department: "Technology"
    },
    // ... more team members
  ];

return (
<div className="grid gap-8 p-10">
{team.map((member) => (
<div key={member.id} className="text-center">
<img 
            src={member.image} 
            alt={member.name}
            className="w-32 h-32 rounded-full mx-auto mb-4"
          />
<h3 className="font-bold text-lg">{member.name}</h3>
<p className="underline decoration-red-400 decoration-[6px] underline-offset-4">
{member.role}
</p>
<p className="text-gray-600 mt-2">{member.department}</p>
</div>
))}
</div>
);
}

Event Timeline with Date Emphasis

A vertical timeline showing events with emphasized dates using text decoration thickness.

This is a live editor. Play around with it!
export default function EventTimeline() {
  const events = [
    {
      id: 1,
      date: "JAN 15",
      title: "Product Launch",
      description: "Launch of our new mobile app",
      location: "Virtual Event"
    },
    {
      id: 2,
      date: "FEB 28",
      title: "Tech Conference",
      description: "Annual developer conference",
      location: "San Francisco, CA"
    },
    // ... more events
  ];

return (
<div className="max-w-2xl mx-auto p-8">
{events.map((event) => (
<div key={event.id} className="flex gap-6 mb-8">
<div className="w-24">
<span className="font-mono text-lg underline decoration-pink-500 decoration-[8px] underline-offset-4">
{event.date}
</span>
</div>
<div className="flex-1 border-l-2 border-gray-200 pl-6">
<h3 className="text-xl font-bold">{event.title}</h3>
<p className="text-gray-600">{event.description}</p>
<p className="text-sm text-gray-500 mt-2">{event.location}</p>
</div>
</div>
))}
</div>
);
}

Customization Examples

This example demonstrates how to implement different underline thicknesses for primary and secondary navigation items.

This is a live editor. Play around with it!
// App.js
  import tailwindConfig from "./tailwind.config.js";
tailwind.config = tailwindConfig;

export default function NavigationMenu() {
  return (
    <nav className="bg-slate-900 p-8">
      <div className="max-w-4xl mx-auto">
        <ul className="flex justify-between items-center gap-8">
          <li>
            <a
              href="#"
              className="text-white text-xl font-semibold no-underline hover:underline hover:decoration-thick hover:decoration-purple-500 transition-all duration-300"
            >
              Home
            </a>
          </li>
          <li>
            <a
              href="#"
              className="text-white text-xl font-semibold no-underline hover:underline hover:decoration-medium hover:decoration-blue-400 transition-all duration-300"
            >
              Products
            </a>
          </li>
          <li>
            <a
              href="#"
              className="text-white text-xl font-semibold no-underline hover:underline hover:decoration-thin hover:decoration-green-400 transition-all duration-300"
            >
              Contact
            </a>
          </li>
        </ul>
      </div>
    </nav>
  );
}

Article Headlines with Custom Underlines

This example shows how to create responsive typography with varying underline thicknesses.

This is a live editor. Play around with it!
// App.js
  import tailwindConfig from "./tailwind.config.js";
tailwind.config = tailwindConfig;

export default function ArticleHeadlines() {
  return (
    <div className="max-w-5xl mx-auto p-8 bg-gray-50">
      <article className="space-y-12">
        <h1 className="text-4xl md:text-6xl font-bold text-gray-900 underline decoration-red-500 decoration-lg md:decoration-xl mb-8">
          Breaking News Today
        </h1>
        
        <div className="grid gap-8">
          <h2 className="text-2xl md:text-3xl font-medium text-gray-800 underline decoration-blue-400 decoration-sm hover:decoration-lg transition-all">
            Technology Updates 2024
          </h2>
          
          <h2 className="text-2xl md:text-3xl font-medium text-gray-800 underline decoration-green-400 decoration-xs hover:decoration-sm transition-all">
            Environmental Changes
          </h2>
          
          <h2 className="text-2xl md:text-3xl font-medium text-gray-800 underline decoration-purple-400 decoration-sm hover:decoration-lg transition-all">
            Scientific Discoveries
          </h2>
        </div>
      </article>
    </div>
  );
}

Product Price Cards with Emphasized Discounts

This example demonstrates how to style pricing information effectively.

This is a live editor. Play around with it!
// App.js
  import tailwindConfig from "./tailwind.config.js";
tailwind.config = tailwindConfig;

export default function PriceCards() {
  return (
    <div className="bg-gray-100 p-8">
      <div className="max-w-6xl mx-auto grid grid-cols-1 md:grid-cols-3 gap-8">
        <div className="bg-white p-6 rounded-xl shadow-lg">
          <img
            src="https://images.unsplash.com/photo-1523275335684-37898b6baf30"
            alt="Product"
            className="w-full h-48 object-cover rounded-lg mb-4"
          />
          <h3 className="text-xl font-bold mb-2">Premium Watch</h3>
          <div className="space-y-2">
            <p className="text-gray-500 line-through decoration-red-500 decoration-price">
              $299.99
            </p>
            <p className="text-2xl font-bold text-green-600">$249.99</p>
          </div>
        </div>

        <div className="bg-white p-6 rounded-xl shadow-lg">
          <img
            src="https://images.unsplash.com/photo-1505740420928-5e560c06d30e"
            alt="Product"
            className="w-full h-48 object-cover rounded-lg mb-4"
          />
          <h3 className="text-xl font-bold mb-2">Wireless Headphones</h3>
          <div className="space-y-2">
            <p className="text-gray-500 line-through decoration-red-500 decoration-discount">
              $199.99
            </p>
            <p className="text-2xl font-bold text-green-600">$149.99</p>
          </div>
        </div>

        <div className="bg-white p-6 rounded-xl shadow-lg">
          <img
            src="https://images.unsplash.com/photo-1572635196237-14b3f281503f"
            alt="Product"
            className="w-full h-48 object-cover rounded-lg mb-4"
          />
          <h3 className="text-xl font-bold mb-2">Designer Sunglasses</h3>
          <div className="space-y-2">
            <p className="text-gray-500 line-through decoration-red-500 decoration-super-thick">
              $399.99
            </p>
            <p className="text-2xl font-bold text-green-600">$299.99</p>
          </div>
        </div>
      </div>
    </div>

);
}

Best Practices

Maintain Design Consistency

When working with text decoration thickness in Tailwind CSS, ensure that the styles align with the overall theme or design system of your project. For instance, if your site uses thin text decorations for subtitles and thick underlines for headers, maintain this pattern throughout.

By standardizing the text decoration utilities, you not only create a recognizable look but also ensure maintainability. This could include applying custom Tailwind configurations to override the defaults for better consistency. For example, your tailwind.config.js can define specific thickness values for global use. This helps avoid hardcoded, inconsistent values scattered throughout your codebase.

Combining Tailwind Utilities Thoughtfully

Leverage the versatility of Tailwind CSS by combining multiple utilities to achieve intricate designs while maintaining clarity in the code. For example, you can pair text decoration thickness utilities with color, underline offset, and hover effects to create dynamic interactive elements. Consider using hover:decoration-4 alongside hover:decoration-green-400 for hover-responsive elements.

When combining utilities, adhere to readability and avoid over-complication. For instance, limit the layering of numerous utility classes by grouping related functionality or encapsulating styles through component-level abstraction. If you’re designing a navigation menu, use Tailwind's responsive modifiers to scale the thickness across breakpoints, ensuring you achieve a harmonious relationship between size and design.

Accessibility Considerations

Improving Readability and Content Navigation

Text decoration thickness can significantly influence readability, especially for underlined links or headings. Many users rely on visible markers such as underlines and line-through styles to distinguish interactive or emphasized sections. You should always test your chosen thickness against varying font sizes and weights to ensure that the visual hierarchy is clear while maintaining adequate text spacing.

Accessible Interactive Elements

Interactive elements like buttons, dropdowns, or forms benefit from clear visual indications triggered by hover, focus, or active states. Use Tailwind's state modifiers like hover or focus to give accessibility cues. For keyboard users, increasing underline thickness on focus can provide better navigability, ensuring that they can interact with components as intuitively as mouse or touch-screen users.

By combining states with decoration thickness and offsets, you can ensure an intuitive experience for assistive technology users. Always test combinations of underlines, colors, offsets, and states to confirm compatibility with screen readers or other accessibility tools, ensuring compliance with accessibility standards.

Debugging Common Issues

Managing Overflow and Alignment Issues

Problems with overflowing text decorations often occur when thickness values are visually inconsistent with surrounding elements. A frequent cause of this issue is using larger decoration-* utilities with small font sizes, which can lead to misaligned decorations or visual clutter. To resolve this, align text decoration utility values to the font size and weight of the element.

Troubleshooting Nesting Conflicts

Nested components with decoration thickness utilities may encounter style inheritance issues, where parent-level declarations unintentionally affect child elements. For example, applying global text decoration styles to a parent container can extend to links or list items, leading to undesired overrides. To prevent this, isolate styles within specific contexts using Tailwind’s group utility in combination with group-hover:decoration-*.

In the below snippet, when you hover on the card, the decoration underline will come on the title:

This is a live editor. Play around with it!
export default function FeaturedArticles() {
  const articles = [
    {
      id: 1,
      title: "Sustainable Living",
      category: "Lifestyle",
      image: "https://images.unsplash.com/photo-1542601906990-b4d3fb778b09",
      author: "John Doe",
      readTime: "8 min"
    },
  ];

return (
<div className="grid gap-6 p-8">
{articles.map((article) => (
<article key={article.id} className="bg-white rounded-lg shadow-md">
<img 
            src={article.image} 
            alt={article.title}
            className="w-full h-48 object-cover rounded-t-lg"
          />
<div className="p-4 group">
<h2 className="text-xl font-bold group-hover:underline group-hover:decoration-4 group-hover:decoration-yellow-400 mb-2">
{article.title}
</h2>
<p className="text-gray-600">{article.category}</p>
<div className="mt-4 flex justify-between text-sm text-gray-500">
<span>{article.author}</span>
<span>{article.readTime} read</span>
</div>
</div>
</article>
))}
</div>
);
}