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

Introduction

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:

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

<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
  },
})
</script>
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

Conclusions

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

P.S.

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 support me by donating at LiberaPay. Each donation will be used to write new articles and develop non-profit open-source projects for the community.

Support author at LiberaPay

Discussion (0)