Reputation: 193108
How to write a CSS Selector selecting elements NOT having a certain attribute?
I have 2 <div>
nodes as follows:
First:
<div class="weEq5" style="will-change; width;">
<button class="_35EW6">
Second:
<div class="weEq5">
<button class="_35EW6">
I need to select the <div>
(with the similar class) and each of them which have a similar descending <button>
but without the style
attribute.
XPath seems working fine as:
//div[@class and not (@style)]/button
I am looking for an equivalent CssSelector.
Trials:
div[class :not(style)]>button (doesn't works).
I have been through the following discussion but they seem to be discarding the class attribute as :not([class])
as in:
I was looking in similar lines ending with :not(attribute)
.
Upvotes: 13
Views: 11679
Reputation: 6459
I think more accurate CSS Selector is:
div[class]:not([style])>button
because the button
element is a child of div
element.
Hope it helps you!
Upvotes: 18
Reputation: 316
I do not understand how the situation developed in the first place, where the structure of the page necessitates the CSS rules to be aware of whether "style=..." exists in the document itself. Or even why style=... is being used.
The style attribute is old-school now, pre-CSS I believe. It also takes precedence over anything in the CSS. That attribute does not accept CSS class names. It accepts only native html style properties like "width","height","font" - old-school stuff - ultimately those are what your CSS resolves to, no matter how fancy or obfuscated it is through frameworks: font, width, left, top, float.. and so on.
By use of the class attribute (instead of style) in the document you get infinite control from which to write smart selectors in your CSS.
You can put 3 classes in the class attribute of your div for example, if you want, and have your selectors apply styling to it if 2 of the classes are present but not if all 3 are there. Tonnes of flexibility, no need to override or use "style=..." in the document at all.
Upvotes: 3
Reputation: 824
That's the code you're looking for:
div:not([style]) button{
background-color: red;
}
Now let's break it down. We have have four selectors in this example:
.weEq5
.The combination of div:not([style])
means that we want all divs that do not have a style attribute. After which we have a space and a button means that we want all the buttons that are inside the above selector.
Adding a >
before the button div:not([style]) > button
will only select button elements which are direct children of the selected div. It will exclude from selection buttons that are deeper inside the div.
Upvotes: 13
Reputation: 723688
Normally, you would write :not([style])
to match an element that does not have a style
attribute, as described here which emphasizes the use of both ()
and []
brackets, in that order.
But if this isn't working in Selenium WebDriver, and worse still if :not(style)
works exactly like how I would expect :not([style])
to, then that's a bug with its CSS selector parser, since :not(style)
actually means "not a style
element" which makes div:not(style)
redundant as an element can only either be a div
or a style
but not both at the same time. Unless you absolutely require a selector, I strongly recommend using the XPath locator strategy instead of relying on quirks like this with Selenium WebDriver's CSS selector engine that force you to write selectors that are both incorrect and don't work anywhere else that accepts a selector.
Upvotes: 4