CSS @media rule in JavaScript

栏目: IT技术 · 发布时间: 6年前

内容简介:JavaScript is in this very special place when it comes to web technologies. It either provides functionalities that can't be found anywhere else or can easily replace other web languages - HTML and CSS that is.While most JS developers probably know of the

JavaScript is in this very special place when it comes to web technologies. It either provides functionalities that can't be found anywhere else or can easily replace other web languages - HTML and CSS that is.

While most JS developers probably know of the DOM API and all the UI libraries and frameworks built on top of it, the knowledge of "CSS API" (it's not technically called that way, but you get the point), is less common.

I've already covered the API you can use to create your CSS stylesheets right from JS inmy previous article. Instead, today I'd like to focus on something more advanced - on how to control your @media CSS rules - you've guessed it - in JS!

CSS API recap

Let's start with a very quick recap of the previous article.

You can access a stylesheet in 2 ways - either through the sheet property of a <style> tag DOM element or as one of the document.styleSheets indexed collection's items. In both cases, the result is an object implementing the CSSStyleSheet interface that then gives you further access to control methods like insertRule() and removeRule() , as well as properties like cssRules .

const style = document.createElement("style");
document.head.appendChild(style);

const styleSheet = style.sheet;
const ruleIndex = styleSheet.insertRule(".example { background-color: red }");
const rule = styleSheet.cssRules[ruleIndex];

The insertRule() method returns the index at which the new CSS rule was inserted. This can then be used to access the rule object implementing the CSSRule interface. And such an object, as expected, has some properties of its own - mainly used to configure and access the rule's data.

CSSRule

Now, here's where we slow down a little bit. That's because the CSSRule and its derivatives must be well-understood, to be able to create more complex JS-based stylesheets .

On its own - although you'll never see it that way - CSSRule has only a few properties. The most important ones are probably the cssText - holding your rule's textual CSS representation and the type - a constant value indicating the type of the given CSSRule .

// ...
rule.cssText; // ".example { background-color: red; }"

There are multiple types and thus derivatives of the CSSRule interface. The most common one - CSSStyleRule is responsible for rules like the one you see above. In addition to standard CSSRule properties, it also has some more interesting ones like selectorText - textual representation of the rule's CSS selector, and style - a CSSStyleDeclaration object, just like DOM element's inline styles you might be accustomed to.

// ...
rule.selectorText; // ".example"
rule.style.backgroundColor; // "red"
rule.style.backgroundColor = "green";
rule.style.backgroundColor; // "green"

As a nice bonus - did you know that you can change the style of your rule, altering it and all the elements it's applied to in real-time!?

CSSMediaRule

But all the different CSSRule s are not what you came here for - no. You've come for the CSS @media rule. And, as one might expect, it also has its reflection on the JavaScript side - this time in the form of the CSSMediaRule .

CSSMediaRule is that much interesting because of its deeper inheritance. Unlike simple CSSStyleRule that's a direct child of the CSSRule , CSSMediaRule additionally has CSSGroupingRule and CSSConditionRule (in the given order) as its parents.

This says a lot about the rule. The CSSGroupingRule is meant for the rules that contain nested rules within them, while CSSConditionRule means that they're applied only when a certain condition is met. Remember CSS syntax for a @media rule?

@media screen and (min-width: 900px) {
  .example {
    background-color: blue;
  }
}

Now, both of the CSSMediaRule parents add important properties and methods to it. Going from all the way up (directly below CSSRule itself) the CSSGroupingRule adds methods like insertRule() and deleteRule() as well as cssRules property to the party. Sounds familiar? That's because these are similar functionalities to what we saw earlier, all the very beginning with the CSSStyleSheet interface.

// ...
const mediaRuleText = `@media screen and (min-width: 900px) {
  .example {
    background-color: blue;
  }
}`;
const mediaRuleIndex = styleSheet.insertRule(ruleText);
const mediaRule = styleSheet.cssRules[mediaRuleIndex];

mediaRule.cssRules[0].selectorText; // ".example"
mediaRule.cssRules[0].style.backgroundColor; // "blue"

In our case, there's only 1 rule grouped by the CSSGroupingRule - a simple CSSStyleRule , which means that we've come a full circle.

Next up, we've got the CSSConditionRule which brings with it the conditionText property. This guy allows us to access the textual representation of the CSS condition. In our case it's:

mediaRule.conditionText; // "screen and (min-width: 900px)"

The CSSMediaRule also adds a property of its own - media - that's equal to an object implementing MediaList interface. Basically, a bit more advanced version of conditionText . It's not really important for anything so if you're interested, just check out the MDN docs.

The other way around

So, that pretty much wraps it up for the CSSMediaRule and related APIs. There are quite a few variations of CSSRule like this one, which when used together can lead to pretty impressive results. Dynamic, manageable CSS-in-JS libraries like my own Prototope with complex real-time updates are definitely possible.

But you might also say that these things are best for the CSS to deal with. And you'd be absolutely right - that's what CSS was designed for. But if so, maybe you'd be interested in something different?

What if I told you that there's a way to evaluate media queries right in JS? To know when e.g. a window has the desired width or height? Well, that's surely possible and all thanks to matchMedia()

matchMedia

So, matchMedia() is a method accessible directly on the window object (globally), that allows you to parse given media query and react to the changes in its activity.

const mediaQuery = matchMedia("screen and (min-width: 900px)");

matchMedia() returns what's called a MediaQueryList object. This guy provides you with everything you'd want when working with media queries. You've got the most important matches property to check whether the media query matches the current website's state, the media property to get back the provided media query string, and two addListener() and removeListener() methods to listen for the media query state changes.

mediaQuery.addListener(() => {
	mediaQuery.matches; // true or false
});
mediaQuery.media; // "screen and (min-width: 900px)"

Now, you cannot argue with the usefulness of this feature. Being able to check whether the certain media query applies is extremely helpful when dealing with any kind of JS-driven UI - take Masonry Grid for example. The matchMedia() way is much faster than any other similar solution (especially the one with constant resize even monitoring). And have I already said that it has great cross-browser support with up (or rather down) to IE 10!

Conclusion

With the CSS API and matchMedia() I think I've shown you an impressive side of JavaScript capabilities. I hope you've learned something new and will now be able to create all sorts of JS wonders - from simple JS-driven UI layouts to full-blown CSS-in-JS libraries.

For more web development guides and tutorials, follow me on Twitter , Facebook , or through my newsletter below. I've also got a YouTube channel (not very active recently, but I'm working on it), which you might want to check out and subscribe to. Thanks for reading this piece and I wish you happy coding!


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

游戏测试精通

游戏测试精通

舒尔茨 / 周学毛 / 清华大学出版社 / 2007-9 / 48.00元

《游戏测试精通》来自3位在游戏测试领域都有着极其丰富经验的专业人员,是亚马逊“五星级”畅销书,也是国内第一本专业级游戏测试经典之作,不仅内容全面、实例丰富,而且讲解透彻、可读性强,并提供多个资源下载和技术支持站点。现如今,游戏产业发展迅猛,游戏测试已成为游戏产品、游戏软件、游戏程序设计与开发不可或缺的环节。《游戏测试精通》主要揭示了如何将软件测试的专业方法运用到游戏产业中,全面涵盖了游戏测试的基本......一起来看看 《游戏测试精通》 这本书的介绍吧!

SHA 加密
SHA 加密

SHA 加密工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具