How to create good looking custom scrollbars

Published at Feb 02, 2024Updated at Feb 03, 20247  minutes read

In my opinion one of the most difficult part in frontend is to make the layout look similar in every browser and that's because we have CSS Resets, but scrollbars can be one of the points we forget but can makes a huge difference to users.

Introduction

At my first year as developer, I always will remember a gaffe committed when introducing some new features I had developed to the CEO's company. Well, I use Mozilla Developer Edition to code, but at that time I forgot users uses Chrome in majority.

Statcounter graph showing Chrome are used by 70% of the users
Browser Market Share Worldwide Dec 2022 - Jan 2024. Ref.https://gs.statcounter.com

So the CEO. Yes, the scrollbar's feature was horrible in Chrome because the scrollbars are not aesthetic as Firefox. In the end, I did not got any in any trouble, the CEO only just pointed out and I did the fix in the next patch. I learnt to never forget scrollbars again, it cannot be neglected.

Problems

The main issue with scrollbars it is different styles in each browser which makes really hard to us track how the final layout is gonna be delivered to the user. And is not only the visuals, some browsers make the scrollbars take a size of the container, which can lead to layout looking weird. We gonna follow the name convention in this fantastic article by Zach Leatherman - Two Browsers Walked Into a Scrollbar:

  • Obtrusive scrollbars: scrollbars that take up screen real estate. These do not overlay on top of the content, but appear next to it.

  • Unobtrusive scrollbars: scrollbars that sit on top of the content. These don't subtract screen real estate away from the container they belong to.

I personally would prefer that every browser had unobtrusive scrollbars most because we as developer would not need to worry about taking some space in our layout. But I know that's not possible and probably would ruin a lot of layouts out there. Don't get me wrong, I am not saying some browser is better than other, I really think that every browser has some kind of problem when talking about scrollbars. Let's point out:

Mozilla Firefox

Firefox has unobtrusive and really aesthetic scrollbar which is great but I don't like how only "grows" the scrollbar on hover, not the container, but the scrollbar. I think if it has to grow, that should grow on hover the content to be easy accessed and not the scrollbar. Like if I already have reached the scrollbar, it does not need to grow, right? The grow is to make the bar more accessible...

Gif showing that Firefox only grows the scrollbar if hovered IN the scrollbar
Mozilla Firefox default scrollbar

Chromium Browsers

I love chromium browsers specially Chrome and Opera GX, I use them both in different situations, like coding I like Chrome and Mozilla Firefox Developer, but for daily routines I prefer Opera GX. But most of the scrollbars are not that great. First, they are obtrusive which for sole already brings some problems. Second, it is so wider even if user is not hovering the content, which is really ugly...

Gif showing the default behavior scrollbar in Mozilla Firefox
Chrome default scrollbar

Edge

One scrollbar I really like is from Edge Browser, yes, the successor of Internet Explorer. I think Edge has a lot of similar stuff with Chrome and the scrollbar is no different. Edge still has a wide scrollbar, but the borders are rounded which gives like a Firefox feeling. I really like, but I think could be better if were a little thinner.

Gif showing the default behavior scrollbar in Edge
Edge default scrollbar

Mobile

In mobile we have a little different problem. In my opinion mobile, the scrollbar can have the same problems above depending on which mobile browser you are, but with additional that scrollbars are only shown if you are actually scrolling, how I am supposed to know if that container has scroll if does not have a scrollbar?

Objectives

In this article I gonna show you how you can make your scrollbars aesthetic as can be in many different browsers, only using CSS. I am already warning you that is not possible to make like a reset to them, like we have done to h1, p and so on. CSS has its limitations and to achieve the fully goal probably will you need some Javascript code or maybe create all the logic with it. The method I am gonna show you is relative simple and can works on most browsers like Mozilla Firefox, Google Chrome, Brave, Opera GX, Edge and Safari, there will be an image with properties browser support in the end of the article. I think that's enough of talk, let's code.

Solution

First, please, do not ever style the main scrollbar. This is not standard, this do not need to follow your layout, it's good to look native to users do get lost. I think is good to style your scrollbars inside something you created, because this is "part" of your layout, different from the main scrollbar that is "part" of browser's layout. Did get it?

Well, for the solution, I searched a lot and got really frustrated when finding out the perfect solution do not exist, but we can came to a really nice result. Most of the sites uses some kind of Javascript or very difficult CSS approaches, so I filtered out the really necessary styles and merge them in a class styled-scrollbars you can use in the overflowing container. Most of these styles were gotten from Reddit's aside menu.

CSS code

There is no error, we gonna use two properties for Firefox (scrollbar-color and scrollbar-width) and some webkit for Chromium's browsers.

