CSS3 combining selectors with OR instead of AND

↘锁芯ラ 提交于 2019-11-26 11:36:57

问题


Given this selector:

body[class*=\"page-node-add-\"][class~=\"page-node-edit\"] {background:red;}

It will match a body which has a class that contains a substring of page-node-add- AND a class which is exactly page-node-edit

I would like to say match the first OR the second (but not both). Is it possible?

The problem with using a comma:

If I have a long selector like:

body[class*=\"page-node-add-\"] form.node-form > .field-type-field-collection > table > thead tr th,
body[class~=\"page-node-edit\"] form.node-form > .field-type-field-collection > table > thead tr th
{...}

That is a pain I would have thought CSS3 would remedy that, I was imagining something like:

body([class*=\"page-node-add-\"]):or([class~=\"page-node-edit\"]) {background:red;}

Thanks


回答1:


You'll need to split them up using a comma:

body[class*="page-node-add-"], body[class~="page-node-edit"] {background:red;}

The problem with using a comma:

... is that you can't do it any other way than with a comma. Perhaps it could have been remedied with Selectors 3, but unfortunately the spec says otherwise. That is only going to be remedied by Selectors 4, either because it wasn't proposed until recently, or it was proposed but didn't make the cut for level 3.

In level 4 of Selectors you will be able to do something like this:

body:matches([class*="page-node-add-"], [class~="page-node-edit"]) form.node-form > .field-type-field-collection > table > thead tr th
{...}

Currently, this is being implemented under its originally-proposed name, :any(), with the prefixes :-moz-any() and :-webkit-any(). But using :any() in public-facing CSS is pointless given that

  1. only Gecko and WebKit support it; and

  2. you have to duplicate your rulesets because of the way prefixed selectors are handled, which not only defeats the intended purpose of the :matches() selector, but makes things even worse:

    body:-moz-any([class*="page-node-add-"], [class~="page-node-edit"]) form.node-form > .field-type-field-collection > table > thead tr th
    {...}
    body:-webkit-any([class*="page-node-add-"], [class~="page-node-edit"]) form.node-form > .field-type-field-collection > table > thead tr th
    {...}
    

In other words, until implementations update themselves to the standardized :matches(), there is no other viable solution (save from using a preprocessor to generate the repeated selectors for you).




回答2:


I found the answer here:

CSS Shorthand to identify multiple classes

Mozilla and webkit has a -moz-any or -webkit-any, though in the CSS4 spec there is a :matches. Suprised this wasn't thought of in CSS3 as it would greatly reduce the amount of repetative code without having to use SASS or LESS or whatever.




回答3:


So you really want XOR when I read your question. You can achive this by using the :not selector and say "class one and not the other" and the other way around.

div.one:not(.two), div.two:not(.one) {
    background:red;
}

Here is a fiddle: http://jsfiddle.net/XfgxK/3/



来源:https://stackoverflow.com/questions/10753174/css3-combining-selectors-with-or-instead-of-and

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!