this more a conceptual question. Recently i found myself to be more confident with this kind of html (example)
<div id="mainCont">
<div id="mainContFirst">Text <span id="mainContFirstSpan">option</span></div>
<div id="mainContSecond">Other Text</div>
</div>
Having all important tag marked with an ID you can easly write down css:
#mainContFirst {} etc
is this a bad pratice? Should I use just css selector? Is this faster then use selector?
Thanks
Grouping (edit)
Ok now What about elements that should have the same style?
let's say for example in every divs the second <span> should have font-size:10px; it's better this:
<div>
text text <span></span> <span id="firstDivSpan"></span>
</div>
<div>
text text <span></span> <span id="secondDivSpan"></span>
</div>
and then the css:
#firstDivSpan, #secondDivSpan {...}
Or like this?
<div>
text text <span></span> <span id="firstDivSpan" class="commonStyle"></span>
</div>
<div>
text text <span></span> <span id="secondDivSpan" class="commonStyle"></span>
</div>
.commonStyle{...}
What's better?
ID selectors are the fastest. That is not bad practice at all; you're simply operating under the assumption that there will only be one element with that ID on your pages.
That said you shouldn't abuse IDs for lame reasons like rendering performance. Use IDs to mark truly unique elements, not to mark everything so you can forget about stuff like descendant combinators, classes, groups etc. Those other selectors are what make CSS so powerful, not just the ID selectors.
Re question edit: there isn't any better one in this case. Performance issues aside (because they don't matter at all) it largely depends on the meaning of the selectors.
If your styles apply to any element with the .commonStyle class then use the class selector. If you only want to target those two specific spans regardless of the class then the ID selectors are more appropriate.
It is better to use the ID like in your example.
It is easier for the browser to fetch a particular ID element rather than have to find all parents, then descendants...
As someone expanded on my answer in a separate thread, article regarding this: http://www.css-101.org/descendant-selector/go_fetch_yourself.php
ID, class, element name - they are all CSS selectors.
Related
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>
For example:
<div class="menu">
<div class="menu__item">
<div class="menu__item-title">
</div>
</div>
</div>
There's some solution like menu__title.
But if menu has its own title, then how to recognize menu's title and menu item's title?
The main difference is that block__element__element is not a valid BEM selector. The markup you showed in your question is the CORRECT way of naming your elements.
Create a block
If a section of code might be reused and it doesn't depend on other
page components being implemented.
Create an element
If a section of code can't be used separately without the parent
entity (the block).
The exception is elements that must be divided into smaller parts –
subelements – in order to simplify development. In the BEM
methodology, you can't create elements of elements. In a case like
this, instead of creating an element, you need to create a service
block.
More info in the official documentation: https://en.bem.info/methodology/quick-start/#should-i-create-a-block-or-an-element
If you want to have Menu title, the markup should look something like this:
<div class="menu">
<h2 class="menu__title">..</h2>
<div class="menu__item">
<div class="menu__item-title">
</div>
</div>
</div>
BEM gets a bit tricky when you have "children" of an element. But either use the menu__item-title naming convention or rethink your element, perhaps it can be separated and reused as a Block?
I just started out using BEM and SMACCS for my stylesheets but have run into some trouble as far as naming deeply nested elements in the DOM. Say for instance I have a div called .main-container. Nested inside the first level of the main-container is an additional div which by convention would be named .main-container__article.
<div class="main-container>
<div class="main-container__article></div>
</div>
This is where things get confusing. Inside that article div let's say I have a header followed by a paragraph that has a nested span tags. Do I continue prepending classes with main-container__article as so?
<div class="main-container>
<div class="main-container__article>
<h1 class="main-container__article__header">Heading</h1>
<p class="main-container__article__copy">
<span class="main-container__article__copy__intro-text>Example text.</span>
</p>
</div>
</div>
How far down does the rabbit hole go when it comes to naming parent/child elements? Is there a point where you reset at the second-level element and go from there?
<div class="main-container>
<div class="article>
<h1 class="article__header">Heading</h1>
<p class="article__text">
<span class="article__text__intro-text>This is example text.</span> for a paragraph
</p>
</div>
</div>
BEM naming shouldn't resemble DOM structure because otherwise you won't be able to change markup without changes in CSS.
So for your example I'd make it like this:
<div class="main-container">
<div class="article">
<h1 class="article__header">Heading</h1>
<p class="article__copy">
<span class="article__intro-text">Example text.</span>
</p>
</div>
</div>
There's also a quite powerful thing called mixes, which gives possibility to mix different BEM entities on the same DOM node:
Heading
Example text.
So now you may apply CSS to article block and main-container__article element separately which is very useful when you need to reuse article outside main-container.
.main-container__article__copy__intro-text
definitely doesn't help the readability and maintainability of your stylesheets.
I suggest to break such giant blocks into several smaller blocks. If you do this, you can reuse your styles - in your example you couldn't use the article-block somewhere else.
I would "reset" everytime you can encapsulate a block which can potentially be used in several places in your app/website.
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
This is my problem: I have to select and remove ALL the elements that follow one precise element.
Here an example of how my webpage is structured:
<h2>
<span class="myClass" id="Note">Note</span>
</h2>
<ol class="secondClass">...</ol>
<h2>...</h2>
<ul>...</ul>
<h2>...</h2>
<ul>...</ul>
<table class="tableOne">...</table>
<div class="otherClass">
In particular i have to delete ALL elements after <span class="myClass" id="Note">Note</span>
I read a lot of topic about the NextAll() Jquery Selector, but however I can't manage to solve my problem.
.nextAll() targets siblings and your span doesn't have any. Perhaps you should be targeting its parent. Eg,
$(".myClass").parent().nextAll().remove()
The problem is that nextAll only gets sibling elements. For a generic solution to this problem, if you use nextAll you would need to call it on the element and all parent elements:
$(".myClass").parents().andSelf().nextAll().remove();