こんにちは、Ryohei(@ityryohei)です!

本記事では、Vue.jsのv-ifやv-showのtransitionでスクロールバーが表示される場合の対処法をご紹介しています。

Vue.jsでv-ifやv-showで要素を表示する際にtransitionを使用すると、アニメーション時にスクロールバーが表示されるんだけど、非表示にする方法ないかな?

上記の疑問にお答えします。

本記事では下記バージョンのVue.jsで動作確認をしております。

  • Vue.js:v3.2.20

では、解説していきます。

スクロールバーが表示される原因

v-ifv-showで条件に応じてレンダリングする要素を切り替えると、処理中に一時的に切り替え前・切り替え後の要素が表示されます。その際に二つの要素を足した高さが親要素の高さを超えると、スクロールバーが表示されます。

v-ifv-showで切り替えを行うと一瞬のことなのであまり気にならないですが、transition等でアニメーションを付与すると、スクロールバーの表示が気になります。下記にデモをご用意しましたので、ボタンをクリックして二つの要素が切り替わる際の動作をご確認ください。

See the Pen 7299-1 by ryohei (@intotheprogram) on CodePen.

上記デモは極端な例ですが、やっぱりスクロールバーがあると気になりますよね。なのでスクロールバーを非表示にする対処法を2パターンご紹介したいと思います。

CSSで親要素にスタイルを追加する

要素のスクロールバーを非表示する場合、overflowプロパティを使用します。親要素のスタイルにoverflow: hiddenheight(autoや100%は除く)を追加することでスクロールバーを非表示にすることができます。

HTML

<div id="app">
    <transition>
        <section v-if="show">1</section>
    </transition>
    <transition>
        <section v-if="!show">2</section>
    </transition>
    <button v-on:click="toggle">Click Me!</button>
</div>

CSS

#app {
    height: 100vh;
    overflow: hidden;
}

DEMO

See the Pen 7299-2 by ryohei (@intotheprogram) on CodePen.

スクロールバーが非表示になっていますね。CSSによる対応は以上となります。

JavaScripttでスクロールバーを非表示にする

CSSを試してみたけど、高さの指定等の理由で対応できない場合はJavaScriptでスクロールバーを非表示にする方法が良さそうです。処理の流れは下記のようになります。

  • 親要素のclientHeightを取得・設定する
  • 親要素のスクロールバーを非表示にする
  • transitionのアニメーション終了後に再度スクロールバーを表示する

下記にサンプルを掲載しています。他にも効率の良い方法はあると思うので、参考程度にしていただければ幸いです。

HTML

<div id="app">
    <transition>
        <section v-if="show">1</section>
    </transition>
    <transition>
        <section v-if="!show">2</section>
    </transition>
    <button v-on:click="toggle">Click Me!</button>
</div>

CSS

.v-enter-from, .v-leave-to {
    opacity: 0;
    transition: .3s;
}

.v-leave-from, .v-enter-to {
    opacity: 1;
    transition: .3s;
}

JavaScript

const App = {
    data() {
        return {
            show: true,
        }
    },
    methods: {
        toggle(){
            this.height()
            this.hidden()
            this.visible()
            this.show = !this.show
        },
        height(){
            document.getElementById('app').style.height = document.getElementById('app').clientHeight + 'px'
        },
        hidden(){
            document.getElementById('app').style.overflowY = 'hidden'
        },
        visible(){
            setTimeout(function () {
                document.getElementById('app').style.overflowY = 'auto'
            }, 350)
        }
    }
}

Vue.createApp(App).mount('#app')

DEMO

See the Pen 7299-3 by ryohei (@intotheprogram) on CodePen.

以上でJavaScriptでスクロールバーを非表示にすることができました。

最後に

Vue.jstransitionはあまり使ったことがなかったので実装時に一部詰まる場面がありました。ただ、transition要素でアニメーションしたい要素をラップするだけで実装できるのは、かなり便利です。一度コツをつかんでしまえばわかりやすい機能ですので、今後も末永く使っていきたいと思います!

以上、Vue.jsでv-if・v-showのtransitionでスクロールバーが表示される場合の対処法のご紹介でした!

この記事を書いた人

Ryohei

Webエンジニア / ブロガー

福岡のWeb制作会社に務めるWebエンジニアです。エンジニア歴は10年程で、好きな言語はPHPとJavaScriptです。本サイトは私がインプットしたWebに関する知識を整理し、共有することを目的に2015年から運営しています。Webに関するご相談があれば気軽にお問い合わせください。