CSS @media rule in JavaScript

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

内容简介: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!


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

查看所有标签

猜你喜欢:

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

Ruby on Rails敏捷开发最佳实践

Ruby on Rails敏捷开发最佳实践

李刚 / 电子工业出版社 / 2008-4 / 79.80元

《Ruby on Rails敏捷开发最佳实践》适用于正在使用Ruby On Rails进行应用开发的开发人员、渴望了解Ruby On Rails框架的开发人员,尤其适合有初步的Java EE开发经验,想从Java EE平台过渡到Ruby On Rails开发平台的开发者。 Ruby On Rails框架一经推出,立即引起B/S结构应用开发领域革命性的变化:开发者无需理会架构,只需要按Rail......一起来看看 《Ruby on Rails敏捷开发最佳实践》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

URL 编码/解码
URL 编码/解码

URL 编码/解码

MD5 加密
MD5 加密

MD5 加密工具