css  /* Firefox Only */
/* Approaches mobile first, because here, the scrollbar-color will be set and always will be that color, but on desktop, that we have hover effect, we can give a transparent color, but how this is mobile first, we give the color here, and treat the desktop in other style */
.styled-scrollbars {
  scrollbar-color: var(--some-really-nice-color-here);
  scrollbar-width: thin;
}
 
/* Chrome and others Browsers  */
.styled-scrollbars::-webkit-scrollbar {
  width: 4px;
  height: 4px
}
 
/* Chrome and others Browsers  */
.styled-scrollbars::-webkit-scrollbar-track {
  background: transparent;
}
 
/* With device has hover (Desktop or TV, etc) give a little effect on hover */
@media (hover: hover) {
  .styled-scrollbars {
    scrollbar-color: var(--some-really-nice-color-here-not-hover)  transparent ;
    scrollbar-width: thin;
    border-radius: 8px;
    transition: cubic-bezier(0.165, 0.84, 0.44, 1) 500ms  all ;
  }
 
  .styled-scrollbars:hover {
    scrollbar-color: var(--some-really-nice-color-here) transparent
  }
 
  .styled-scrollbars:hover::-webkit-scrollbar-thumb {
    background: var(--some-really-nice-color-here);
    border-radius: 8px;
    -ms-overflow-style: none;
    scrollbar-width: thin;
  }
}

To find the browser's support, please look at:

Final results

Gif showing the result of aesthetic scrollbar in Firefox
Mozilla Firefox
Gif showing the result of aesthetic scrollbar in Chrome
Chrome
Gif showing the result of aesthetic scrollbar in Edge
Edge

Additional tips

One very interesting stuff I found by searching content for this article is a solution for components that has a special css for hovering effects, is to use media query hover to only enable this on hover support devices. You can checkout the full video by the master of CSS Kevin Powell. I highly recommend.

Conclusion

In this article we saw a very clean way, consistent and CSS only to style your scrollbars to be aesthetic as possible between many different browsers like Mozilla Firefox, Google Chrome, Brave, Opera GX, Edge and Safari. Of course this approach is not 100% effective in all platforms, but works on most of them. Have a nice day. 😎✨✨✨😎

References

Two Browsers Walked Into a Scrollbar. Access at

Reddit. Access at

About the author

Profile of Felipe Scherer
Written by:

Felipe Scherer

- Software Engineer

Hello. I currently working as developer for more than 2 years coding sites, apps and games. In the free time I like to write articles to help people get started in this incredible world of coding. Feel free to explore my Github and use my public code 😊. Don't forget to follow me on my socials. 🌟

Share this Article

Help us improve

If you find any mistakes or just want to make the article more complete, consider editing this page in Github.

edit_squareEdit on Github
open_in_new
descriptionContribution guide
open_in_new

You may also like

Create custom classes Tailwind

Create custom classes Tailwind

