Is there a way to select a specific parent using XPath? - html

From the reading I've done so far I don't think it's possible but in the off chance it is, here goes:
Given the following overly simplified HTML (based on HTML generated from a CMS, so no real control over it)
<div class="random">
<div class="random"> <-- This is the one I want
<div class="random">
<div class="random">
<span class="random">
<input id="experiment-randomnumbers-textinput-2">
</span>
</div>
</div>
</div>
</div>
I have hacked together the following XPath expression to get the node that I want:
//input[contains(#id,'experiments') and contains(#id,'textinput-2')]/parent::span/parent::div/parent::div/parent::div
The question is, is there a neater way of doing this? I'm assuming it can't be done in CSS?
Cheers
Rob

Let BASE_XPATH = //input[contains(#id,'experiments') and contains(#id,'textinput-2')].
Then, if the target is four ancestors up, and you don't care about the ancestor elements' names:
BASE_XPATH/../../../..
If there's a unique condition (in elided parts of your markup) among ancestors:
BASE_XPATH/ancestor::*[ UNIQUE_PREDICATE ]

Related

How to name subelements according to BEM?

I have a question regarding BEM (Block Element Modifier) class naming conventions.
What if I need to have 3 nested divs, how should I name the class of the 3rd one?
.one{} //block
.one__two{} //block element
//?
<div class="one">
<div class="one__two">
<!-- How should I rename class "three"? -->
<div class="three"></div>
</div>
</div>
I want to rename ".three" to "one__two__three", or "two__three", but I'm not sure that this is right, because as I understand, according to BEM nesting elements inside of elements is not allowed.
To me, it's about relationships, particularly key-value relationships, so I would approach it that way.
Without exploring contextual naming paradigms, it could be suggested to use one__three.
Alternatively, if one is simply a container for two, then one could be renamed two__container and three renamed to two__item. Of course that doesn't make a whole lot of sense using numbered labels like this, but I hope you can see where it could lead.
Nesting elements is fine; build the structure to your needs. The important thing is to not couple the classnames to your nesting. The classname schema does really only recognize two types of DOM elements: the block itself and the elements of that block; of the latter all are equal regarding the naming schema, no matter how deeply nested in the block.
Here is an example:
<div class="product-card">
<div class="product-card__img-area">
<img class="product-card__product-picture" src="https://example.com/cabulator.jpg"/>
</div>
<div class="product-card__header">
<span class="product-card__main-headline">Encabulator</span>
<span class="product-card__sub-headline">The turbo shmeerf of all Shmoof</span>
</div>
<div class="product-card__text-body">
Lorem ipsum shmeerf of Shmoof quooz bar moof bla bla
</div>
<div class="product-card__footer">
<a class="product-card__cta" href="https://example.com/buy.html">Buy it!</a>
</div>
</div>
And modifiers are added as needed:
<div class="product-card__footer">
<a class="product-card__cta product-card__cta--bargain" href="http://exmpl.com/buy">
Buy it! 50% off for first-time customers!!!!!! OMG!!!!
</a>
</div>

Where to put semantically meaningfull blocks in twitter bootstrap skeleton?

this is my first question, so please, do not judge strictly. The essence is in follows: I imagine block structure of document as a printing press - but very remotely, of course - because press already hase content and semantic, while div's structure of document - only skeleton for it, and both mentioned subjects must be added. An object of concern to me is where I should put this semantic in document skeleton, formed with twitter bootstrap and defining structure - for example:
<div class="container">
<div class="row">
<div class="col-xs-12">
Content, which must be wrapped in some semantically meaningfull element - like, for example - article-preview class
</div>
</div>
</div>
I see two different ways, but dont know, what way is better practice in marking down html documents:
1) Adding semantic class to element, which already have class that forming my document structure - col-xs-12 - or press in my analogy.
<div class="container">
<div class="row">
<div class="col-xs-12 article-preview">
'Content, which must be wrapped in some semantically meaningfull element like, for example - article-preview class'
</div>
</div>
</div>
2) Or adding brand new semanit block under structuring block and putting my content here:
<div class="container">
<div class="row">
<div class="col-xs-12">
<div class="article-preview">
Content, which must be wrapped in some semantically meaningfull element - like, for example - article-preview class
</div>
</div>
</div>
</div>
I apologize if the question seems a little stupid to you, but I thinking about it for really long time and from now on can not do anything until it is resolved.
Thank you!
I will prefer the second way. Because bootstrap cols have their own styles and structure, so if you have additional styles or codes try to do like second way.
I think we should keep the bootstrap structure.
Go with the first approach because I feel the second approach will make your code long unnecessarily.
With the first approach as well you can add your custom styles. just add your stylesheet after the bootstrap css.

