Nuxt 3 & Vuetify はとても使いやすいフレームワークで気に入ってします。
ひつじの翻訳室で開発している TraToys もこのフレームワークを使って開発しています。
しかし、つい最近つまづいたことがありました。
それが、タイトルにもある position: sticky です。
つくりたかったもの
このように2カラムあって、右側のカラムは左側のスクロールに関係なく、常に表示されるようにしたかったのです。
通常これは、CSSで position: sticky を設定すれば上手くいきます。
<template>
<v-container id="stick-container">
<v-row>
<v-col>
<v-list>
<v-list-item v-for="(i, n) in arr" :title="n" />
</v-list>
</v-col>
<v-col>
<div class="sticky-top">
<p>Stick at top!</p>
</div>
</v-col>
</v-row>
</v-container>
</template>
<script setup lang="ts">
const arr = Array(100).fill(true);
</script>
<style>
.sticky-top {
position: sticky;
top: 0;
}
</style>
しかし、これだけではなぜか上手くいきませんでした。
heightの設定や親要素・兄弟要素などいろいろ調整してみましたが、どうにも上手くいきません。
何が問題だったか
調べ回ったところ、こんなissueが上がっていました。
https://github.com/vuetifyjs/vuetify/issues/15433
これによると、v-layout コンポーネントに position: relative と overflow: hidden が設定されているのが問題かもしれないとのこと。このissueはすでに閉じられていますが、開発ツールで要素を見てやると、確かにv-layoutにはoverflow: hiddenが設定されています。
そのため、layouts/default.vue を作成し、次のようにv-layoutにstyleを設定してやります。
<template>
<v-app>
<v-layout class="rounded rounded-md" style="overflow: visible">
<v-app-bar
color="blue-grey"
scroll-behavior="elevate"
scroll-threshold="100"
>
<v-app-bar-title>Default Layout</v-app-bar-title>
</v-app-bar>
<v-main
class="d-flex align-center justify-center"
style="width: 100%; height: 100%"
>
<slot />
</v-main>
</v-layout>
</v-app>
</template>
これで最初の画像のとおり、stickyを実現することができました。
この記事のコードは こちら(Stackblitz)にあります。