[jquery] $(window).width() not the same as media query

I am using Twitter Bootstrap on a project. As well as the default bootstrap styles I have also added some of my own

//My styles
@media (max-width: 767px)
{
    //CSS here
}

I am also using jQuery to change the order of certain elements on the page when the width of the viewport is less that 767px.

$(document).load($(window).bind("resize", checkPosition));

function checkPosition()
{
    if($(window).width() < 767)
    {
        $("#body-container .main-content").remove().insertBefore($("#body-container .left-sidebar"));
    } else {
        $("#body-container .main-content").remove().insertAfter($("#body-container .left-sidebar"));
    }
}

The problem I am having is that the width calculated by $(window).width() and the width calculated by the CSS doesn't seem to be the same. When $(window).width() returns 767 the css calculates it the viewport width as 751 so there seems to be a 16px different.

Does anyone know what is causing this and how I could solve the problem? People have suggested that the width of the scrollbar isn't being taken into considering and using $(window).innerWidth() < 751 is the way to go. However ideally I want to find a solution that calculates the width of the scrollbar and that is consistent with my media query (e.g where both conditions are checking against the value 767). Because surely not all browsers will have a scrollbar width of 16px?

This question is related to jquery css twitter-bootstrap media-queries

The answer is


Implementation slick slider and display different numbers of slides in the block depending on the resolution (jQuery)

   if(window.matchMedia('(max-width: 768px)').matches) {
      $('.view-id-hot_products .view-content').slick({
        infinite: true,
        slidesToShow: 3,
        slidesToScroll: 3,
        dots: true,
      });
    }

    if(window.matchMedia('(max-width: 1024px)').matches) {
      $('.view-id-hot_products .view-content').slick({
        infinite: true,
        slidesToShow: 4,
        slidesToScroll: 4,
        dots: true,
      });
    }

Here's a less involved trick to deal with media queries. Cross browser support is a bit limiting as it doesn't support mobile IE.

     if (window.matchMedia('(max-width: 694px)').matches)
    {
        //do desired changes
    }

See Mozilla documentation for more details.


The best cross-browser solution is to use Modernizr.mq

link: https://modernizr.com/docs/#mq

Modernizr.mq allows for you to programmatically check if the current browser window state matches a media query.

var query = Modernizr.mq('(min-width: 900px)');
if (query) {
   // the browser window is larger than 900px
}

Note The browser does not support media queries (e.g. old IE) mq will always return false.


if you want to check the width screen in the device every 1 second you can do

 setInterval(function() {
        if (window.matchMedia('(max-width: 767px)').matches) {
            alert('here')
        } else {
            alert('i am ')
        }
    }, 1000);

I was facing the same problem recently - also with Bootstrap 3.

Neither $.width() nor $.innerWidth() will work for you.

The best solution I came up with - and is specifically tailored to BS3 -
is to check the width of a .container element.

As you probably know how the .container element works,
it's the only element that will give you the current width set by BS css rules.

So it goes something like

bsContainerWidth = $("body").find('.container').width()
if (bsContainerWidth <= 768)
    console.log("mobile");
else if (bsContainerWidth <= 950)
    console.log("small");
else if (bsContainerWidth <= 1170)
    console.log("medium");
else
    console.log("large");

if(window.matchMedia('(max-width: 768px)').matches)
    {
        $(".article-item").text(function(i, text) {

            if (text.length >= 150) {
                text = text.substring(0, 250);
                var lastIndex = text.lastIndexOf(" ");     
                text = text.substring(0, lastIndex) + '...'; 
            }

            $(this).text(text);

        });

    }

yes, that's due to scrollbar. Right answer source: enter link description here

function viewport() {
    var e = window, a = 'inner';
    if (!('innerWidth' in window )) {
        a = 'client';
        e = document.documentElement || document.body;
    }
    return { width : e[ a+'Width' ] , height : e[ a+'Height' ] };
}

Check a CSS rule that the media query changes. This is guaranteed to always work.

http://www.fourfront.us/blog/jquery-window-width-and-media-queries

HTML:

<body>
    ...
    <div id="mobile-indicator"></div>
</body>

Javascript:

function isMobileWidth() {
    return $('#mobile-indicator').is(':visible');
}

CSS:

#mobile-indicator {
    display: none;
}

@media (max-width: 767px) {
    #mobile-indicator {
        display: block;
    }
}

Here is an alternative to the methods mentioned earlier that rely on changing something via CSS and reading it via Javascript. This method does not need window.matchMedia or Modernizr. It also needs no extra HTML element. It works by using a HTML pseudo-element to 'store' breakpoint information:

body:after {
  visibility: hidden;
  height: 0;
  font-size: 0;
}

@media (min-width: 20em) {
  body:after {
    content: "mobile";
  }
}

@media (min-width: 48em) {
  body:after {
    content: "tablet";
  }
}

@media (min-width: 64em) {
  body:after {
    content: "desktop";
  }
}

I used body as an example, you can use any HTML element for this. You can add any string or number you want into the content of the pseudo-element. Doesn't have to be 'mobile' and so on.

Now we can read this information from Javascript in the following way:

