How to take get element in css - html

I'm not sure that there is unique question, but i can't find the same, sorry. Can u please help me to take element from DOM using CSS to apply style for it. i have similar block
<div class="parent-block">
<div class="child accomplished">
</div>
</div>
<div class="parent-block">
<div class="child accomplished">
</div>
</div>
<div class="parent-block">
<div class="child null">
</div>
</div>
<div class="parent-block">
<div class="child null">
</div>
</div>
</div>
So i need to take last child with class accomplished. I can't use nth-child because it's dynamically blocks and it can be a lot of parent blocks with accomplished.

See the selectors specification.
The only :last pseudo-classes are keyed off every sibling an element has or every sibling of the same type.
There is nothing along the lines of :last-of-class.
You need to use JS to achieve this.

You could use JQuery to select your required element.
Use the following sytax:
$(selector).action()
So here you could use:
$(".child acomplished").last().css("border", "3px solid red")
Take a look at the w3 schools docs to see how to add JQuery to your project:
https://www.w3schools.com/jquery/jquery_get_started.asp

Use
For the first element :
document.getElemesntsByClassName("parent-block")[0].style.color = "#fff";
For the last element
document.getElemesntsByClassName("parent-block")[3].style.color = "#fff";

Related

CSS selector for elements before and after a given element

I have a piece of generated HTML I am parsing. Roughly speaking, the part I am interested in for this problem looks like this:
<div class="rowset">
<div class="head">...</div>
<div class="head">...</div>
<div class="head">...</div>
<div class="head">...</div>
<div class="head">...</div>
<br><h2>WOWZA</h2><br>
<div class="head">...</div>
<div class="head">...</div>
<div class="head">...</div>
</div>
I need a way to select the divs that appear before WOWZA and the ones that appear after WOWZA in two separate operations. There will always be at least one div before and one after the WOWZA, and they always have the same class of "head". The number of head divs will vary from rowset to rowset.
The text WOWZA is constant, never changes. I just don't know how to use it as a separator in this context?
I can use jquery selectors for this too if necessary.
I believe you would have to use jQuery for this, because CSS3 does not currently have a way to select an element by it's text content. However, with jQuery we can use .contains()
To select the elements after your text:
You can use ~, the General sibling combinator
The general sibling combinator (~) separates two selectors and matches
the second element only if it follows the first element (though not
necessarily immediately), and both are children of the same parent
element.
To select the elements before your text:
We can use jQuery's .not() to exclude the elements in $afterWowza from the collection
let $afterWowza = $('.rowset h2:contains("WOWZA") ~ .head');
let $beforeWowza = $('.rowset .head').not($afterWowza);
$beforeWowza.css('background-color', 'blue');
$afterWowza.css('background-color', 'red');
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="rowset">
<div class="head">...</div>
<div class="head">...</div>
<div class="head">...</div>
<div class="head">...</div>
<div class="head">...</div>
<br><h2 class="wowza">WOWZA</h2><br>
<div class="head">...</div>
<div class="head">...</div>
<div class="head">...</div>
</div>
You can use the jQuery selector: $("br ~ h2")
Or, wrap an HTML <span> or <div> around the line with an id and use jQuery selector: $("#idname")

How can one read a list of text from divs in the most reliable way, using sibling relations in Selenium with Python?

