CSS3 combining selectors with OR instead of AND - css

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

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
only Gecko and WebKit support it; and
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).

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.

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/

Related

css performance with direct descendents

I searched but I don't get a concrete answer.
I will ask a simple question
Is it more effective to do this :
body > html > section > div.class1,
body > html > section > table > tbody > tr > td > div.class1
{
background-color : red;
}
or this :
div.class1 {
background-color: red;
}
Browsers will check and convert every code you give to them (HTML and CSS inclued), for each selector the browser set the attributes to the right HTML markers. For very small website it doesn't affect a lot but for large website like Amazon that have more than 1 million lines of code, it will affect a lot the performances.
I think this is a good exemple: https://www.html5rocks.com/en/tutorials/internals/howbrowserswork/#Main_flow_examples
Less specificity is faster. Every selector is another run of a loop. Rule
of thumb, after 3 selectors deep perf will start to be impacted.
https://csswizardry.com/2011/09/writing-efficient-css-selectors/
Also note that well perf is in question, the real performance hit will be when you specify too deeply. I promise you that the long term maintenance become the real problem. Again 3 selectors deep is again a good Rule of Thumb.
Lastly, if you need help with css structure/architecture try:
1- http://getbem.com/
2- https://www.xfive.co/blog/itcss-scalable-maintainable-css-architecture/

How to exclude more than one th child

I want to exclude last and second last child of th to apply some css property.Individually it come be done like
.List thead tr th:not(:last-child){
//Some Css properties
}
and same for second last child.Can it be combined using not operator in one css selector?
CSS3 brings us the :nth-last-child() selector. To combine multiple :not items just add them to the end.
JSFiddle
li:not(:last-child):not(:nth-last-child(2)) {
color:red;
}
According to caniuse.com this method may be only fully supported from IE9. I say may be because caniuse isn't specific enough. Personally, I don't go out of my way to support < IE9 anymore unless it's a requirement.
.List thead tr th:nth-last-of-type(1) ,.List thead tr th:nth-last-of-type(2) {
/*Some Code*/
}
Try This

how to apply css to a specific element of a table?

I have a table like below
Consider the table id="testtable", and there is no class or id to uniquely identify the
specific td shown in the above screen.
I found a way to access second tr in this example like below
but i got stuck with accessing the second td in this second tr.
Anyone could you please give me a hand on this?
Thanks
maybe this help you dude :)
#testtable tbody > tr:first-child+tr > td:firt-child+td
{
}
or you can use the :nth-child pseudo class like this:
#testtable > tr:nth-child(2) > td:nth-child(2)
{
}
Note though, this won't work in older browsers (or IE), you'll need to give the cells a class or use javascript in that case.
you may use :nth-child()
http://api.jquery.com/nth-child-selector/
#testtable tbody >:tr:nth-child(2)
{
}

IE8 breaks when using two selectors?

I'm styling a table using CSS and I realised that IE8 doesn't support :nth-child
So before I added support for IE8, the css looked like so
.my-comments table.comments-list tr td:nth-child(1){width:18%;}
Then I added another selector like so
.my-comments table.comments-list tr td:nth-child(1), .my-comments table.comments-list tr .datecol{width:18%;}
IE8 doesn't like this, it wont recognise the 2nd selector but if I take out the first one like below then it works
.my-comments table.comments-list tr .datecol{width:18%;}
Any ideas how to fix this?
Obviously I could just use the above code but I'd like to leave in both selectors for future browsers
I would try making the style separately (without the comma). IE8 is probably not recognizing the :nth child and skipping the declaration.
If you would still like your nth-child(1) style to work in IE8 (with out having to add the .datecol class) you could change your CSS to the following:
.my-comments table.comments-list tr td:first-child + td {
width:18%;
}
The above code would target the second td - which is what I believe you are aiming to do with nth-child(1) and is support across a wider range of browsers.
I feel like I'm missing something here. Can't you just separate them into 2 different lines?
.my-comments table.comments-list tr td:nth-child(1){width:18%;}
.my-comments table.comments-list tr .datecol{width:18%;}

Alternate rows in one column only - CSS

How do I color alternate rows in only one column in my table? What's the code for that?
As #afranz409 stated, the ideal solution would be to create a class. However, this can be done with a CSS specific solution, with limited browser capabilities (None of the IE browsers < 9):
table tr:nth-child(2n) > td:nth-child(1) {
background-color: #eee;
}
In other words, for every alternate row, within the first table column, fill the background color #eee. As seen on JsFiddle.
For a more cross-browser compatible solution, I would recommend using this selector within jQuery:
$('table tr:nth-child(2n) > td:nth-child(1)').css("background-color", "#eee");
You're going to have to set the class on the specific <td>'s that you want colored, rather than the <tr>'s like you would for alternating rows
You could do it using the nth-child() selector.
See: http://jsfiddle.net/thirtydot/2NxE6/
CSS:
tr:nth-child(2n) > td:nth-child(4) { /* highlight column 4 */
background: #ccc
}
This works in modern browsers, but it doesn't work in Internet Explorer until version 9.
If you need it to work in earlier versions of Internet Explorer, here are your choices:
Use something like http://selectivizr.com/ to enable significant CSS3 support in older versions of IE.
Apply the selector using jQuery instead - this is a good option if your site already relies on jQuery.
Use another answer that suggests adding a class to the relevant td elements.
For the first column you can do something like:
tr:nth-child(odd) > td:first-child {
background: green;
}
tr:nth-child(even) > td:first-child {
background: blue;
}
It really depends on which column you want to color. If the x-th column, you can try td:nth-child(x).

Resources