loading...
Cover image for Tailwind CSS static navbar with shadow on scroll for Vue applications

Tailwind CSS static navbar with shadow on scroll for Vue applications

chipd profile image Chris Dermody Originally published at chrisdermody.com ・2 min read

I first wrote about this over on my blog - really only for my own personal reference since I'll need this code again in my next project. But thought I'd share here too.

demo of scrolling effect for shadow on navbar

If you're not using Tailwind for your CSS needs - I highly recommend it. It's now a staple of my product building toolkit, and it just fits so well with Vue.js and Nuxt workflows that I can't imagine moving to something else.

One thing about Tailwind is it leaves the Javascript to you. This is so it's library-agnostic.

For most of my projects I want that smooth shadow under the navbar - here's the code I use to achieve it.

The HTML

<nav 
    :class="{ 'scrolled': !view.atTopOfPage }" 
    class="fixed flex w-full bg-white border-b items-center justify-between flex-wrap p-5 m-auto top-0 animated">
</nav>

Here, we're adding the .scrolled class when the value in view.atTopOfPage is false.

The CSS

I have a navbar component that I use throughout the app, so this code would go there. PS: Yes this is technically SCSS...

nav {
    z-index: 10
}

nav.scrolled {
    @apply shadow-2xl;
    border-bottom: 0px;
}

Apply the shadow to the navbar when it has the class scrolled.

The Javascript

// in data, I like to store a view object with all 
// the values I need for a component to manage 
// it's 'view' state - ie loading, 
// or in this case, if the user is at the top of the page or not
data () {
    return {
        view: {
            atTopOfPage: true
        }
    }
},

// a beforeMount call to add a listener to the window
beforeMount () {
    window.addEventListener('scroll', this.handleScroll);
},

methods: {
    // the function to call when the user scrolls, added as a method
    handleScroll(){
        // when the user scrolls, check the pageYOffset
        if(window.pageYOffset>0){
            // user is scrolled
            if(this.view.atTopOfPage) this.view.atTopOfPage = false
        }else{
            // user is at top of page
            if(!this.view.atTopOfPage) this.view.atTopOfPage = true
        }
    }
}

The Result

Buttery smooth shadows on your navbar. Check it out in action on my product Referextra.com

Posted on by:

chipd profile

Chris Dermody

@chipd

I'm a Product Owner who codes. I love building things in my own time, tripcoster.com, mydevportfol.io, referextra.com, livedata.ninja

Discussion

markdown guide
 

Hi,

nice article!

But please, avoid doing things like:

<nav class="fixed flex w-full bg-white border-b items-center justify-between flex-wrap p-5 m-auto top-0 animated">

this isn't different from inline style... what if you have to change text align, margin, or background color? Normally this is a css job, but with this markup you have to change your html for every cosmetic change.

If you really want to use the Tailwind classes, give your nav a single classname (like, i don't know, class="main-navbar"), then in your scss extend all the Tailwind classes under .main-navbar. This way you can leave your html clean and independent from the styling.

 

Your thought was my initial thought also but I have revisited it.

Keeping it in the html is not as big of a issue as it use to be. It also makes it more portable, unless you are using plain css files or something that is not css in js.

This is how tailwind was designed to be used. Yes you can compose new classes with it. But that is really just making more work on yourself.

In modern web dev, like the Vue app he built, he most likely has single file components. So now if he wanted to adjust the nav bar, he will be going into that file anyways.

The big argument you are making are multiple instances of a piece of html across the site. Well, with modern development by making components you only have one place for that code in development. So it’s not extra work.

Additionally my teams have switched to TailwindCss and with the inline classes have found a few things.

  1. It’s faster to develop because the syntax is shorter and your not opening another file or moving to the style block in the same file.

  2. They still need to know css, unlike bootstrap.

  3. Code reviews have become easier, because you are not mapping classes declared somewhere else and the styles to the html.

  4. Naming things is hard, now they do a lot less of that.

  5. Our extensions have been pretty minimal, same with overrides, yet we do not look like what you might assume the theme is.

Because of many of these reasons, we may even use Alpine JS in the next project.

So I know this goes against conventional wisdom. I have been at this for almost 20 years and totally understand where your coming from. But as you can see I have come around.

 

Bravo ... that's exactly what I was thinking.

Extending makes sense if you're doing something multiple times over and over, like cards for instance or alerts. But utility first gives you far more fine grained control over your presentation.

You'll notice even boostrap has added many utility classes to mimic the tailwind paradigm.

Thanks for the code OP, this was very useful.

 

I've been working with Tailwindcss for more than a year and I could not put into words, what is like to work with it. Kudos to these arguments

 

More I see Tailwind CSS the more I like it.IΓ„ have been thinking to rebuild my site Colors & Fonts[colorsandfonts.com] with Tailwind, right now is built with BulmaCSS but using Bueafy's CSS file.

How much are you liking Tailwind.

Very nice the whole site.

 

I'm absolutely loving Tailwind. I think it's fantastic and endlessly flexible, I never have trouble creating the UI that I need - and it slots into my Vue workflow seamlessly. With PurgeCSS it makes my CSS files crazy light. Love it.

 

Great post! I'm using Vue/Nuxt, Tailwind and Firebase to build some hobbyist projects and I love it. I like having so much control and the ability to write the html and "css" at the same time in the same place.

Anyway, I have a newbie question. When I fix the nav bar like this, how do I prevent it from covering the top part of the element below (my nuxt element) ?

 

I usually add a padding/margin to the top of the body element so that all content is pushed down a little. Hope that helps

 

Thanks Chris, this was really useful and drop dead simple to implement on my existing navbar.

Brilliant mate.