var breakpoint = window.getComputedStyle(document.querySelector('body'), ':after').getPropertyValue('content').replace(/"/g,'');

if (breakpoint === 'mobile') {
    doSomething();
}

This way we are always sure that the breakpoint information is correct, since it is coming directly from CSS and we don't have to hassle with getting the right screen-width via Javascript.


try this

getData(){
    if(window.innerWidth <= 768) {
      alert('mobile view')
      return;
    }

   //else function will work

    let body= {
      "key" : 'keyValue'
    }
    this.dataService.getData(body).subscribe(
      (data: any) => {
        this.myData = data
      }
    )
}

It's maybe a better practice not to JS-scope the document's width but some sort of change made by css @media query. With this method you can be sure the JQuery function and css change happens at the same time.

css:

#isthin {
    display: inline-block;
    content: '';
    width: 1px;
    height: 1px;
    overflow: hidden;
}

@media only screen and (max-width: 990px) {
    #isthin {
        display: none;
    }
}

jquery:

$(window).ready(function(){
    isntMobile = $('#isthin').is(":visible");
    ...
});

$(window).resize(function(){
    isntMobile = $('#isthin').is(":visible");
    ...
});

Workaround that always works and is synced with CSS media queries.

Add a div to body

<body>
    ...
    <div class='check-media'></div>
    ...
</body>

Add style and change them by entering into specific media query

.check-media{
    display:none;
    width:0;
}
@media screen and (max-width: 768px) {
    .check-media{
         width:768px;
    }
    ...
}

Then in JS check style that you are changing by entering into media query

if($('.check-media').width() == 768){
    console.log('You are in (max-width: 768px)');
}else{
    console.log('You are out of (max-width: 768px)');
}

So generally you can check any style that is being changed by entering into specific media query.


Try this

if (document.documentElement.clientWidth < 767) {
   // scripts
}

For More Reference click here


What i do ;

<body>
<script>
function getWidth(){
return Math.max(document.body.scrollWidth,
document.documentElement.scrollWidth,
document.body.offsetWidth,
document.documentElement.offsetWidth,
document.documentElement.clientWidth);
}
var aWidth=getWidth();
</script>
...

and call aWidth variable anywhere afterwards.

You need to put the getWidth() up in your document body to make sure that the scrollbar width is counted, else scrollbar width of the browser subtracted from getWidth().


It may be due to scrollbar, use innerWidth instead of width like

if($(window).innerWidth() <= 751) {
   $("#body-container .main-content").remove()
                                .insertBefore($("#body-container .left-sidebar"));
} else {
   $("#body-container .main-content").remove()
                                .insertAfter($("#body-container .left-sidebar"));
}

Also you can get the viewport like

function viewport() {
    var e = window, a = 'inner';
    if (!('innerWidth' in window )) {
        a = 'client';
        e = document.documentElement || document.body;
    }
    return { width : e[ a+'Width' ] , height : e[ a+'Height' ] };
}

Above code Source


Use

window.innerWidth

This solved my problem


Javascript provides more than one method to check the viewport width. As you noticed, innerWidth doesn't include the toolbar width, and toolbar widths will differ across systems. There is also the outerWidth option, which will include the toolbar width. The Mozilla Javascript API states:

Window.outerWidth gets the width of the outside of the browser window. It represents the width of the whole browser window including sidebar (if expanded), window chrome and window resizing borders/handles.

The state of javascript is such that one cannot rely on a specific meaning for outerWidth in every browser on every platform.

outerWidth is not well supported on older mobile browsers, though it enjoys support across major desktop browsers and most newer smart phone browsers.

As ausi pointed out, matchMedia would be a great choice as CSS is better standardised (matchMedia uses JS to read the viewport values detected by CSS). But even with accepted standards, retarded browsers still exist that ignore them (IE < 10 in this case, which makes matchMedia not very useful at least until XP dies).

In summary, if you are only developing for desktop browsers and newer mobile browsers, outerWidth should give you what you are looking for, with some caveats.


Examples related to jquery

How to make a variable accessible outside a function? Jquery assiging class to th in a table Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Getting all files in directory with ajax Bootstrap 4 multiselect dropdown Cross-Origin Read Blocking (CORB) bootstrap 4 file input doesn't show the file name Jquery AJAX: No 'Access-Control-Allow-Origin' header is present on the requested resource how to remove json object key and value.?

Examples related to css

need to add a class to an element Using Lato fonts in my css (@font-face) Please help me convert this script to a simple image slider Why there is this "clear" class before footer? How to set width of mat-table column in angular? Center content vertically on Vuetify bootstrap 4 file input doesn't show the file name Bootstrap 4: responsive sidebar menu to top navbar Stylesheet not loaded because of MIME-type Force flex item to span full row width

Examples related to twitter-bootstrap

Bootstrap 4: responsive sidebar menu to top navbar CSS class for pointer cursor How to install popper.js with Bootstrap 4? Change arrow colors in Bootstraps carousel Search input with an icon Bootstrap 4 bootstrap 4 responsive utilities visible / hidden xs sm lg not working bootstrap.min.js:6 Uncaught Error: Bootstrap dropdown require Popper.js Bootstrap 4 - Inline List? Bootstrap 4, how to make a col have a height of 100%? Bootstrap 4: Multilevel Dropdown Inside Navigation

Examples related to media-queries

iPhone X / 8 / 8 Plus CSS media queries What is correct media query for IPad Pro? How can I detect Internet Explorer (IE) and Microsoft Edge using JavaScript? CSS media query to target only iOS devices How to set portrait and landscape media queries in css? iPhone 6 and 6 Plus Media Queries Responsive design with media query : screen size? Bootstrap 3 breakpoints and media queries $(window).width() not the same as media query How to make responsive table