惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

G
GRAHAM CLULEY
S
Security @ Cisco Blogs
P
Proofpoint News Feed
Cisco Talos Blog
Cisco Talos Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
C
Cyber Attacks, Cyber Crime and Cyber Security
T
Tor Project blog
WordPress大学
WordPress大学
Project Zero
Project Zero
S
Schneier on Security
P
Proofpoint News Feed
小众软件
小众软件
P
Privacy International News Feed
美团技术团队
L
LangChain Blog
Know Your Adversary
Know Your Adversary
J
Java Code Geeks
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
The Register - Security
The Register - Security
N
Netflix TechBlog - Medium
Microsoft Security Blog
Microsoft Security Blog
Engineering at Meta
Engineering at Meta
I
InfoQ
量子位
Vercel News
Vercel News
博客园 - 三生石上(FineUI控件)
Spread Privacy
Spread Privacy
D
DataBreaches.Net
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
U
Unit 42
P
Privacy & Cybersecurity Law Blog
C
Cybersecurity and Infrastructure Security Agency CISA
T
The Blog of Author Tim Ferriss
Latest news
Latest news
K
Kaspersky official blog
MongoDB | Blog
MongoDB | Blog
L
LINUX DO - 热门话题
Simon Willison's Weblog
Simon Willison's Weblog
云风的 BLOG
云风的 BLOG
S
Securelist
AWS News Blog
AWS News Blog
F
Fortinet All Blogs
T
Threat Research - Cisco Blogs
Stack Overflow Blog
Stack Overflow Blog
Scott Helme
Scott Helme
Help Net Security
Help Net Security
Y
Y Combinator Blog
宝玉的分享
宝玉的分享
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
T
Tenable Blog

Oriol Brufau’s blog

Improved raster transforms with non-uniform scales CSS ::marker pseudo-element in Chromium Hello world!
Open Prioritization for implementing selector list argument of :not() in Chrome
Oriol Brufau · 2020-07-13 · via Oriol Brufau’s blog

As you probably know, CSS selectors are patterns that can be used to apply a group of style declarations to multiple elements. For example, if you want to select all elements with the class foo, you can use the selector .foo or [class~=foo]. But sometimes, instead of styling the elements that have a specific characteristic, we want to exclude these and style the other ones.

For example, some developers prefer the border box sizing model rather than the content box one, so they use

* { box-sizing: border-box }

But then, imagine there is an image like

<img src="img.png" width="100" height="50" style="padding: 5px" />

The size attributes will include the padding, so the resulting content area will be 90x40. Not only will the image be downscaled, possibly producing artifacts, but it will also be stretched: the aspect ratio becomes 2.25 instead of the natural 2.

The above shows that excluding images can be a good idea. In CSS2, the solution was simply using a more specific selector to undo the general one:

* { box-sizing: border-box }
img { box-sizing: content-box }

However, in more complex cases this can get tedious, and the reset value may not be that obvious. Therefore, the Selectors Level 3 specification introduced the :not() pseudo-class. It accepts a selector argument, and matches all elements that do not match the argument. The example above can then be

:not(img) { box-sizing: border-box }

There were some limitations though. The selector argument had to be a simple selector, that is, one of:

Additionally, nesting negations like :not(:not(...)) was also invalid.

:not() with selector list argument

Selectors level 4 has made :not() more flexible, now it accepts any selector list as the argument.

In particular, it allows a compound selector argument, like :not(ul[reversed]), which matches all elements except the ones that both are ul and have the attribute reversed.

Another example of what you can do in level 4 is using a complex selector, that is, a sequence of compound selectors separated by combinators. For instance, :not(div > p) matches all elements except the p which have a div parent.

And finally, an example with a selector list could be :not(div, p), matching all elements except the ones that are either a div or a p.

Is that completely new behavior? Well, using De Morgan’s laws, the selectors above can be transformed into others which were valid in level 3:

Level 4 new syntax Level 3 alternative
:not(ul[reversed]) :not(ul), :not([reversed])
:not(div > p) :not(p), :not(div) > p, p:root
:not(div, p) :not(div):not(p)

However, the specificities are not completely equivalent. The specificity of a selector is a tern of 3 natural numbers (A,B,C), where in simple cases A is the number of ID selectors in the whole selector, B is the number of attribute or class selectors and pseudo-classes, and C is the number of type selectors and pseudo-elements. The specificity is one of the criteria used to solve conflicts when different CSS rules set the same property to the same element: the winning declaration will be the one with the most specific selector, when comparing specificities in lexicographical order.

The specificity of a :not() pseudo-class is the greatest among the specificities of the complex selectors in the argument, while the specificity of a selector list is the greatest among the complex selectors that match.

For example, for :not(ul[reversed]), the specificity is the same as for ul[reversed], i.e. (0,1,1). However, the specificity of :not(ul), :not([reversed]) can either be:

  • If only :not(ul) matches: (0,0,1).
  • If only :not([reversed]) matches: (0,1,0).
  • If both match, the maximum: (0,1,0).

Additionally, the level 3 alternatives can become cumbersome when used as part of a bigger selector. For instance, :not(.a1.a2) :not(.b1.b2) :not(.c1.c2) would become

:not(.a1) :not(.b1) :not(.c1), :not(.a1) :not(.b1) :not(.c2),
:not(.a1) :not(.b2) :not(.c1), :not(.a1) :not(.b2) :not(.c2),
:not(.a2) :not(.b1) :not(.c1), :not(.a2) :not(.b1) :not(.c2),
:not(.a2) :not(.b2) :not(.c1), :not(.a2) :not(.b2) :not(.c2)

Note the combinatorial explosion! It could be avoided using :is() or :where(), but they are also new level 4 additions.

Moreover, not all :not() selectors have a finite alternative in level 3. Consider :not(div p), that is, all elements which either are not p or don’t have any div ancestor. The problem is that we can’t directly enforce a constraint over all ancestors, instead we need something like

:not(p), p:root,
:root:not(div) > p,
:root:not(div) > :not(div) > p,
:root:not(div) > :not(div) > :not(div) > p,
/* ... */

and if a priori the DOM tree can be arbitrarily deep, we don’t know when to end the selector.

It’s for all these reasons that allowing selector lists in :not() is such a nice addition!

Browser support and Igalia’s Open Prioritization

If the new capabilities of :not() with a selector list sound cool to you, you might want to start using it right now! However, while major browsers have supported the level 3 version for a long time, only WebKit supports the level 4 one, Chrome and Firefox don’t.

But here is where Igalia comes into play! We are happy to announce Open Prioritization, an experiment for crowdfunding web platform features.

Historically, which features are implemented sooner and which ones are delayed has been decided by browser vendors, and big companies that can fund the work. But wouldn’t it be great if web developers could also have a saying in this prioritization?

At Igalia we have selected a few tasks that we think the community might be interested in. During a first stage, anybody can pledge their desired amount of money for their preferred choices. The first feature that reaches the goal will be selected for a 2nd stage, in which the actual funding will happen. And once funded, Igalia will do the implementation work. Note: don’t worry if you pledge for an option which is not selected, your money is only deducted when funding. See the FAQ for more details.

One of the features that we offer is precisely implementing :not() with selector lists in Chrome. If you like the idea, I invite you to pledge here!

Open Prioritization by Igalia. An experiment in crowd-funding prioritization.