Due to difference between CSS media queries based on max-width and jQuery’s ‘$(window).width()‘ measurement (caused by the inconsistent ways in which browser media queries handle scrollbars), there is always a mismatch between ‘jQuery $(window).width()‘ and CSS3 Media Queries. Which in turn causes some ugly or unexpected behaviour by your responsive website.
The Issue:
Initially I was using the code below:
1 2 3 4 5 | $(window).resize(function(){ if ($(window).width() <= 767){ // do something here } }); |
When viewing the site in Firefox, I noticed a small difference in the width at which my media query and javascript were firing. The inconsistent treatment of vertical scrollbars in media query widths causes a small difference between browsers in the actual window width when a media query fires, which in turn causes media query and jQuery width measurements to not match in some popular browsers: Firefox, IE, and Opera. Any appearance of the responsive website was broken. So after some googling I made a solution which is better than detecting native window/device screen size.
Use jQuery to test for a changed CSS property, rather than the browser width
jQuery functions with CSS media queries
Rather than the measuring the screen width on resize of the window, I check for a css rule that is changed by the media query. This way, regardless of the how the browser treats the scrollbar, the media query will fire at the same time.
Suppose that body has a ‘padding-top: 140px‘ CSS rule for mobile devices and it’s ‘70px‘ for other large devices (ipad, tablet, desktop), I check for the change in rule.
jQuery
1 2 3 4 5 6 7 8 9 | $(window).resize(function(){ if ($("body").css("padding-top") == "70px" ){ // your code here } else{ // your code here for small screen device } }); |
CSS media queries
1 2 3 4 5 6 7 8 9 | body, my-class { padding-top: 70px; } @media(max-width:767px) { body, my-class { padding-top: 140px; } } |
This is the way you can run jQuery functions with CSS media queries for responsive website. And as a note when you initially load the page on a mobile device, there doesn’t actual browser resize happen. So to use this idea you can place the code inside another function and call it either on load as well as browser resize.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | $(document).ready(function() { function ele_adjust() { if ($(".my-class").css("padding-top") == "70px" ) { $('#tag-title').removeClass('header6').addClass('header1'); $('#hash-btn').addClass('btn-group-lg'); } else { $('#tag-title').removeClass('header1').addClass('header6'); $('#hash-btn').removeClass('btn-group-lg'); } }; ele_adjust(); $(window).resize(ele_adjust); }); |
Here you can see that we are defining desired class changes inside a function and the function is called itself on DOM ready as well as whenever window resize takes place.