I'm trying to locate and then read the list of text 1-5. All divs with class="col-md-6" have the same structure, so I'm trying to use the text from:
<h5>Header Unique Text</h5>
as it is the only unique element and then proceed to extract the texts but without using /div[x]/div[y] type xpath, as it won't be reliable in my case. I'm searching for a css selector(or even xpath) which uses sibling relations, maybe nth-child, related to the header tag or its parent div. However, I'm not sure you are even able to move backward in the DOM with css selectors.
Any help would be greatly appreciated.
<div class="row dashboard-admin-widgets">
<div class="col-md-6">...</div>
<div class="col-md-6">...</div>
<div class="col-md-6">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>Header Unique Text</h5>
</div>
<div class="ibox-content">
<div>Text 1</div>
<div>Text 2</div>
<div>Text 3</div>
<div>Text 4</div>
<div>Text 5</div>
</div>
</div>
</div>
</div>
If it is the last child as shown you can use a last-child selector
.col-md-6:last-child .ibox-content div
You could also use nth-of-type
.col-md-6:nth-of-type(n) .ibox-content div
Or even last-of-type
.col-md-6:last-of-type .ibox-content div
You can use xpath to get the ancestor of <h5>Header Unique text</h5> like this:
//h5[normalize-space(.)='Header Unique Text']/ancestor::div[#class='ibox float-e-margins']/div[#class='ibox-content']/div
Let me break it down for you so you can adjust the xpath to your needs.
First, we look for <h5>Header Unique text</h5> and then we get its ancestor which is div[#class='ibox float-e-margins']. You can use any attribute, tag, just like you would write your xpath.
Now we are looking for elements in context of div[#class='ibox float-e-margins']. Then, use we look for all div elements with the text you desired.
Also, instead of using /ancestor::div, you can get first parent and look for it's sibling like this:
//h5[contains(text(), 'Header Unique Text')]/parent::div[#class='ibox-title']/following-sibling::div[#class='ibox-content']/div

Is it OK to apply multiple BEM elements to an html element's class?

I am structuring the CSS in my web application according to the BEM convention.
I have a block called item and 3 elements: item__section, item__title and item__description.
I am using these BEM classes as follows:
<div class="item">
<div class="item__section item__title"> ... </div>
<div class="item__section item__description"> ... </div>
</div>
The item__section element class contains style that we reuse between elements.
Is this valid BEM or should I create a modifier for item__section for each kind of section(title and description)?
That's absolutely valid and is called mix:
https://en.bem.info/methodology/key-concepts/#mix
https://en.bem.info/methodology/css/#mixes
I don't think you should.
You could add mixin like:
<div class="item">
<div class="item__section u-title"> ... </div>
<div class="item__section u-description"> ... </div>
</div>
but don't use two elements of the same block in the same tag because you can end up with specificity problems

Am I allowed to use element from a parent block, inside a children block?

I would like to know if, according to BEM methodology, I can have the following structure:
.block1
.block1__element1
.block2
.block1__element2 <-- ??
Am I allowed to use an element from a parent block, inside a children block?
Thanks.
UPDATE:
This is the actual DOM structure:
<div class="head">
<div class="head__user"></div>
<div class="head__nav">
<div class="menu">
// <-- ???
</div>
</div>
</div>
According to best practices of BEM methodology: am I allowed to move the element with head__user inside the menu block? Or all elements inside the menu block need to start with the menu__ prefix?
I hope this clears out the problem.
I been using BEM for sometime and from what I got it's not recommended nor intended to be used like that. You can nest different BEM elements to each other like menu-blockintohead-block, but menu-block items should not go outside its parent menu-block, like you should not put menu-block__item at the top of head-block. Does it makes sense? :)
To illustrate there are two ways to go. What should be noted here is that depending on the scale of your project and how you build things (component based?). If you don't have a large project and are not doing or reusing the menu else where you can do it both ways. Lets say your menu is huge amount of html/css I would do it like #1
This is not correct
<div class="head">
<div class="head__user"></div>
<div class="head__nav">
<div class="menu">
<div class="head__something"></div>
</div>
</div>
</div>
Recommended solution
Based on this part of the documentation. Now you can chop your own header design into blocks, does this below match?
<div class="head">
<div class="head__user"></div>
<div class="head__nav">
<div class="menu">
<div class="menu__something"><img src="" class="menu__image" /></div>
</div>
</div>
</div>
I think this variant is allowed:
<div class="head">
<div class="head__nav">
<div class="menu">
<div class="head__user"></div>
</div>
</div>
</div>
I haven't found the current part in the official BEM documentation, but I've found this part:
The block name defines the namespace, which guarantees that the elements are dependent on the block (block__elem).
A block can have a nested structure of elements in the DOM tree:
Example
<div class="block">
<div class="block__elem1">
<div class="block__elem2">
<div class="block__elem3"></div>
</div>
</div>
</div>
However, this block structure is always represented as a flat list of elements in the BEM methodology:
Example
.block {}
.block__elem1 {}
.block__elem2 {}
.block__elem3 {}
This allows you to change a block's DOM structure without making changes in the code for each separate element:
Example
<div class="block">
<div class="block__elem1">
<div class="block__elem2"></div>
</div>
<div class="block__elem3"></div>
</div>
The block's structure changes, but the rules for the elements and their names remain the same.
I understand it as there is only one rule about HTML structure for elements in BEM: an element has to be inside its block (it doesn't matter how deep).
One possible problem that I can imagine for this case is using some of BEM tree formats. But if you don't need it, I think there's no problem.
I would consider making the potential head__something into simply something, and then to provide multiple modifications of it. e.g. something--head and something--menu.
<div class="head">
<div class="head__user"></div>
<div class="head__nav">
<div class="menu">
<div class="something--menu" />
</div>
</div>
<div class="something--head" />
</div>
Also, refactoring further, I would consider getting rid of head__nav as it probably does not add any richer semantics than menu.
<div class="head">
<div class="head__user"></div>
<div class="menu">
<div class="something--menu" />
</div>
<div class="something--head">for those cases where you want <code>something</code> directly descending from <code>head</code></div>
</div>

Get child by it's parent's another child

My HTML looks like that:
<div class="parent">
<div class="url">
LINK
</div>
<div class="stats">
<div class="a">12</div>
<div class="b">14</div>
</div>
</div>
<div class="parent">
<div class="url">
LINK
</div>
<div class="stats">
<div class="a">133</div>
<div class="b">13</div>
</div>
</div>
<div class="parent">
<div class="url">
LINK
</div>
<div class="stats">
<div class="a">4</div>
<div class="b">46</div>
</div>
</div>
Is this possible to get parent's child which is found by another, the same parent child?
So, I want to get contents of class b of second parent. But I want to find bu it's href parameter.
Like that-
XPath finds parent, which has child url and a with href parameter http://url.com/view/364
XPath takes contents of class b in the same parent
If you don't understand, I basically need that XPath gets number 13 (contents of b), but find it using href parameter.
Is this possible? How this can be done?
An even cleaner approach is (line break only for readability)
//div[#class = 'parent' and div[#class = 'url']
/a/#href = 'http://url.com/view/364']/div[#class = 'stats']/div[#class = 'b']
It is better than the answer you found yourself (actually, it's a good thing you found an answer yourself!) because there are no unnecessary parent axis (..) steps in it.
It is better than
(//a[#href='http://url.com/view/364']/following::div[#class='b'])[1]
because following::div[#class = 'b'] selects a div element that follows the context item, even if it is in another div[#class = 'parent']. For instance, if the document looked like
<html>
<div class="parent">
<div class="url">
LINK
</div>
<div class="stats">
<div class="a">133</div>
</div>
</div>
<div class="parent">
<div class="url">
LINK
</div>
<div class="stats">
<div class="a">4</div>
<div class="b">46</div>
</div>
</div>
</html>
then the result would be
<div class="b">46</div>
Well, a cleaner approach would be to use the following axis and then select the first node with class='b'.
"(//a[#href='http://url.com/view/364']/following::div[#class='b'])[1]"
I found the answer.
It is easy to do that -
//*[#class="parent"]/div[#class="url"]/a[#href="http://url.com/view/364"]/../../div[#class="stats"]/div[#class="b"]