DEV Community

Cover image for πŸ€·β€β™€οΈ πŸ€·β€β™‚οΈ Tailwind CSS with Heroicons: The SVG path stoke-width issue resolve
Vic ShΓ³stak
Vic ShΓ³stak

Posted on • Updated on

πŸ€·β€β™€οΈ πŸ€·β€β™‚οΈ Tailwind CSS with Heroicons: The SVG path stoke-width issue resolve


Hello, wonderful DEV people! πŸ‘‹

This is not exactly a standard β€œsimple error”, but rather a feature that the developers cannot bring to the Heroicons project in any way. The community has already paid attention to this and even formed a PR, but it was closed.

I will describe the solution for the Vue.js (with TypeScript) web application, but you can apply it to React, Svelte, or any other (or no framework at all).

Come on, let's resolve this problem! πŸ‘‡

πŸ“ Table of contents

Explanation of the problem

When we enlarge the icons, for example, through the built-in Tailwind CSS classes of that particular component, we may notice that the icon thickness becomes not quite what we expected.

<NewspaperIcon class="h-10 w-10" />          
Enter fullscreen mode Exit fullscreen mode

Yes, Tailwind CSS has a class stroke-{number} that allows you to customize this attribute only for the element that has it. But in the Heroicons implementation, this stroke-width attribute specified on the <path> nested elements, not on the <svg> wrapper (to which we have access).

tw docs 1

☝️ By the way: The stroke-width attribute is a presentation attribute defining the width of the stroke to be applied to the shape.

More info about stroke-width is here.

Therefore, we will have to write our styles to perform the desired behavior. There's nothing wrong with that, just watch the comments in the code!

↑ Table of contents

resolving the issue

Resolving the issue

Okay, here's a typical application structure on the Vue.js framework:

β”œβ”€β”€ src
β”‚   β”œβ”€β”€ assets
β”‚   β”‚   └── css
β”‚   β”‚       β”œβ”€β”€ ...
β”‚   β”‚       β”œβ”€β”€ heroicons.css # <-- styles for Heroicons
β”‚   β”‚       └── style.css     # <-- styles for Tailwind CSS
β”‚   β”œβ”€β”€ components
β”‚   β”‚   β”œβ”€β”€ ...
β”‚   β”‚   └── App.vue           # <-- main app component
β”‚   β”œβ”€β”€ main.ts               # <-- main app script
β”‚   └── ...
└── ...
Enter fullscreen mode Exit fullscreen mode

And this is the main TypeScript file where our styles mounted and the Vue instance created:

// ./src/main.ts

import { createApp } from 'vue'

// Import styles.
import './src/assets/css/style.css'
import './src/assets/css/heroicons.css' // <-- styles for Heroicons

// Import main component.
import App from './src/components/App.vue'

// Create a new Vue instance.
const app = createApp(App)

// ...
Enter fullscreen mode Exit fullscreen mode

To avoid conflicts, please verify that all styles you want to add or override satisfy these rules:

  1. Place them strictly after the basic Tailwind CSS style import;
  2. New styles have an associative class name;

Now let's form new styles to override the stoke-width attribute of the Vue component of Heroicons:

/* ./src/assets/css/heroicons.css */

.heroicon-stroke-w-0\.4 > path {
  stroke-width: 0.4;

.heroicon-stroke-w-0\.8 > path {
  stroke-width: 0.8;

.heroicon-stroke-w-1 > path {
  stroke-width: 1;

.heroicon-stroke-w-1\.2 > path {
  stroke-width: 1.2;

.heroicon-stroke-w-1\.6 > path {
  stroke-width: 1.6;
Enter fullscreen mode Exit fullscreen mode

In the CSS code above, I decided to add icon styles to my project to cover these stroke-width values: 0.4, 0.8, 1, 1.2, and 1.6. And by default, without specifying the .heroicon-stroke-w-{number} class, the icons will show up with a value of 2.

And now, we're ready to use these classes like this:

    <router-link :to="{ name: 'news' }">
      <NewspaperIcon class="h-10 w-10 heroicon-stroke-w-1.2" />
    <!-- ... -->

<script lang="ts">
import { defineComponent } from 'vue'
import { NewspaperIcon } from '@heroicons/vue/outline' // <-- add outline Heroicons for Vue

export default defineComponent({
  name: 'Menu',
  components: {
    NewspaperIcon, // add newspaper icon component
Enter fullscreen mode Exit fullscreen mode

This should be enough for any of my needs in the project, but you (having understood the principle) can add any to your taste.

↑ Table of contents


I really hope that the developers will listen to their users and introduce a normal built-in way to determine the stroke-width attribute in Heroicons in the next versions of their wonderful product.

Have a successful work and let simple errors (or such CSS complexities) never stop you on the way to realizing your projects! πŸ˜‰

↑ Table of contents

Photos and videos by


If you want more articles (like this) on this blog, then post a comment below and subscribe to me. Thanks! 😻

And of course, you can help me make developers' lives even better! Just connect to one of my projects as a contributor. It's easy!

My projects that need your help (and stars) πŸ‘‡

  • πŸ”₯ gowebly: A next-generation CLI tool for easily build amazing web applications with Go on the backend, using htmx & hyperscript and the most popular atomic/utility-first CSS frameworks on the frontend.
  • ✨ create-go-app: Create a new production-ready project with Go backend, frontend and deploy automation by running one CLI command.
  • πŸƒ yatr: Yet Another Task Runner allows you to organize and automate your routine operations that you normally do in Makefile (or else) for each project.
  • πŸ“š gosl: The Go Snippet Library provides snippets collection for working with routine operations in your Go programs with a super user-friendly API and the most efficient performance.
  • πŸ„β€β™‚οΈ csv2api: The parser reads the CSV file with the raw data, filters the records, identifies fields to be changed, and sends a request to update the data to the specified endpoint of your REST API.
  • 🚴 json2csv: The parser can read given folder with JSON files, filtering and qualifying input data with intent & stop words dictionaries and save results to CSV files by given chunk size.

Top comments (0)