Tailwind CSS is a popular modern CSS framework known for its utility-first approach. Unlike component-based frameworks like Bootstrap, Tailwind provides a collection of low-level utility classes that you combine to achieve your desired styles. This approach offers greater flexibility and granular control over your styles. It also boasts excellent build optimizations, including generating only the classes used in your project. While Tailwind offers built-in customization options, this article explores various methods for creating custom classes, with a focus on maintaining a positive developer experience. ## Tailwind CSS: Beyond the Basics - Crafting Custom Classes Tailwind CSS has a lot of classes, but there is some time you find yourself the need to use a class that are not in the default package, so what you do? There are a lot of ways to create custom classes, described in [docs](https://tailwindcss.com/docs/adding-custom-styles). I am gonna go though all of them, but be aware my favorite is the last one- By creating a plugin, so if you want, just skip to here ## Arbitrary values-properties-variants Tailwind is built for really hard customization, and that’s so true, you can literaly create any class just combining some prefix or sufix and the compiler will generate for you the classes for build. So, Why we avoid this approach when dealing to customization? The answer is because this goes agains the reusability concept of Tailwind, and if you use more than one that that arbitrary value, I recommend to create a custom utility for it. <Img src="https://github.com/fescherer/fennec-tales-blog/assets/62115215/76b33e7a-bd3f-4940-aabd-e3232034fc7b" name="Arbitrary property Tailwind example" alt="code example of tailwind arbitrary using a color of background" /> <Img src="https://github.com/fescherer/fennec-tales-blog/assets/62115215/9994a2a8-a1df-4be8-813a-759d7ea15e64" name="Build file " alt="Build file showing the arbitrary property became other class" /> ## Customizing the theme If you want to change the properties already build in, like the font-size or color, it’s perfect and really easy to do just customizing the Tailwind theme file. <Img src="https://github.com/fescherer/fennec-tales-blog/assets/62115215/3fcdaf65-9624-4966-8ccd-49aa74daf8c1" name="tailwind.config.ts" alt="Creating a class my-blue in Tailwind file" /> <Img src="https://github.com/fescherer/fennec-tales-blog/assets/62115215/61559e23-be18-43ea-a0a5-04dc0fbca834" name="Code example" alt="Using the custom classes created in a div" /> <Img src="https://github.com/fescherer/fennec-tales-blog/assets/62115215/810e5dfc-70f1-4505-88df-bc1a25c8653d" name="Build file- This may looks weird, but is the same blue I configured, but just with some Tailwind optimization." alt="Build file showing that Tailwind handle better using theme" /> The problem is when you need to create a custom component class, like you repeat that same classes and that became redundant and hard to read. <Img src="https://github.com/fescherer/fennec-tales-blog/assets/62115215/5920d701-17f9-476e-8df4-c5c3024c4594" name="Example of reduntant classes" alt="File showing a lot of container with same classes" /> Isn’t better having just one class like `hello-world-container`? Yes. ## @layer and @apply directive There is a way to add custom classes using some Tailwind directives in CSS files. Like this: <Img src="https://github.com/fescherer/fennec-tales-blog/assets/62115215/53c6e419-42b5-472e-a321-1af95569e58b" name="Example of reduntant classes" alt="File showing a lot of container with same classes" /> You can literaly put any CSS valid property just like the way you would do in normal CSS, but noticed I put the classes inside some directives, why? Tailwind is composed by layers that can be overwritten, eg. You have a base style for your button but you want to change it’s color just in one component, to make that you will need to overwrite it, in normal CSS you will probably use !important, and trust me in my experience if you had use !important, probabily there is something wrong with your code. So use layers with wisdom. I recommend using: - [@layer base](https://tailwindcss.com/docs/adding-custom-styles#adding-base-styles) for tag styles, like I used in the example for tag `code`. - [@layer components](https://tailwindcss.com/docs/adding-custom-styles#adding-component-classes) for classes that has more than one style like the `hello-world-container` which has **display: flex;flex-direction:column;justify-content:center;background-color:purple;padding:1rem**. Most customization you will need is gonna be made here. - [@layer utilities](https://tailwindcss.com/docs/adding-custom-styles#adding-custom-utilities) is the highest priority, so use carefully. I recommend using just for one single property like **transparent:background-color:transparent**. This will mostly be used for classes that do not exist in default Tailwind. Well, so we learned about the @layer directive, but what is that @apply in the example? This is a way to use your Tailwind token in the styling file. For build does not matter if you use the **hello-world-container** or **hello-world-container-2**, both produces the same result, so @apply helps your code readbility. Using directives may seen the best way to create custom classes in Tailwind, but as I said in the beginning of the article, this is not my favorite way. I prefer much more creating a custom plugin. ## Why I do not like Tailwind directives like @layer and @apply Fist I need to say why I love the experience of working with Taiwlind insted other CSS framework similar like Bootstrap. Tailwind has been investing not just in optimizations and fast files, but in development experience too. Tailwind has a very nice VSCode plugin called [Tailwind Intellisense](https://tailwindcss.com/docs/editor-setup#intelli-sense-for-vs-code) I personally do not recommend you use Tailwind without this plugin. One thing it changes is when you hover a class, it shows what is that CSS equivalent, is literally required for me and I do not see me not using it. <Img src="https://github.com/fescherer/fennec-tales-blog/assets/62115215/9b5e1959-3c80-4589-867c-47b0fdf40e48" name="Tailwind VSCode Intellisense showcase" alt="Print showing when hovering the class has a popup showing CSS equivalent" /> You know, when you create custom classes, you need Tailwind Intellisense to recognize it, but I never found a way to make recognize directives like @layer. When creating custom classes like that, you do not have the hover preview :( This is unacceptable, specially because custom classes do not exist in Tailwind Docs, is the most important classes to have a register and a easy way to check the CSS equivalent. So going though Github Issues and making a lot of testing. I probably have the best solution to create custom classes in Tailwind. ## Create custom plugins As you can see there are a lot of ways to customize you styles in Tailwind, but there is superior way to customize and still get the Tailwind Intellisense working for us, it’s called 🪽 Plugins 🪽. What is and how we implement? <Blockquote cite="https://en.wikipedia.org/wiki/Plug-in_(computing)"> is a software component that adds a specific feature to an existing computer program </Blockquote> So in [Tailwind](https://tailwindcss.com/docs/plugins) is not diffent, plugins are a way to modify the base of Tailwind, you can do a lot of it, but in this article I just gonna show how you can use to create custom classes styles. Every Tailwind project has a **tailwind.config.js** or **tailwind.config.ts** which has all of Tailwind’s configuration, including the **theme** from earlier, but what we want is the **plugins** <Img src="https://github.com/fescherer/fennec-tales-blog/assets/62115215/27b51eae-d5a0-4c14-81cf-19c97aa76398" name="tailwind.config.ts" alt="tailwind.config.ts file" /> You will need to use a function from Tailwind called `plugin`. I highly recommend using Typescript, for its typing features, which helps a lot, but of course you can use Vanila Javascript too. <Img src="https://github.com/fescherer/fennec-tales-blog/assets/62115215/e42b46ba-2710-4575-81b4-6ad8e864e30f" name="Plugin function" alt="Plugin function" /> In it’s parameters you put what you want to create. For this article, we want a component, so we use the addComponent param. <Img src="https://github.com/fescherer/fennec-tales-blog/assets/62115215/bee18037-70d5-435f-810f-fa6876a62629" name="Plugin function add components" alt="Plugin function add components" /> Now just add the class name and the styles like CSS or (CSS Style Declation)[https://www.w3.org/TR/cssom/#the-cssstyledeclaration-interface] (backgroundColor insted background-color). <Img src="https://github.com/fescherer/fennec-tales-blog/assets/62115215/5a6db547-3f58-4eca-98ce-c5564885fbd6" name="Custom class made by plugin example" alt="Custom class made by plugin example" /> And there you go, now you have the hovering effec from Tailwind Intellisense :) <Img src="https://github.com/fescherer/fennec-tales-blog/assets/62115215/688da377-c59e-4cd2-ba24-b02499d4da25" name="Class in action" alt="Print showing when hovering the custom class made by plugin, showing the equivalent CSS" /> ## More dev experience Here's an additional tip to elevate your Tailwind development experience: consider using the [eslint-plugin-tailwindcss package](https://www.npmjs.com/package/eslint-plugin-tailwindcss). This ESLint plugin offers various features to help you write cleaner and more maintainable Tailwind code. ## Summary This article explored various methods for creating custom classes in Tailwind CSS, emphasizing the importance of a positive development experience. By leveraging Tailwind plugins, you can create custom styles while maintaining IntelliSense support and overall code clarity. This approach empowers you to extend Tailwind's capabilities while keeping your development workflow efficient and enjoyable. Thanks for reading see you in the next article, have a nice day 😊