How to specify state with BEM?

Using BEM CSS class syntax, lets say I have an element with the following class:
...
<div class="purchase__module2__heading__tooltip">...</div>
...
Now lets say there is an event or something where this "tooltip" becomes active or visible. What is the proper way to express this with BEM? Do I replace the current class so now it becomes:
...
<div class="purchase__module2__heading__tooltip--active">...</div>
...
or do I add it
...
<div class="purchase__module2__heading__tooltip purchase__module2__heading__tooltip--active">...</div>
...
Or can I just do something simple like this:
...
<div class="purchase__module2__heading__tooltip active">...</div>
...
I think the answer is #2, but it seems very drawn out. #3 is nice and simple but I can't tell if this follows proper BEM guidelines or not.
If you're modifying a block or element you must include the base class as well.
For example
<div class="block">
<div class="block__element">...</div>
</div>
could have the block modified as:
<div class="block block--modifier">
<div class="block__element block--modifier__element">...</div>
</div>
or the element modified as:
<div class="block">
<div class="block__element block__element--modifier">...</div>
</div>
In either case you start needing to use multiple classes.
Looking over your example of:
<div class="purchase__module2__heading__tooltip">
It's clear that you're nesting too deeply, preventing yourself from being able to reuse the majority of your code.
Given the names you're using, I'd guess that what you actually have is:
a purchase module (.purchase-module)
with a heading (.purchase-module__heading)
a tooltip (.tooltip)
The markup could look something like:
<article class="purchase-module">
<h1 class="purchase-module__heading">
...heading text...
<span class="tooltip">...</span>
</h1>
</article>
Note how making the tooltip active now just requires changing a short class:
<span class="tooltip tooltip--active">...</span>
That's the ideal with BEM.
You are right and the answer is #2.
Here's why:
https://en.bem.info/methodology/faq/#why-include-the-block-name-in-names-of-modifier-and-element
https://en.bem.info/methodology/faq/#how-do-i-make-global-modifiers-for-blocks
BTW, you shouldn't keep DOM structure in naming. And here's why: https://en.bem.info/methodology/faq/#why-does-bem-not-recommend-using-elements-within-elements-block__elem1__elem2

What is the purpose of extra <div> wrappers?

I occasionally see the following construct:
<div id="main-header-wrapper">
<div id="main-header">
<span>foo</span>
<span>bar</span>
...
</div>
</div>
There is nothing at all between main-header-wrapper and main-header. Why would one want to use the outer wrapper when there is already one level (i.e. main-header)?
There are multiple aspects that could make a difference:
Some layouts require this combination. If it is needed in your case depends on the css-rules applied. See this question for some details.
JavaScript code may read/manipulate the DOM identifing the nodes by their id

Need 2 id attributes on a div

Usually when I have a div, I use the id attribute to uniquely identify an element.
Ex:
<div id="F123" class="sidebar-item">
My first item goes here
</div>
Now, I need a double 'key' for my div element: a 'slug' attribute and a 'category' attribute.
E.g.:
<div slug="my-first-item" category="techno" class="sidebar-item">
My first item goes here
</div>
The compilator warns me that these attributes are not valid. What is the best way to have a double key on a div? I'm pretty sure there are various ways to proceed but I'm curious about the best way?
<div data-slug="my-first-item" data-category="techno" class="sidebar-item">
My first item goes here
</div>
New HTML data attributes. Why do think you need it if I may ask?
HTML5 allows you to user data-[info].
<div data-slug="my-first-item"></div>
https://developer.mozilla.org/en/HTML/Global_attributes
One way to do this would be to use a class and an id. An element can have any number of classes, so you can create a class for each category (with no styles), and then use the id to be more specific (although each id will still have to be unique, even across classes).
Another alternative is to have each id be of the form id="<category>_<slug>", and find ids that start with the category to get all the elements in a category.
I don't know what or how you are going to process the date but this is my idea:
<div id="name['slug_value']['category_value']" class="sidebar-item">
My first item goes here
</div>
Which translates to:
<div id="name['my-first-item']['techno']" class="sidebar-item">
My first item goes here
</div>
But like the first answer I'm curious about why do you need to do this.