How can I select an element by an attribute set on its parent using CSS 2.0 selectors? - css

I have a HTML like this in my QWebView
<div class='a' id='root'>
<div id='x'>...</div>
<p> ...
<p>
...
<div id='x2'>...</div>
<div>
<a href='go/xxxx'>go</a>
</div>
</div>
How do I select the a? I tried this selectores:
div[id='root'].a
div[id='root'] + a
but it didn't worked. Code:
QWebFrame* frame = webView->page()->mainFrame();
QWebElement button = frame->documentElement().findFirst("div[id='root'].a");
assert(!button.isNull()); // gets executed

Your selector is selecting the div with id='root' and class='a'. If you want to select the a tag inside of that div, you need to make your selector:
div[id='root'].a a
The additional 'a' at the end of the selector tells jquery to select the a inside of the div.

You can switch to using XPath 2.0 in Qt to have more expressive freedom, but then you need to process your HTML as XML.
To resolve, add a descendant selector1 for a. I.e., change this div[id='root'].a into this:
div[id=root].a a
As an alternative, if there's a bug in Qt, try:
div[id=root][class=a] a
Or (which is potentially a bit wider):
div[id~=root][class~=a] a
These last two are just alternatives in case for some reason the original fix to your code (adding the a descendant selector) didn't work.
The code snippets above doesn't use quoted strings, this is optional.
1 adding a was seen in stevenc4's answer), after my original (wrong) solution. Kudos to him :)

Related

using locators to access sibling of current element