Tailwind Strategies for themes

Tailwind Strategies for themes

In this article I will talk about some strategies you can use to create themes on Tailwind, a way to write CSS in utility classes, like if you want to say `display: flex`, you can just give a *classname* of `flex`. Of course this is a very simple example, but you can do so much more and everything is customizable. [Tailwind CSS](https://tailwindcss.com) as the docs says: <Blockquote cite="https://eslint.org/docs/latest/use/getting-started"> A utility-first CSS framework packed with classes like `flex`, `pt-4`, `text-center` and `rotate-90` that can be composed to build any design, directly in your markup. </Blockquote> ### What is Tailwind CSS To understand Tailwind CSS is good to know how it was created. Well, the framework was created by [Adam Wathan](https://twitter.com/adamwathan) because he wanted to use a [Bootstrap](https://getbootstrap.com) kinda syntax with [Less processor](https://lesscss.org), as you may know Bootstrap has build in classes for `buttons`, `forms`, etc. Tailwind in other hand has just utility classes, like `flex`, `backgrounds`, `paddings`, `margins`, etc. That's why in the first versions of Tailwind, it has some of the classes like Bootstrap, but from time on Adam switched to more generic classes. He also needed to change the processor to PostCSS, but you can find the whole history at [OfferZen Origins's channel](https://www.youtube.com/watch?v=1x7HlvSfW6s). For me, frameworks that's uses utility classes are the best ones, it can be strange at first but the productivity grows so much using this strategy that I cannot stop using. ### Popularity For popularity Tailwind is one of the favorite CSS Framework out there. You can see this in [State of CSS Survey](https://2023.stateofcss.com/en-US/css-frameworks): <Img src="https://github.com/fescherer/blog/assets/62115215/23055cb4-026e-4f25-b287-e3556251faf3" name="State of CSS" source="https://2023.stateofcss.com/en-US/css-frameworks" alt="Survey from State of CSS showing the is one of most used technologies for styling" /> They have a lot of interesting data. I suggest you to take look and see for yourself. ### How to use As said before, Tailwind uses utility classes, so you will add them into your html as so: ```html {1-2} <div className="m-4 flex items-center justify-center"> <span>Item 1</span> <span>Item 2</span> </div> ``` When I started coding, the company used [Angular](https://angular.io) with kinda of utility classes. We a had a big style sheet containing all the most used classes like `padding` or `margin` and them, if we would need some more specific style, we create a class just for it. I grow up and for my experience, don't do that, try to stay just with utility classes, it way more easy to maintain. You can find the list of utility classes available [in the docs](https://tailwindcss.com/docs/utility-first). ## What is theme Theme is a set of characteristics that build an idea. I can be applied to an environment to give the feeling of that characteristics. So you can made a party using a Halloween theme, so everyone and the party probably will have characteristics from Halloween. In design is the same thing, we can made certain [rules that build in a theme](https://www.uxpin.com/studio/blog/design-system-theming), like font sizes, spaces, images and colors. This can be used for accessibility advantages or just to made a design some unique like a special version for christmas. It became very popular for all designs to have at least a version called `dark` with more darker colors and a `light` with, of course, lighter colors. So it is very important to know how you can handle this. ## Strategies for theming in Tailwind In this tutorial, I will show only themes that change colors, that's because I think changing the font-size or spaces can be tricky and not so great in the final product. Tailwind already has a [theme build in support](https://tailwindcss.com/docs/dark-mode) but I think is not ideal mostly if you want to add more than just dark and light theme. So that's why I gonna show you some strategies you can use to add more themes for Tailwind CSS. ### Using external libraries There a lot of libs created by the community to solve the problem of multiple themes in Tailwind. Some examples would be: - [Tailwind CSS Theme Variants](https://github.com/JNavith/tailwindcss-theme-variants); - [Tailwind Themer](https://github.com/RyanClementsHax/tailwindcss-themer); - [TW Colors](https://github.com/L-Blondy/tw-colors); - Many more... All have a very similar concept and way to solve this by enable to create themes on `Tailwind.config.ts`, as an example of configuring three themes dark, light and forest using [TW Colors](https://github.com/L-Blondy/tw-colors#add-more-themes): ```typescript const { createThemes } = require('tw-colors'); module.exports = { content: ['./src/**/*.{html,js,jsx,md,mdx,svelte,ts,tsx,vue}'], plugins: [ createThemes({ light: { 'primary': 'steelblue', 'secondary': 'darkblue', 'brand': '#F3F3F3', }, dark: { 'primary': 'turquoise', 'secondary': 'tomato', 'brand': '#4A4A4A', }, forest: { 'primary': '#2A9D8F', 'secondary': '#E9C46A', 'brand': '#264653', }, }) ], }; ``` It is a great improve on my point of view and you can certainly use it, but for me I would like to make my own code in my own way. ### CSS Variables TW Colors uses CSS variables to make the themes, so I thought I could use too as I already made a theme logic using them when working with Angular 2 years ago. Then I started thinking what are my needs and how can I solve them. The first thing was that I want as many themes as possible- So I would need to provide to every theme into different files as I wanted a lot of them, staying at the same file would not be very scalable. Second thing I wanted is to control the theme based on a html attribute `data-theme` as: ```html <html data-theme="dark"></html> ``` With this in mind, I thought on a simple solution: Use CSS variables, and change the value of them using Javascript. To start this I overwrite [Tailwind default colors](https://tailwindcss.com/docs/customizing-colors) with my colors in `Tailwind.config.ts` using CSS variables syntax as: ```typescript import type { Config } from 'tailwindcss' import defaultTheme from 'tailwindcss/defaultTheme' const config: Config = { content: [ './src/**/**/*.{js,ts,jsx,tsx,mdx}', ], theme: { colors: { 'primary': 'var(--primary)', 'secondary': 'var(--secondary)', 'text': 'var(--text)', 'title': 'var(--title)', 'foreground': 'var(--foreground)', 'background': 'var(--background)', 'background-card': 'var(--background-card)', 'text-on-primary': 'var(--text-on-primary)', 'text-hover': 'var(--text-hover)', 'primary-hover': 'var(--primary-hover)', 'code-header': 'var(--code-header)', 'transparent': 'transparent', 'current': 'currentColor', }, } } export default config ``` A little observation about two colors `transparent` and `current` that are been used as constants and not variables values, because I do not want to change them when the theme is changed. Continuing after colors configuration, I need to declare these variables and default values for them into some place so I went to `global.css` where [Tailwind is init](https://tailwindcss.com/docs/installation/using-postcss) and then declare the variables into a root [pseudo-class](https://developer.mozilla.org/en-US/docs/Web/CSS/:root): ```css @tailwind base; @tailwind components; @tailwind utilities; :root { --primary: #51C28A; --secondary: #74DFAA; --text: #DDDDDD; --title: #EAEAEA; --foreground: #282929; --background: #131313; --background-card: #ffffff0a; --text-on-primary: #FFFFFF; --text-hover: #888888; --primary-hover: #409c6e; --code-header: #21222C; } ``` If you want, you can add a accessible [medias prefers color scheme](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme). That almost it, now you just need to add in some css file the values for each theme like so: ```css :root[data-theme='dark'] { --primary: #51C28A; --secondary: #74DFAA; --text: #DDDDDD; --title: #EAEAEA; --foreground: #282929; --background: #131313; --background-card: #ffffff0a; --text-on-primary: #FFFFFF; --text-hover: #888888; --primary-hover: #409c6e; --code-header: #21222C; } ``` To make a better organization I like to make one file for each theme and then export all in one file. <Img src="https://github.com/fescherer/blog/assets/62115215/672b8aae-169a-4028-ace2-0f5482005252" name="Folder structure" alt="Folder structure" /> ```css /* themes/variants/dark.css */ :root[data-theme='dark'] { --primary: #51C28A; --secondary: #74DFAA; --text: #DDDDDD; --title: #EAEAEA; --foreground: #282929; --background: #131313; --background-card: #131313; --text-on-primary: #FFFFFF; --text-hover: #888888; --primary-hover: #409c6e; --code-header: #21222C; } ``` ```css /* themes/variants/light.css */ :root[data-theme='light'] { --primary: #359967; --secondary: #4d9470; --text: #090a0a; --title: #191b1a; --foreground: #dfdfdf; --background: #ffffff; --background-card: #dfdfdf; --text-on-primary: #FFFFFF; --text-hover: #888888; --primary-hover: #409c6e; --code-header: #21222C; } ``` ```css /* themes/index.css */ @import './variants/dark.css'; @import './variants/light.css'; ``` This way I can import the `index.css` file with all the imports already set up. The last part, we need to make the logic to change themes. To do this first you need to map all your themes into an array. ```typescript /* themes/themes.theme.ts */ export const themes = [ 'dark', 'light', ] ``` Lastly just change the value of the `html` attribute `data-theme` with Javascript and voilà. ```javascript document.getElementsByTagName('html')[0].setAttribute('data-theme', 'light') ``` ## SSR Themes preference If you analyze my blog you would probably noticed that theme preference is storage somewhere and then loaded before even the page. How that's possible? The key word is [`cookies`](https://web.dev/understanding-cookies). These type of data is storage and can be access by the server, not only the browser like [`local storage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage), using this, we can load the theme in server and then bring to browser the storage one as default. There are many ways to manage cookies and I think that every framework has its own way to do that. In this tutorial I will teach you with [NextJS 13 using app router](https://nextjs.org) because it is what I use and have experience. First we need to install 1 dependency called [cookies-next](https://www.npmjs.com/package/cookies-next) because with the [new API of app router, we can only use cookies at server components](https://nextjs.org/docs/app/api-reference/functions/cookies) but this solves just one part of the equation the load can be at server components, but every time we use interaction, the component need to be client, so how am I supposed to save a cookie of user theme choice? That's why we use `cookies-next`, to manipulate cookies at client components. ```bash npm install cookies-next ``` Let's start in the root `layout.tsx`. ```jsx export default function RootLayout({ children, }: { children: React.ReactNode }) { const cookieTheme = cookies().get('data-theme') const theme = themes.includes(cookieTheme?.value ?? '') ? cookieTheme?.value : 'dark' return ( <html lang="en" data-theme={theme}> <body> <main> {children} </main> </body> </html> ) } ``` Using the code above you can load the cookie `data-theme` and then pass to `html`. Now to change this just use the code Javascript that I said to you earlier. ```jsx // Here you can storage these values together with the themes like I showed you earlier. const themes = [ 'dark', 'light', ] function handleTheme(theme: string) { document.getElementsByTagName('html')[0].setAttribute('data-theme', theme) } export function ThemeSelector() { return ( <div> { themes.map((theme) => ( <button key={theme} onClick={() => handleTheme(theme)}> {theme} </button> )) } </div> ) } ``` ## User preferences - prefers-color-scheme, prefers-reduced-motion, etc One last thing you can do to make your code even better is to add a default theme based on user preference, it is very common to add a option on theme selector saying `default` or `system`, this is a theme based on user's system theme. So that's really import to make our interface looks like the user's on first time accessing our site. To do that is very simple, just add a [CSS query prefers-color-scheme](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme). ```css /* themes/variants/system.css */ @media (prefers-color-scheme: dark) { :root { --primary: #51C28A; --secondary: #74DFAA; --text: #DDDDDD; --title: #EAEAEA; --foreground: #282929; --background: #131313; --background-card: #282929; --text-on-primary: #FFFFFF; --text-hover: #888888; --primary-hover: #409c6e; --code-header: #21222C; } } @media (prefers-color-scheme: light) { :root { --primary: #359967; --secondary: #4d9470; --text: #090a0a; --title: #191b1a; --foreground: #dfdfdf; --background: #ffffff; --background-card: #dfdfdf; --text-on-primary: #FFFFFF; --text-hover: #888888; --primary-hover: #409c6e; --code-header: #f3e9de; } } ``` ## Conclusion In this article I told you a little about the history behind Tailwind CSS creation, with the explain about what are themes and how people use them with Tailwind. For last how I would implement themes by myself using Tailwind and NextJS SSR feature to load theme in the server rendering time. Thank you for your time. Have a nice day. 😎✨✨✨😎

12 must have VSCode extensions

12 must have VSCode extensions

VSCode is one of the most popular IDE's for coding everything from Java to Javascript. VSCode is super customizable and for that the community created a lot of custom extensions for VSCode. That's what we will cover in this article. ## Extensions.json This is a file you can add to `.vscode` folder and configure a set of extensions that are recommended by VSCode if the user don't have them. ## 1. VSCode Eslint <Img src="https://github.com/fescherer/blog/assets/62115215/be8bd7f5-b4f1-40c7-9974-290068604da3" name="VSCode Eslint" alt="Print showing VSCode Eslint extension" /> [As the doc says](https://eslint.org/docs/latest/use/getting-started): <Blockquote cite="https://eslint.org/docs/latest/use/getting-started"> Eslint is a tool for identifying and reporting on patterns found in ECMAScript/JavaScript code </Blockquote> This means that its goal is to be a tool to enforce certain patterns that we can consider "Good practices" or just avoid errors and bad syntaxes. This is possible by using a big set of rules that are completely customizable, and with just one line you can turn on or off the rules that you prefer and of course there are a lot of custom rules made by the community that in addition to add more validation to Javascript, also makes an integration to other stuff you may have like [React](https://www.npmjs.com/package/eslint-plugin-React), [TailwindCSS](https://www.npmjs.com/package/eslint-plugin-tailwindcss), [Typescript](https://typescript-eslint.io) and many more. So Eslint is very good but why do I need the extension? Well, you can run `npx eslint .` every time to check if Eslint got any error or warning, but if you want something more fast and easy to do, and trust me, you do, [installing the extension](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) allows Eslint to run parallel while coding, ensuring that the error will be shown as you code. **Link for download**: [VSCode Eslint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) ## 2. Git Lens <Img src="https://github.com/fescherer/blog/assets/62115215/5a918dda-768d-40ae-b1aa-7baf01632f11" name="Git Lens" alt="Print showing Git Lens extension" /> Have you ever code with a partner? A friend, co-worker or relative and found a line with a very serious bug and needed went to Github to found how made that line? Well, with Git Lens solves your problem by adding a little hint of who made the last update to that line and in how much time ago. I can tell you must be thinking. How this is so useful? For me, it can be handy to have, you may forgot the extension installed but at some time I can assure you will use. Not only for to know the person how did change the line, but also to know when was the last time that line was updated. I know Git Lens offers other uses, but for my necessities this is good enough. You can read more about it [here](https://www.gitkraken.com/gitlens). **Link for download**: [Git Lens](https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens) ## 3. Editor Config <Img src="https://github.com/fescherer/blog/assets/62115215/433781d2-df06-44ee-a87c-0399dd640e7e" name="Editor Config" alt="Print showing Editor Config extension" /> [Editor config](https://editorconfig.org) is a set of configurations that can maintain consistent coding across multiple IDEs, the configurations are basically about indentations, file formats, charset, unix style new lines, etc. This extensions enables to overwrite vscode configurations with the ones set on `.editorconfig` file. I always like to config this file instead my vscode because this way I know the code will be more consistent across multiple IDEs. **Link for download**: [Editor Config](https://marketplace.visualstudio.com/items?itemName=EditorConfig.EditorConfig) ## 4. Print showing Code Snapshot extension <Img src="https://github.com/fescherer/blog/assets/62115215/9fe14a53-fdf7-4849-b417-7ad969150b72" name="Code Snapshot" alt="Print showing Code Snapshot extension" /> I confess that Code Snapshot is not a super must have extension, but it is really nice and works really well. It can take screenshots from your code in MacOS style for you to post anywhere you want, like in a social media. **Link for download**: [Code Snapshot](https://marketplace.visualstudio.com/items?itemName=robertz.code-snapshot) ## 5. VSCode Icons <Img src="https://github.com/fescherer/blog/assets/62115215/f310c814-9f83-4752-a1a6-d21c8e9be2e2" name="VSCode Icons" alt="Print showing VSCode Icons extension" /> This one has a lot of my opinion, but I really think you should have an extension to modify your icons. It help so much when finding that specific file, I always go for the icon first instead of the file extension or the name of it. **Link for download**: [VSCode Icons](https://marketplace.visualstudio.com/items?itemName=vscode-icons-team.vscode-icons) ## 6. Import Cost <Img src="https://github.com/fescherer/blog/assets/62115215/80b88259-d63e-4233-b75d-32881818b14b" name="Import Cost" alt="Print showing Import Cost extension" /> One of the most important thing we as developer need to understand is how our site can be found by search engines like Google or Bing, and one thing I see a lot is a very large [First Contentful Paint(FCP)](https://web.dev/fcp). This is basically the time when the first render of page ends and this is [crucial for user experience](https://web.dev/fcp/#what-is-a-good-fcp-score), a bad time may result in user leaving your page. One of the strategies to decrease FCP time is the only first load the necessary and after you can load the small pieces like an api call. And this can be achieved by removing all the big bundles inside your project. The [Import Cost extension](https://marketplace.visualstudio.com/items?itemName=wix.vscode-import-cost) helps you to do that by showing the bundle size of that lib and then you can or remove it or search for a lighter lib. **Link for download**: [Import Cost](https://marketplace.visualstudio.com/items?itemName=wix.vscode-import-cost) ## 7. Markdown All in One and MDX <Img src="https://github.com/fescherer/blog/assets/62115215/53dd13aa-8bef-4898-9604-45bf2d875d79" name="MDX extension" alt="Print showing MDX extension" /> <Img src="https://github.com/fescherer/blog/assets/62115215/61d48f6d-a3bb-419a-bc6b-f0952582bd7d" name="A markdown file" alt="Print showing markdown file" /> In this topic I will put two extensions because I know not everyone is a React developer and uses [MDX](https://marketplace.visualstudio.com/items?itemName=unifiedjs.vscode-mdx) files as I use, so it is more reasonable for these people use [Markdown All in One](https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one) that gives all the essential stuff to have a great time writing your files. For React developers I suggest using [MDX](https://mdxjs.com), a superset of Markdown allowing to use React component inside Markdown. It is super handful and as I see, MDX is becoming a popular way to write Markdown in [NextJS](https://nextjs.org/docs/app/building-your-application/configuring/mdx). You can even use [Content layer](https://contentlayer.dev/docs/sources/files/mdx-d747e46d) to type your Markdown, if that's not fantastic I don't know what is. **Link for download**: [Markdown All in One](https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one) **Link for download**: [MDX](https://marketplace.visualstudio.com/items?itemName=unifiedjs.vscode-mdx) ## 8. Code Spell Checker <Img src="https://github.com/fescherer/blog/assets/62115215/fd817aa8-e864-4a55-98a9-8844c359cd9e" name="Code Spell Checker" alt="Print showing Code Spell Checker extension" /> Again, if you write files Markdown or anything that will probably be useful to have a grammar corrector and this extension is just like that. **Link for download**: [Code Spell Checker](https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker) ## 9. Auto Rename Tag <Img src="https://github.com/fescherer/blog/assets/62115215/10594378-40dd-419a-8ff6-9c38c2ec95e0" name="Auto Rename Tag" alt="Print showing Auto Rename Tag extension" /> One of the most useful extension I use is Auto Rename Tag, this as the name says, when change the tag name, the matching one will be changed too. **Link for download**: [Auto Rename Tag](https://marketplace.visualstudio.com/items?itemName=formulahendry.auto-rename-tag) ## 10. Themes <Img src="https://github.com/fescherer/blog/assets/62115215/effc88d1-7a25-40a3-b2b4-2c5f02c1d93f" name="Dracula Theme" alt="Print showing Dracula Theme" /> In number 10 I will put a more vast collection of extensions used to change the VSCode appearance, of course I am talking about [themes](https://vscodethemes.com/). There are a lot and I mean A LOT of available themes that can change the most different aspects, but most likely the colors, you can find a more lighter, darker, greener, yellowish and many more themes. If you want a recommendation, I would certain suggest to use [Dracula Theme](https://marketplace.visualstudio.com/items?itemName=dracula-theme.theme-dracula), it is one of most famous themes out there with more than 5 million installs. The colors are great even for dark environments or bright environments. **Link for download**: [Dracula Theme](https://marketplace.visualstudio.com/items?itemName=dracula-theme.theme-dracula) ## 11. Extra ones Well, for last I would suggest you to install the extension useful for what you are using to code, like if you are using [TailwindCSS](https://tailwindcss.com), please use the [TailwindCSS extension](https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss), and this can be applied to everything in your project, [Styled Components](https://marketplace.visualstudio.com/items?itemName=styled-components.vscode-styled-components) or even other language than Javascript like [Python](https://www.python.org) VSCode has the extension [Python for VSCode](https://marketplace.visualstudio.com/items?itemName=ms-python.python). So have a look what you have installed and search if has an extension that could help you. 😊 ## Conclusion Conclusion reading this article you were introduced to a set of VSCode extensions that can help improve your coding time and quality. All of that are free and can be downloaded from [Microsoft VSCode MarketPlace](https://marketplace.visualstudio.com). Thank you for reading and see you in the next article. Have a nice day. 😎✨✨✨😎