v3.0.1
npm install mq-js --save
This documentation is best viewed on a Desktop computer or laptop for the sake of viewing the examples at all screen sizes.
mq-js was inspired by the mq-scss Sass mixin. I wanted to use media queries in JavaScript in a similar sort of way to how I was using media queries in my Sass code.
This documentation assumes that you have the ability to use ES6 JavaScript syntax in your project. mq-js will work in environments that don't support es6 JavaScript syntax however the syntax will be different to what is documented. View the full documentation for ES5 (IE friendly) examples.
If you are new to Node and npm, read this beginners guide on how to get set up. You will also need JavaScript bundling software such as Browserify, Rollup, or Webpack integrated into your build process for mq-js to work.
Once that is all set up, install mq-js using npm.
npm install mq-js --save
Now, create this simple mq.js file to set up your website breakpoints.
Now import the mq
variable into your main/component JavaScript file.
Note: mq.max
is inclusive of the given screen size and mq.min
is exclusive of the given screen size. This is to avoid any potential 1px overlap issues where both statements return true at the same time. It is also designed to align with how mq-scss works.
It is also worth noting that you can save your breakpoints into a json file and import that instead. This can make the breakpoints a bit more portable.
If you are using mq-scss in your project and have enabled em-conversions, you will need to enable them in mq-js as well.
In the following example, the button will only turn green if you click it when the browser window is at a maximum width of 980px wide (ie. at or below the "medium" breakpoint).
To help you figure out when the button is able to be clicked, the border of the button will turn green when it is clickable.
As you can see, you can easily access the "medium"
breakpoint that you defined earlier by simply parsing a string as the breakpoint value. There is no need to import the breakpoints
variable from the mq.js
file to use the "medium"
breakpoint.
You can also use it in an if statement sort of format as shown below. All mq-js functions can be used in this if
statement format. For the sake of brevity though, I'm just showing the callback
format in the rest of these examples.
Notice that using the callback method gives you access to the screen size data at the time the button is clicked. The if statement format does not (or at least not without custom code).
Also notice that I'm not binding and unbinding the click function on screen resize. By placing mq
inside the click function, it behaves very similarly to how media queries behave in css.
One last thing. If you prefer to explicitly state that the media query is targeting "width", mq.max
can also be written as mq.maxWidth
. It has identical functionality, it's just personal preference.
In the following example, the button will only turn green if you click it when the browser window is at a minimum width of 981px wide (ie. above the "medium" breakpoint).
You might be wondering why 981px instead of 980px. While mq.max
is inclusive of the breakpoint value, mq.min
is exclusive of the breakpoint value. This serves two important purposes:
It prevents bugs from occurring in that 1px sweet spot where both would otherwise return true.
It aligns with how mq-scss handles min and max width to prevent odd bugs where JavaScript is firing but the styles aren't there to support it (or vice versa).
Also, like with mq.max
, it can be written like mq.minWidth
instead if you prefer.
mq.inside
works in much the same way as it does in mq-scss.
Instead of stating one value then calling the function, you state two values then call the function.
You can state the breakpoint values in any order but the function needs to be called last (if at all). The function will be triggered if the screen width sits between the two breakpoint values when it is called.
The smaller value always gets +1 for consistency with the mq-scss mixin and to prevent 1px overlap issues.
It can also be written as mq.insideWidth
if you prefer.
mq.outside
does what you would expect. It is the opposite of mq.inside
. It will only fire if the screen width is outside of the two breakpoint values.
It can also be written as mq.outsideWidth
if you prefer.
One of the major features found in mq-scss is that you can easily create meaningful media query variables.
Here is how to do a similar sort of thing in mq-js:
Just because you have access to the breakpoint values, it doesn't mean that you have to use them. mq-js still works if you just parse solid numbers into it.
Remember that if you use mq.min
it will be like adding 1 pixel to the value that you provide.
What if you only want to tweak one of the normal breakpoint values so that it is just a few pixels larger than the base break point? That is when it is useful to import the breakpoint
variable.
In the following example, I'm importing the breakpoints variable and using it to add 30px to the "medium"
breakpoint.
mq-js is just a simple function that checks the current window size when it is called. It doesn't do anything fancy when you resize the window. With a little extra code though, you can easily make it run on window resize.
The following example uses Debounce to prevent the function from firing until the window has finished resizing. This improves performance and can avoid odd bugs from occurring.
The button will activate when the screen is at the correct width and deactivate when not. Clicking the button does nothing.
As of version 2.0.0, mq-js supports various plugins that allow it to fully replicate everything that mq-scss can do.
These plugins can be loaded from the mq.js file to avoid the need for loading them every time you wish to use them.
Alternatively, you can load all of the plugins in one statement by simply importing mq-js/ultimate
;
This one is pretty straight forward, it works in pretty much the same way as min
, max
, inside
and outside
except it targets height instead of width. Available functions are mq.minHeight
, mq.maxHeight
, mq.insideHeight
and mq.outsideHeight
.
The height plugin is the main reason why I have provided the alternate names for the width based commands. When you are combining height and width media queries in an if statement it can be easier to read mq.minWidth(800) && mq.minHeight(400)
than mq.min(800) && mq.minHeight(400)
.
This one is even simpler. One little gotcha is that there is no "square" orientation type in css. There is only portrait and landscape types. Square screen types seem to fall under portrait
in css so I've made square screen types fall under portrait
in mq-js as well.
This one is a little more complex. The ratio's for mq-js are always formatted as [width] / [height]
. Ratios work off of width more so than height in CSS so mq-js does as well. So a ratio of 2 / 3
is counted as being larger than a ratio of 1 / 3
since 2 / 3
is wider than 1 / 3
.
With this in mind, the ratio plugin provides you with all the typical ranges but for ratios.
You can also provide the ratio as a string instead.
This plugin is a bit different to the others. The primary purpose of this plugin is to fire off functions when a media query either enters or leaves a defined screen size range.
It takes a function that returns an mq-js screen-check result as it's first parameter and a callback function as it's second parameter. It will then call the callback function every time the screen-check result changes from true
to false
or false
to true
.
mq-js has a lot of complicated functionality that I needed to be able to test effectively. Doing it with demos by eye wasn't cutting it.
I built a custom unit testing framework to do this.
I needed the testing framework to do the following:
I'm pretty happy with the testing framework that I came up with. If you would like to see it in action, open Firefox and press the button below.
To view the detailed test results, click on one of the windows that appear and press the F12 key to bring up dev tools. Click on the "console" tab to view the test results.
The tests don't work properly in Chrome because window.outerWidth - window.innerWidth
does not have a stable value in Chrome.