It seems that the task you are attempting is not a simple one. Inline style tags do not support media queries, making it a bit challenging.
The specification states:
The value of the style attribute must match the syntax of the contents of a CSS declaration block
Possible Solution 1:
This solution might be straightforward, although it may not align entirely with your requirements.
This method involves using img
elements and toggling their display using CSS.
<template>
<div>
<img class="image--sm" :src="src.sm" />
<img class="image--md" :src="src.md" />
<img class="image--lg" :src="src.lg" />
</div>
</template>
<script>
export default {
props: {
src: Object
}
}
</script>
<style>
.image--md,
.image--lg {
display: none;
}
@media (min-width: 400px) {
.image--sm {
display: none;
}
.image--md {
display: block;
}
}
@media (min-width: 600px) {
.image--md {
display: none;
}
.image--lg {
display: block;
}
}
</style>
Example: https://jsfiddle.net/h3c5og08/1/
Possible Solution 2:
If using image tags doesn't achieve the desired outcome, this alternative approach involves injecting CSS content to adjust background images dynamically.
In Vue templates, inserting style tags directly is not recommended as it goes against the framework's design principles, which focus on mapping state to UI without side-effects.
Templates should only be responsible for mapping the state to the UI. Avoid placing tags with side-effects in your templates, such as , as they will not be parsed.
While declarative styling in templates is restricted, JS can be utilized within the mounted hook of a component to apply targeted dynamic styles.
To confine dynamic styles to the element, use the internal id of the component (this._uid
) to scope the CSS properties.
<template>
<div class="image" :data-style-scope="_uid">
</div>
</template>
Create a computed property to generate the appropriate styles based on the data, ensuring to keep it limited to dynamic values only.
css () {
const selector = `.image[data-style-scope="${this._uid}"]`
const img = val => `${selector} { background-image: url("${val}"); }`
const sm = img(this.sm)
const md = img(this.md)
const lg = img(this.lg)
return `
${sm}
@media (min-width: 200px) { ${md} }
@media (min-width: 300px) { ${lg} }
`
}
Utilize the generated string from the css
computed property to create a style tag during mount. Then, watch changes to the computed property for updates.
Remember to clean up by removing the added style node before destroying the component.
{
data () {
return {
// Reference data properties
style: null,
styleRef: null
}
},
mounted () {
let style = document.createElement('style')
style.type = "text/css"
style.appendChild(document.createTextNode(''))
this.styleRef = style
this.style = style.childNodes[0]
this.style.textContent = this.css
document.head.appendChild(style)
},
beforeDestroy () {
this.style.parentElement.removeChild(this.style)
},
computed: {
css () {
// ...
}
},
watch: {
css (value) {
this.style.textContent = this.css
}
}
}
Working Example: https://jsfiddle.net/bLkc51Lz/4/