In-depth discussion of CSS Feature Detection @ supports and Modernizr, @ supportsmodernizr
What is CSS feature detection? We know that as front-end technologies are changing with each passing day, new technologies and attributes are emerging one after another. The CSS layer is no exception.
Some new attributes can greatly improve the user experience and reduce the workload of engineers, and in the current front-end atmosphere:
- Many experimental features have not become a standard but are widely used;
- It is necessary to be compatible with multiple terminals and browsers, while the implementation of a new function by different browsers is similar;
In this context, we want to use new technologies to provide a better user experience, in addition, CSS feature detection is designed to ensure the basic experience of end users of earlier versions.
CSS feature detection is used to determine whether the current browser supports a feature based on different browser terminals. With CSS feature detection, we can use new technologies in the browser environment that supports the current features, but do not support some rollback mechanisms.
This article mainly introduces two methods for detecting CSS features:
CSS
@supports
Traditional CSS feature detection is implemented through javascript, but native CSS can be implemented in the future.
CSS@supports
The CSS syntax is used to implement feature detection, and the CSS statements that you want to implement are written in the internal CSS block.
Syntax:
@supports <supports_condition> { /* specific rules */}
For example:
div {position: fixed;}@supports (position:sticky) { div { position:sticky; }}
In the above example,position: sticky
It is a new attribute of position, which is used to achieve viscous layout. It can easily implement some la s that previously required javascript (I understand the details ), however, it is currently only supported in the-webkit-kernel.
The above statement definesposition: fixed
, Followed by the following sentence@supports (position:sticky)
This is the content in the feature detection brackets. If the current browser supports@supports
Syntax, and supportsposition:sticky
Syntax, then the div is setposition:sticky
.
We can see that,@supports
The core of the syntax lies in this sentence:@supports (...) { }
The parentheses are a CSS expression. If the browser determines that the expressions in the brackets are valid, the CSS expressions in the brackets will be rendered. In addition to the most common usage, you can also use the following keywords:
@supports not
&&
@supports and
&&
@supports or
@supports not
-- Non
The not operator can be placed before any expression to generate a new expression. The new expression is the negative value of the original expression. Let's look at an example:
@supports not (background: linear-gradient(90deg, red, yellow)) { div { background: red; }}
Because the not keyword is added, it is opposite to the previous example. If it is detected that the browser does not support linear gradientbackground: linear-gradient(90deg, red, yellow)
To set the div color to red.background: red
.
@supports and
-- And
This is easy to understand and make multiple judgments, similar to javascript's&&
Operator. Use the and operator to connect two original expressions. The generated expression is true only when the values of both original expressions are true. Otherwise, the generated expression is false.
Of course, and can be connected to any number of expressions. For example:
p { overflow: hidden; text-overflow: ellipsis;}@supports (display:-webkit-box) and (-webkit-line-clamp:2) and (-webkit-box-orient:vertical) { p { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }}
At the same time, the detection@supports (display:-webkit-box) and (-webkit-line-clamp:2) and (-webkit-box-orient:vertical)
Three CSS rules are set if they are supported at the same time. These three syntaxes must be supported by the browser at the same time. If the expression is true, it can be used to omit multiple rows:
Demo stamp me
@supports or
-- Or
Understood@supports and
, It is easy to understand@supports or
And javascript||
If one of the expressions is true, the generated expression is true. Example:
@supports (background:-webkit-linear-gradient(0deg, yellow, red)) or (background:linear-gradient(90deg, yellow, red)){ div { background:-webkit-linear-gradient(0deg, yellow, red); background:linear-gradient(90deg, yellow, red) }}
In the preceding example, only browser support is detected.background:-webkit-linear-gradient(0deg, yellow, red)
Or (or)background:linear-gradient(90deg, yellow, red)
Add a gradient to the div element.
Demo stamp me
Of course, keywordsnot
You can alsoand
Oror
Hybrid use. If you are interested, try it.
Can I use?
For compatibility, see Can I use first:
This is still a feature in the experiment. Although most browsers already support it, it still takes some time for mobile terminals to be compatible.
But we can start using it.@supports
Achieve progressive enhancement.
Progressive enhancement: builds pages for earlier browsers to ensure the most basic functions, then, improve the effect and interaction of advanced browsers and append the functions to provide a better user experience:
CSS. supports ()
Talked about@supports
, It is necessary to sayCSS.supports()
.
It is used@supports
In another form, we can use javascript to obtain support for CSS attributes.
You can open the console and enterCSS.supports
Try:
If you do not implement CSS. supports by yourself, output the above information, indicating that the browser supports@supports
The syntax is as follows:
CSS.supports('display', 'flex') // trueCSS.supports('position', 'sticky') // true
So what is its use? If your page needs to dynamically add new properties that you are not sure which browsers support, it may be useful. Also, it can be used with the modernizr we will talk about later.
Modernizr
The above describes the CSS Feature Detection. In the past, javascript was usually used for feature detection. Among them, modernizr was the most outstanding.
Modernizr is an open source javascript library. With nearly stars, we can see their excellence.
Let's take a look at the usage method. Suppose the page has referenced modernizr. The syntax is as follows:
// Listen to a test, give it a callbackModernizr. on ('testname', function (result) {if (result) {console. log ('the test passed! ');} Else {console. log ('the test failed! ') ;}}); // Or similar to CSS. supports () Modernizr. testAllProps ('background', 'linear-gradient (90deg, #888, # ccc) '); // true
For example, if we want to differentiate whether a div under the style browser supports gradient or not, there are the following CSS:
div { background: #aaa;}.linear-gradient div{ background: linear-gradient(90deg, #888, #ccc);}
Use Modernizr for determination. If gradient is supported, add.linear-gradient
Style. For example, jquery syntax is used:
if (Modernizr.testAllProps('background', 'linear-gradient(90deg, #888, #ccc)')) { $('html').addClass('linear-gradient');}
Demo stamp me
Of course, Modernizr has many other functions that can be used to flip through its APIs.
Feature Detection Principle
If the entire Modernizr library is too large to be introduced, the page does not support@supports
In fact, it is very convenient and simple to implement it with simple javascript.
To know how many CSS attributes the browser supports, try the following in the debugging window:
var root = document.documentElement; //HTMLfor(var key in root.style) { console.log(key);}
The screenshot above is only a small part of the image. If we want to check whether a property style is supported, we can check whether it exists in any element. style.root
Can be replaced with any element.
Of course, elements may havebackground
Attribute, but does not support specificlinear-gradinet()
Attribute Value. How can I check this time? You only need to assign a specific value to an element and then query whether the attribute value can be read.
Var root = document.doc umentElement; root. style. backgroundImage = 'linear-gradient (90deg, #888, # ccc) '; if (root. style. backgroundImage) {// supported} else {// not supported}
In the above Modernizr example, the javascript code can be changed:
var root = document.documentElement;root.style.backgroundImage = 'linear-gradient(90deg, #888, #ccc)';if(root.style.backgroundImage) { $('html').addClass('linear-gradient');}
Of course, when determining the specific attribute value, we select the element used for judgment as an element hidden on the page because of a CSS assignment operation.
Advantages and disadvantages of various methods
- Native
@supports
The performance is certainly the best, and external javascript is not required. This is the first release, but the compatibility problem is helpless. Currently, it is not the best choice.
- Modernizr has powerful functions and good compatibility, but external javascript needs to be introduced. An http request is required. If only a few features are detected, it is a bit cool.
- To detect the required features, use javascript to implement a simple function and encapsulate the methods used above:
/*** Used for simple CSS Feature Detection * @ param [String] The Name Of The CSS attribute to be detected by the property * @ param [String] specific attribute value of the value style * @ return [Boolean] whether to pass the check */function cssTest (property, value) {// elements used for testing, hidden on the page var ele = document. getElementById ('test-display-none'); // if (arguments. length = 1) {if (property in ele. style) {return true;} // condition of two parameters} else if (arguments. length = 2) {ele. style [property] = value; if (ele. style [property]) {return true;} return false ;}
A simple test:
There is no silver bullet in software engineering, so either method has a suitable scenario. What we need to do is to understand their principles and use them flexibly according to different scenarios.
A series of CSS articles are summarized in my Github.
At the end of this article, if you have any questions or suggestions, you can have a lot of discussions, original articles, and limited writing skills. If there are any mistakes in this article, please kindly advise.