Reputation: 117
I've noticed that the JavaScript media query seems to take effect after the CSS equivalent ones.
I've created two examples demonstrating what I'm talking about:
HTML:
<div class="foo">
bar
</div>
CSS:
.foo {
background-color: orange;
}
@media(max-width: 300px) {
.foo {
background-color: blue;
transform: translateY(100px);
transition: all 300ms ease-out;
}
}
jsbin link is: here
Here transition happens, when screen width becomes 300px or less from something bigger.
But when creating responsive design such transition can be annoying. I'm trying to get rid of them. The following Javascript and CSS solves the problem, but I'm not sure that is it reliable or not.
HTML
<div class="foo">
bar
</div>
<button>toggle translateY to 200px</button>
CSS
.transition {
transition: all 300ms ease-out;
}
.foo {
background-color: orange;
}
@media(max-width: 300px) {
.foo {
background-color: blue;
transform: translateY(100px);
}
}
.translateY {
transform: translateY(200px);
}
JavaScript:
const w = window.matchMedia("(max-width: 300px)");
const div = document.querySelector(".foo");
const button = document.querySelector('button');
function fun(e) {
if (e.matches) {
div.classList.add('transition');
} else {
div.classList.remove('transition');
}
}
// for initial screen width change detection
fun(w);
w.addEventListener('change', fun);
button.onclick = function() {
div.classList.toggle('translateY');
}
jsbin link is here
Here it seems the following thing happens in order when screen width becomes 300px or less from something bigger:
transform: translateY(100px)
is rendered in a flash.transition
class is added to div
by JavaScript.By clicking the button, it makes sure that the transition
class is working.
This example doesn't cause any unwanted transition as screen size becomes 300px or less from something bigger.
So it seems that any CSS media query is rendered before JavaScript equivalent media queries. I think it's a good thing. But I'm not sure, is it the standard well supported behavior? Is it safe to build logic based on this behavior?
Upvotes: 1
Views: 1182
Reputation: 196286
This is part of the CSS specificity
Inline styles added to an element (e.g.,
style="font-weight: bold;"
) always overwrite any styles in external stylesheets, and thus can be thought of as having the highest specificity.
The javascript code you posted will add inline styles (through the style
property of the element) and thus has the highest specificity. (it has nothing to do with the js media query, it just has to do with how you apply the style in the JS to the element)
Update after the comments/update in question
Again it depends on when you load the CSS and the JS. If you first include the CSS file, since it is a render blocking resource, it will be applied first.
I am not sure though, why don't you apply all the rules through CSS media queries ?
const div = document.querySelector(".foo");
const button = document.querySelector('button');
button.onclick = function() {
div.classList.toggle('translateY');
}
.foo {
background-color: orange;
}
@media(max-width: 300px) {
.foo {
background-color: blue;
transform: translateY(100px);
transition: all 300ms ease-out;
}
}
.translateY {
transform: translateY(200px);
}
<div class="foo">
bar
</div>
<button>toggle translateY to 200px</button>
Upvotes: 3