How can i use findelement , to locate the 3rd div element from the element that has the id=1.custom-system-user.generatepassword and then the img element inside the third div sibling ?
please note that there is no guarantee that the table element is the first sibling, so what i need is access the third div relative to the table element Only (I can't rely on the div being the n-th sibling) ?
P.s - is there such a thing "nested" css selectors/locators ( table+div+div+div>img )?
Note
My simplified example (id attribute has been added only for debug purposes):
<html>
<body>
<table id="0.custom-System-User.generatePassword">Table</table>
<div>Foo</div>
<div>Bar</div>
<div>
<div>
<div>
<img id="my-image" />
</div>
</div>
</div>
</body>
</html>
Python script:
from selenium import webdriver
browser = webdriver.Chrome()
browser.get(URL)
el = browser.find_element_by_xpath('//table[contains(#id, generatePassword)]/following-sibling::div[3]//img')
el.get_attribute('id')
Output:
In [5]: el.get_attribute('id')
Out[5]: u'my-image'
xpath selector might be like '//table[contains(#id, generatePassword)]/following-sibling::div[3]/div/div/img'.
Assuming that there will be three div elements, you can use xpath easily
driver.findElement(By.xpath("//div[#class='x-form-item'][3]/div/div/img"))
try the following xpath:
"//div[contains(#id, '1.custom-System-User.x-auto')]//img"
If not working, can you please expand all sections of the provided HTML, since I can't know what's exactly there.
can you try this
driver.findElement(By.xpath("//table[#id='0.custom-System-User.generatePassword']/div[3]/div/div/img"))

Hiding previous element by checked selector

I would like to use css3 features to hiding previous element.
Basically,
I want to use a checkbox to hide previous sibling element without using javascript.
I have prepared a sample for entry point.
http://cssdesk.com/5zccy
Thanks
Edit:
I have changed sample.
My usecase: I want to have collapsible sections at my site. Two area separated by a simple checkbox and checking it will beautifully hide previous sibling.
I believe that using pure css will let me to reduce using javascript for this task.
You can not hide the previous elements - just the following ones with the general sibling selector
DEMO
Then you might be able to position the elements, so on the actual page the checkbox will appear after the .parent div.
There's no css selector to select the previous tag of a matched element. The closest you can get using only css it's doing that for the next element:
<input class="hider" type="checkbox" /> child
<div class="parent">
Parent
</div>​
.hider:checked + * {
display:none;
}​

How can I use CSS to select the "a" tag in the following layout?

I have the following html snippet:
...
<div>
<a></a>
<select class="error"></select>
<label class="error"></label>
<div></div>
</div>
...
I need to select the "a" tag with CSS. Is this possible?
I am trying to select the "a" tag. The error class is dynamically injected via javascript. I want to have a static css rule that makes the "a" tag red.
I am only interested in a CSS approach using selectors. If this is not possible, I do not need help with alternative approaches.
~~~~~~~~~~~~~~
EDIT:
~~~~~~~~~~~~~~
The only thing that separates this "a" tag from other "a" tags is the presence of the error class elements following it. The error class is dynamically applied. I do not want to select other "a" tags that do not have an error class following it. I only want to select this "a" tag when it is followed by the error class.
~~~~~~~~~
EDIT AGAIN:
~~~~~~~~~
I explained that poorly. I was hoping that I could select the first child (or something) of all divs that contain the error class.
It is not possible. CSS has no tools for selecting an element on the basis of its siblings after it. Even CSS Selectors 4 (which contains many proposed, but not approved or implemented, additions to selectors) lacks such a feature. (If it will ever be added, I suppose it would be called “preceding-sibling combinator”.)
<style>
.mylinkclass {
...style info goes here
}
</style>
...
<div>
<a class="mylinkclass"></a>
<select class="error"></select>
<label class="error"></label>
<div></div>
</div>
...
Just selecting the anchor will give you what you want in that specific layout.
a {color: red;}
-- Edit --
Since you changed your question, here's a new answer:
Use JS to check if siblings of a particular type exist.
$('a').each(function(){
if (​$(this).siblings('.error').length > 0​​)
$(this).css('color','red');
});​
Regarding your updated question, try this hackish solution:
div a:nth-last-child(4)
{
background-color:yellow;
}
if you can count on the fact that your DIV has 4 and only 4 elements inside (the anchor being the first) when the error elements are present and fewer (or more) elements otherwise.
Anyway, you're probably better off using Javascript for this (or proper HTML).

Select with CSS the last div in recursive div layout

With the below HTML, how i can select the DIV depper (which has no children)?
I think that i can use nth-last-child but dont work because all divs has the last (and also the first)! :D
PD: Not is possible the use of the ID or CLASS property in the DIV deeper (because they are HTML existent files in web)
Html:
<div class="base">
<div>
<div>
<div>
<div>
<!-- recursive divs (quantity not defined...) -->
</div>
</div>
</div>
</div>
</div>
CSS selectors cannot look to the parent elements, sadly, so you can't see which elements don't have divs as children.
If you are using jQuery, you can do this to find the element:
$('.base :not(:has(*))').addClass('deepest');​
Demo: http://jsfiddle.net/EhZax/
You'll have to use Javascript. Here's an example using jQuery:
$('.base *').filter(function(){
return ! $(this).find('> *').length;
});
See it here in action: http://jsfiddle.net/E6sec/
Update: If you want to, you could create your own :sterile selector. Here's an example:
jQuery.expr[':'].sterile = function(el) {
return ! el.children.length;
};
You could then just use it as you would any other pseudo selector:
$('.base :sterile');​
Here's the fiddle: http://jsfiddle.net/FBw5q/
P.S. I used the native el.children since it's way faster than any of jQuery's methods. However, IE < 9 will include comments as children. If that concerns you, you can use jQuery's children() method.
You need Javascript for that. It's not possible with CSS only

wildcard * in CSS for classes

I have these divs that I'm styling with .tocolor, but I also need the unique identifier 1,2,3,4 etc. so I'm adding that it as another class tocolor-1.
<div class="tocolor tocolor-1"> tocolor 1 </div>
<div class="tocolor tocolor-2"> tocolor 2 </div>
<div class="tocolor tocolor-3"> tocolor 3 </div>
<div class="tocolor tocolor-4"> tocolor 4 </div>
.tocolor{
background: red;
}
Is there a way to have just 1 class tocolor-*. I tried using a wildcard * as in this css, but it didn't work.
.tocolor-*{
background: red;
}
What you need is called attribute selector. An example, using your html structure, is the following:
div[class^="tocolor-"], div[class*=" tocolor-"] {
color:red
}
In the place of div you can add any element or remove it altogether, and in the place of class you can add any attribute of the specified element.
[class^="tocolor-"] — starts with "tocolor-".
[class*=" tocolor-"] — contains the substring "tocolor-" occurring directly after a space character.
Demo: http://jsfiddle.net/K3693/1/
More information on CSS attribute selectors, you can find here and here.
And from MDN Docs MDN Docs
Yes you can do this.
*[id^='term-']{
[css here]
}
This will select all ids that start with 'term-'.
As for the reason for not doing this, I see where it would be preferable to select this way; as for style, I wouldn't do it myself, but it's possible.
An alternative solution:
div[class|='tocolor'] will match for values of the "class" attribute that begin with "tocolor-", including "tocolor-1", "tocolor-2", etc.
Beware that this won't match
<div class="foo tocolor-">
Reference:
https://www.w3.org/TR/css3-selectors/#attribute-representation
[att|=val]
Represents an element with the att attribute, its value either being exactly "val" or beginning with "val" immediately followed by "-" (U+002D)
If you don't need the unique identifier for further styling of the divs and are using HTML5 you could try and go with custom Data Attributes. Read on here or try a google search for HTML5 Custom Data Attributes

Resources