🤷‍♀️ 🤷‍♂️ Tailwind CSS with Heroicons: The SVG path stoke-width issue resolve
Tags: css, tailwindcss, vue, webdev
Published: 2021-10-18 13:18:34

## 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](https://heroicons.com/) project in any way. The community has already [paid attention](https://github.com/tailwindlabs/heroicons/issues/241) to this and even formed a [PR](https://github.com/tailwindlabs/heroicons/pull/281), 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! 👇

<a name="toc"></a>
### 📝 Table of contents

- [Explanation of the problem](#explanation-of-the-problem)
- [Resolving the issue](#resolving-the-issue)
- [Conclusions](#conclusions)

<a name="#explanation-of-the-problem"></a>
## 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.

```vue
<NewspaperIcon class="h-10 w-10" />          
```

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e333gphs0n99xawssrm4.png)

> ☝️ **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](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-width).

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](#toc)

![resolving the issue](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4up9zk4pg5b1rv9a1buh.jpg)

<a name="#resolving-the-issue"></a>
## Resolving the issue

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

```console
.
├── 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
│   └── ...
└── ...
```

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

```typescript
// ./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)

// ...
```

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:

```css
/* ./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;
}
```

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:

```html
<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>
```

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](#toc)

<a name="#conclusions"></a>
## 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](#toc)

<a name=""></a>
## Photos and videos by

- Maik Jonietz https://unsplash.com/photos/_yMciiStJyY
- Alessandro Bianchi https://unsplash.com/photos/_kdTyfnUFAc

<a name=""></a>
## 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 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][gowebly_url]: 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][cgapp_url]: Create a new production-ready project with Go backend, frontend and deploy automation by running one CLI command.
- 🏃 [yatr][yatr_url]: 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][gosl_url]: 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][csv2api_url]: 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][json2csv_url]: 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.

<!-- Footer links -->

[gowebly_url]: https://github.com/gowebly
[cgapp_url]: https://github.com/create-go-app
[yatr_url]: https://github.com/koddr/yatr
[gosl_url]: https://github.com/koddr/gosl
[csv2api_url]: https://github.com/koddr/csv2api
[json2csv_url]: https://github.com/koddr/json2csv