How to Scroll to the Bottom of a div Element in Vue.js
To scroll to the bottom of a div element in Vue.js:
- Create an element at the bottom of the
div
. - Set a ref on this element.
- Call
scrollIntoView()
on the ref to scroll down to this element.
<template>
<div>
<div
style="
position: fixed;
background-color: white;
bottom: 0;
margin-bottom: 10px;
"
>
<button
@click="scrollToBottom"
style="margin-left: 8px"
>
Scroll to bottom
</button>
</div>
<div style="height: 5rem"></div>
<div>
<h2
v-for="fruit in allFruits"
:key="fruit"
>
{{ fruit }}
</h2>
<!-- 👇 Element created at the bottom -->
<div ref="bottomEl"></div>
</div>
<div style="height: 150rem"></div>
</div>
</template>
<script>
export default {
data() {
return {
allFruits: [
'Apples',
'Bananas',
'Oranges',
'Grapes',
'Strawberries',
'Blueberries',
'Pineapples',
'Mangoes',
'Kiwis',
'Watermelons',
],
};
},
methods: {
scrollToBottom() {
this.$refs.bottomEl?.scrollIntoView({ behavior: 'smooth' });
},
},
};
</script>
Here we have a list of fruits displayed.
The Scroll to bottom
button scrolls to the bottom of the div on click.
It does this by calling scrollIntoView()
in a click
event listener we set on the bottom element’s ref.
...
<script>
...
methods: {
scrollToBottom() {
this.$refs.bottomEl?.scrollIntoView({ behavior: 'smooth' });
},
},
};
</script>
We set the behavior
option to smooth
to make the element scroll into view in an animated way, instead of jumping straight to the element in the next frame – auto
.
auto
is the default.
We create the Vue ref using the div
element’s ref
prop.
<template>
<div>
...
<div>
...
<div ref="bottomEl"></div>
</div>
</div>
</template>
...
Doing lets us access the HTMLElement
representing the div using this.$refs.bottomEl
.
Scroll to bottom of dynamic list div in Vue.js
We can do something similar to scroll to the bottom of a div containing a list of items that change over time.
<template>
<div>
<div
style="
position: fixed;
background-color: white;
bottom: 0;
margin-bottom: 10px;
"
>
<button @click="addFruit">Add fruit</button>
<button
@click="scrollToLastFruit"
style="margin-left: 8px"
>
Scroll to last
</button>
</div>
<div style="height: 5rem"></div>
<div ref="fruitsContainer">
<h2
v-for="fruit in fruits"
:key="fruit"
>
{{ fruit }}
</h2>
</div>
<div style="height: 150rem"></div>
</div>
</template>
<script>
export default {
data() {
return {
allFruits: [
'Apples',
'Bananas',
'Oranges',
'Grapes',
'Strawberries',
'Blueberries',
'Pineapples',
'Mangoes',
'Kiwis',
'Watermelons',
],
fruits: [],
};
},
mounted() {
this.fruits = [...this.allFruits.slice(0, 3)];
},
methods: {
addFruit() {
this.fruits.push(this.allFruits[this.fruits.length]);
},
scrollToLastFruit() {
const lastChildElement =
this.$refs.fruitsContainer.lastElementChild;
lastChildElement?.scrollIntoView({
behavior: 'smooth',
});
},
},
};
</script>
Like in the previous example, we also have a list of fruits displayed here.
But this time the list isn’t static – when can add an item to it with the Add fruit
button.
The Scroll to last
button scrolls to the last item in the div – the most recently added item.
Like before, we use the click
event to set a click event listener on the button.
We set the ref on the list instead of a list item, since the items are created dynamically, and the last item will not always be the same.
<template>
<div>
<div
...
>
...
<div ref="fruitsContainer">
...
</div>
...
</div>
</template>
Doing this lets us access the HTML element using this.$refs
.
In this listener, we use the lastElementChild
property of the list element to get its last item element. Then we call scrollIntoView()
on this last item to scroll down to it.
...
<script>
export default {
...
methods: {
scrollToLastFruit() {
const lastChildElement =
this.$refs.fruitsContainer.lastElementChild;
lastChildElement?.scrollIntoView({
behavior: 'smooth',
});
},
},
};
</script>
Scroll to bottom of div after render
Sometimes we want to scroll to the bottom of the div immediately after the page renders.
If we want to scroll to the bottom of the list in the previous section,
we’ll just call scrollIntoView()
from the mounted
hook:
...
<script>
export default {
...
mounted() {
this.scrollToLastFruit();
},
methods: {
scrollToLastFruit() {
const lastChildElement =
this.$refs.fruitsContainer.lastElementChild;
lastChildElement?.scrollIntoView({
behavior: 'smooth',
});
},
},
};
</script>
The code in the mounted
hook is run just after the component mounts.
So we call scrollToLastFruit()
here, which in turn calls scrollIntoView()
to scroll to the bottom of the list div.
Here’s the full code for reference:
<template>
<div>
<div style="height: 5rem"></div>
<div ref="fruitsContainer">
<h2
v-for="fruit in allFruits"
:key="fruit"
>
{{ fruit }}
</h2>
</div>
<div style="height: 150rem"></div>
</div>
</template>
<script>
export default {
data() {
return {
allFruits: [
'Apples',
'Bananas',
'Oranges',
'Grapes',
'Strawberries',
'Blueberries',
'Pineapples',
'Mangoes',
'Kiwis',
'Watermelons',
],
};
},
mounted() {
this.scrollToLastFruit();
},
methods: {
scrollToLastFruit() {
const lastChildElement =
this.$refs.fruitsContainer.lastElementChild;
lastChildElement?.scrollIntoView({
behavior: 'smooth',
});
},
},
};
</script>
We removed the buttons to focus on the scroll after render.
Key takeaways:
- To scroll to the bottom of a div element in Vue.js, create a bottom element and set a ref on it.
Then use thescrollIntoView()
method on the ref to scroll down to the bottom element. - Set the
behavior
option to'smooth'
for animated scrolling. - For dynamically changing lists, set the ref on the container element and use
lastElementChild
to scroll to the last item. - Use the
mounted
hook to scroll to the bottom immediately after rendering.