CSS Media Queries are great. They allow you to change the styles of your components based on the size of the browser viewport. But they’re not always what you need. Sometimes you want to change your components’ styles based on the width of the components themselves, not the width of the window. Now, you could wait until CSS Element Queries finally make it into some finalized spec and get shipped in evergreen browsers, but there’s a much easier solution for Vue.js components that requires far less waiting: vue-responsive-component.
This guide assumes you have a Vue.js project already set up. If not, go ahead and start a new Vue project using vue-cli 3.0 and the default options. $ vue create my-new-project
and hitting enter a couple times should be sufficient.
vue-responsive-components
is a library that uses ResizeObserver (through a MutationObserver-based polyfill) to performantly determine when an element resizes. Go ahead and grab the library now:
$ npm install --save vue-responsive-components
Let’s go ahead and create a file called Responsive.vue
in our components directory. Yes, it’s about the most creative name I could think of.
<template>
<!--
v-responsive takes a set of objects
where the keys are class names and the values are
functions that take an element and return a boolean.
If the functions return true, then the classes will be applied.
In this case, if the component is less than 800 pixels wide,
the `small` class will be applied.
If the component is less than 400 pixels wide, both the `small`
and `tiny` classes will be applied.
-->
<div class="responsive-component" v-responsive="{
tiny: el => el.width < 400,
small: el => el.width < 800
}">
</div>
</template>
<script>
import { ResponsiveDirective } from "vue-responsive-components"
export default {
directives: {
responsive: ResponsiveDirective
}
}
</script>
<style scoped>
.responsive-component {
height: 200px;
background: red;
}
/* Applied when the component is less than 800px wide. */
.responsive-component.small {
background: green;
}
/* Applied when the component is less than 400px wide. */
.responsive-component.tiny {
background: blue;
}
</style>
Alright, so this is just about the world’s most boring component. It will just be a big red box, unless the element size is less than 800 pixels, in which case it will be a green box, if it gets any smaller, say, 400 pixels, it will be a blue box. Yippie.
Of course, since each of those queries takes a function as an argument, you can do far more advanced things with them.
So… How do we test our component?
Go ahead and open App.vue
(or whichever component you wish to embed the responsive component inside)
<template>
<!--
This gives us convenient resize handles to shrink and resize
the parent of the responsive component.
-->
<div id="app" style="resize: horizontal; overflow: hidden;">
<Responsive></Responsive>
</div>
</template>
<script>
import Responsive from './components/Responsive.vue'
export default {
components: {
Responsive
}
}
</script>
You should now find that your colored box componenty-thingy will change color when you resize the parent component.
This could be used for all sorts of things! List cards that dynamically adapt to their environment regardless of their layout, and more! Use your imagination!
For more information about vue-responsive-components, take a look at the official docs.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!