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?
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:I used
body
as an example, you can use any HTML element for this. You can add any string or number you want into thecontent
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:
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.
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.
See Mozilla documentation for more details.
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:
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.
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:
jquery:
Implementation slick slider and display different numbers of slides in the block depending on the resolution (jQuery)
If you don't have to support IE9 you can just use
window.matchMedia()
(MDN documentation).window.matchMedia
is fully consistent with the CSS media queries and the browser support is quite good: http://caniuse.com/#feat=matchmediaUPDATE:
If you have to support more browsers you can use Modernizr's mq method, it supports all browsers that understand media queries in CSS.