Utilizing Media Queries with Dynamic Vue Properties

On one of my website pages, I always have a Div element with a Background Image that changes based on Media Queries (for example, I fetch a smaller resolution from my CDN on mobile phones).

However, since I retrieve the Image URL on Page Load, I need to set it in CSS. This would work fine for a computed Style property, but those do not support Media Queries.

So far, the only solution I have found is using a Resize Event Listener, but I would prefer a cleaner solution.

Here is an example of how it looks in CSS with a predefined URL:

/* Custom, iPhone Retina */ 
@media only screen and (min-width : 320px) {
  .image {
        background: linear-gradient(rgba(255, 255, 255, 0.0), rgba(0, 0, 0, 0.95)), url("https://res.cloudinary.com/.../image/upload/c_scale,w_900/v.../3.jpg") no-repeat center;
        background: -webkit-linear-gradient(rgba(255, 255, 255, 0.0), rgba(0, 0, 0, 0.95)), url("https://res.cloudinary.com/.../image/upload/c_scale,w_900/v.../3.jpg") no-repeat center;
      }
  }

/* Extra Small Devices, Phones */ 
@media only screen and (min-width : 480px) {
  .image {
        background: linear-gradient(rgba(255, 255, 255, 0.0), rgba(0, 0, 0, 0.95)), url("https://res.cloudinary.com/.../image/upload/c_scale,w_1300/v.../3.jpg") no-repeat center;
        background: -webkit-linear-gradient(rgba(255, 255, 255, 0.0), rgba(0, 0, 0, 0.95)), url("https://res.cloudinary.com/.../image/upload/c_scale,w_1300/v.../3.jp"") no-repeat center;
      }
  }

Answer №1

An effective solution that comes to mind is to store the window width when the page loads and then dynamically add a class based on that value. Check out more information on this link.

data() {
   return {
      deviceWidth: 0
   }
}

Assign the window width on component mount

created() {
   this.deviceWidth = window.innerWidth;
}

Then in your template

// manage different screen sizes
<element 
   :class="{'image-ios': deviceWidth < 480, 'image-small': deviceWidth >= 480}"></element>

It's important to note that you won't require a resize listener since the screen width at the time of loading will be sufficient for most scenarios, especially on mobile devices.

Answer №2

Make sure to include your assets in the build output. Utilize Webpack to handle path creation dynamically instead of hardcoding them.

If that's not feasible, consider using CSS image-set for defining responsive images beyond media queries. Keep in mind, though, that browser support may be limited.

Alternatively, leverage the srcset attribute in HTML and show/hide the element based on media queries.

-- Edit:

Don't forget that you can bind styles directly in the VUE.js template using v-bind:style. Check out an example here. This updates the style block compiled during build rather than creating inline "computed" styles.

-- Edit #2

Try using VUE to set a CSS Variable like --backgroundImage, which can then be utilized within media queries in your CSS. Check out a helpful Codepen example.

CSS

:root {
  --backgroundImage: 'blank.png';
}

div {
  background-image: var(--backgroundImage);
}

VUE

watch: {
    img(val){
    element.style.setProperty('--backgroundImage', val)
    }
}

Answer №3

To manage the desired value, utilize the matchMedia function. This enables browser engineers to enhance screen resize calculations effectively.

<script setup>
import { ref, computed, onUnmounted, onMounted} from "vue";

const mediaQuery = window.matchMedia('(min-width : 480px)');
const isScreenLarge = ref(mediaQuery.matches)

const update = (event) => (isScreenLarge.value = event.matches);
onMounted(() => mediaQuery.addEventListener("change", update));
onUnmounted(() => mediaQuery.removeEventListener("change", update));

const background = computed(() => isScreenLarge.value ? 'large.jpg' : 'small.jpg';
</script>

<template>
<div>some content</div>
</template>

<style scoped>
div {
  background: v-bind(background);
}
</style>

For more flexibility, consider constructing a composable to handle this task in various sections of your application.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is a sleek method for including a key and value pair to an object using an array?

In a project using angular2/typescript, I am working with an array of objects that contain key/value pairs from a database. These values are then displayed in a table on the UI using ag-grid-ng2. The table headers are dynamic and set in the database. One ...

What could be causing my grid-area properties to not take effect?

I'm attempting to create a basic structure with a header in the top row, menu and content in the middle row, and footer at the bottom. Here is what I have so far: body { color: white; } .container { background: cyan; display: grid; ...

Mobile-exclusive carousel feature

I am currently working on a project where I need to create a carousel specifically designed for mobile devices. I want the carousel to display only one image at a time on screens with a resolution lower than 650px, while on larger screens, a standard grid ...

The form submission did not yield any results

function calculateCost() { var projectorCost=0,price=0,quantity=0,discountPrice=0,totalCost=0; var modelName=document.getElementById('projectormodel').value; var quantity=document.getElementById('q ...

Sharing a Promise between Two Service Calls within Angular

Currently, I am making a service call to the backend to save an object and expecting a number to be returned via a promise. Here is how the call looks: saveTcTemplate(item: ITermsConditionsTemplate): ng.IPromise<number> { item.modifiedDa ...

The 'gulp-jade' plugin seems to be malfunctioning and failing to properly compile jade files into HTML documents

Currently, I am immersed in a project where I rely on using gulp. My main objective is to compile the jade files I create (found in the _jadefiles folder) and have them output as .html files in the _includes folder within my project. The current list of t ...

Is there a way to modify the Java class name to consist of two separate words?

(Edited) I am completely new to android app development. My question is: How can I rename a java class with two words instead of one? My main menu consists of 3 options, each linked to a java class: public class Menu extends ListActivity{ String cla ...

Tips for resizing mesh along the global axis

Have you ever used an online 3D editor that allows you to manipulate individual meshes by moving, scaling, and rotating them? This editor utilizes custom transform controls inspired by the TransformControls code from three.js. Here is a snippet of code fro ...

Hero Sticky Transition with 100vhDivElement

My code is giving me some trouble. I want the div with text to stay at the bottom of the hero section with a transparent background. When that div reaches the top, it should stick with a black background. The issue is that I have set it in the javascript v ...

Attaching identical class and event handlers to numerous dynamically created elements

I am facing a challenge with the following HTML structure: <a href="#" @click.prevent="toggleClass">Show/Hide</a><br> <li :class="{myClass: showItems}">Item 1</li> <a href="#" @click.prevent="toggleClass">Show/Hide< ...

Implementing a Slide animation in React

I am currently working on a carousel feature that includes two buttons, Next and Previous. When the user clicks on Next, I want the carousel to slide from left to right, and when they click on Previous, it should slide from right to left. One important not ...

Remove the dropdown menu in real time, ensuring that only the most recent one is

Although the example may seem unusual, I am deliberately recreating a real problem to find a solution. When I click on a button, it generates 3 dynamic dropdowns based on a list of animals. My issue is that I want to delete a selected item, but it always ...

Descending through layers of a flattened array of objects

I've been diving into the world of array of objects and have successfully flattened them. Now I'm faced with the challenge of nesting them based on unique values at different levels. Currently, I'm using the reduce method to achieve this, bu ...

Is there a way to uncheck a checkbox by clicking on a link?

Just have a single checkbox for toggling: <label><input type="checkbox" name="myfield" id="myfield" />&nbsp;&nbsp;Enable Sound</label> Users can click on it to turn sound on the site. I'm looking for a way to uncheck the ch ...

Converting a JavaScript dictionary into an array of documents: The ultimate guide

I have an object that looks like this: const obj = { "restaurant": 20, "hotel": 40, "travel": 60 } Is there a way to transform it into the format below? const newArray = [ { "category_name": "restaurant", "amount": 20 }, { "category_na ...

Employ a data or computed property that relies on the value of the prop. The prop will be changed

I'm trying to open a modal in Vue, but I keep getting this error message in the console from the navigator: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed ...

When placed within a setInterval loop, the event.clientY variable becomes inaccessible

I am working on a script to move an element around a web page, and I have encountered a problem. Whenever I try to put it in a loop using setInterval while the mouse is down and moving, I receive an error message stating 'Uncaught TypeError: Cannot re ...

Utilizing JQuery to modify CSS in a partial view

My layout includes a button and a dynamically filled div below it using ajax and a partial view. Here is the code related to the button: $(document).on('click', '.btn-release', function () { StartReleaseVersionEdit(); ReleaseV ...

Understanding Multiple Type Scenarios in React with Typescript

Code Demonstration: type PropsType = {top: number} | {bottom: number} // The function that moves something in one direction by a specific distance. function move(props: PropsType) { ... } Expected Usage: move({top: 100}) or move({bottom: 100}) Avoid us ...

Count the number of distinct values in an array of objects

Could you assist me with a JavaScript problem I'm experiencing? I have an array and need to extract the count key from the response. Here is a sample response: var events = [ ... I would like the array response to look like this: var events = [ ... ...