BEM naming from unique to repeating elements - css

I have code like this
<div class="chatlist-container chatlist-container_hidden">
<div class="container-header">
<span class="chatlist-title">
</span>
<div class="container-header__button">
<span class="icon-minus"></span>
</div>
<div class="container-header__button">
<span class="icon-cancel"></span>
</div>
</div>
<dl class="chatlist-container__chatlist">
<div class="chatlist-container__chatgroup">
<p ...
<div ...
</div>
<div class="chatlist-container__chatgroup">
</div>
<div class="chatlist-container__chatgroup">
</div>
</dl>
</div>
Where chatlist-container is a main container, then goes container-header , which can be reused in another containers, so he named without dependency chatlist-container__, then goes chatlist-container__chatlist, which exists only inside chatlist-container so he named with his dependency, and then goes chatlist-container__chatgroup, groups which can repeat but only exists inside chatlist-container, how to name their childs, with or withoud dependency of chatlist-container ?
I imagine this like chatlist-container__chatgroup-title and chatlist-container__chatgroup-description, right? But if so, if description will have and childs later, their naming can be very tricky and long.
Also, if so, how to write css, now it looks like:
.chatlist-container { ...
.chatlist-container .chatlist-container__chatlist { ...
.chatlist-container .chatlist-container__chatlist .chatlist-container__chatgroup { ...
But if i add child elements to my groups, their selectors are getting kilometer long, and looks like this
.chatlist-container .chatlist-container__chatlist .chatlist-container__chatgroup .chatlist-container__chatgroup-title { ...

A different approach to the naming could be taken, if you so desired.
You mentioned that other containers exist, and that chatlist_container is only one type of a container, which makes me think that perhaps there should be a container class somewhere with the chatlist version being a modifier, i.e. container--chatlist.
Also, in my opinion, just because chatgroup currently only exists within the chatlist container doesn't mean that it has to have the container's name prefixed to it. Giving it a name like chatgroup allows it to be used outside of the container at some point perhaps. Then any of its children only need to have chatgroup prefixed to their names.
This is not an answer, as you know what you are building far more than any of us here, but perhaps these thoughts might lead you to rethinking the current naming scheme and thus making things easier for yourself.

If maintainability is the issue, i'd suggest using a preprocessors such as sass would help out.. Sass has a functionality with nesting and using the & sign to avoid long rules, pseudo example code:
.wrapper {
height: 100%;
.b-header {
display: flex;
background: #F5F5F5;
flex-direction: column;
padding: 0 2rem;
margin-top: 2rem;
&__about {
width: 100%;
padding: 2rem;
word-wrap: break-word;
.title {
font-size: calc(1.5rem + 3vw);
margin-bottom: 5rem;
}
.job {
font-size: calc(1.8rem + 3vw);
margin-bottom: 1.5rem;
}
.cv {
display: inline-block;
font-size: calc(0.5rem + 3vw);
margin: 3rem 0;
}
}
&__image {
img {
min-width: 100%;
max-width: 100%;
}
}
}
}

Related

How to exclude some class when parent class is selected

I'm sorry if this is a silliest question that you've ever found. I wanna find some "shortcut" to make this happen. Here's the example:
<body>
<div class="wrapper">
<nav></nav>
<aside></aside>
<footer></footer>
</div>
</body>
I wanna give some style into the all of .wrapper content, except for the footer. Is it possible to handle it? Or... Is there any CSS selector for an exception?
NOTE: Please don't give me an "easy way" solution like this:
nav {
//some style
}
aside {
//some same style
}
Thats quite easy. Just do it as follows:
.wrapper > *:not(footer) {
color: green;
}
This may be helpful.
The * refers all elements and *:not(footer) says all elements except footer element.
This .wrapper *:not(footer) stands to select all elements except footer inside .wrapper class.
This is how it works.
.wrapper *:not(footer) {
display: inline-flex;
justify-content: center;
align-items: center;
background-color: #cccccc;
color: #000000;
}
<body>
<div class="wrapper">
<nav>01</nav>
<aside>02</aside>
<footer>03</footer>
</div>
</body>

BEM naming and positioning

I'm new to BEM and i'm trying to implement this:
.details-header {
margin-top: 10px;
padding-bottom: 0;
display: block;
&__heading-panel {
margin-top: 10px;
}
&__heading {
display: inline-block;
}
}
Defining the same margin-top inside details-header__heading-panel is wrong, i know, but because there is element between details-header and details-header__heading-panel, i need this margin, how do i solve this, and also keep the code DRY?
EDIT: Here is the html:
<div class="details-header">
<div>Something</div>
<div class="details-header__heading-panel">
<h1 class="details-header__heading">
<span>something</span>
</h1>
<a>
Link
</a>
</div>
</div>
I need margin between that div between details-header and details-header__heading-panel
There's nothing wrong with defining the same margin-top inside details-header and details-header__heading-panel. Just keep going with your original code.
It's not copy-paste but just coincidence.

text align in html/css [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
As you can see the text is not properly aligned.
I want the text to be displayed like these and it should be justified also:
Ethics/Moral:Respect for mankind,the environment and fglll
nature without exceptionRespect for mankind,the
environment and nature without exception
The next line should start at the same point as the previous line.
How can I do it in css
#MuFFes mentioned the css properties text-indent, but I prefer to use dl, dt, and dd elements.
dt {
float: left;
clear: left;
width: 100px;
text-align: right;
font-weight: bold;
}
dt:after {
content: ":";
}
dd {
margin: 0 0 0 110px;
padding: 0 0 0.5em 0;
}
<dl>
<dt>Ethics/Moral</dt>
<dd>Respect for mankind, the environment and nature without exception.</dd>
<dt>Honesty</dt>
<dd>Treating everyone with sincerity and integrity.</dd>
<dt>Quality/Safety</dt>
<dd>Mankind and the environment, the product and its utilization -achieving the optimum together.</dd>
</dl>
By using flex you can do like this
Note, the br I added is merely there to show how it behaves when breaking line
.row {
display: flex;
}
.row ~ .row {
margin-top: 5px;
}
.row div:first-child {
color: steelblue
}
<div class="row">
<div>
Ethics/Moral:
</div>
<div>
Respect for mankind, the environment and<br>nature - without exception
</div>
</div>
<div class="row">
<div>
Honesty:
</div>
<div>
Treating everyone with sincerity and<br>integrity
</div>
</div>
and if you need 2 even columns and have dynamic content, use display: table-row/table-cell
.row {
display: table-row;
}
.row div {
display: table-cell;
}
.row ~ .row div {
border-top: 10px solid transparent;
}
.row div:first-child {
color: steelblue
}
<div class="row">
<div>
Ethics/Moral:
</div>
<div>
Respect for mankind, the environment and<br>nature - without exception
</div>
</div>
<div class="row">
<div>
Honesty:
</div>
<div>
Treating everyone with sincerity and<br>integrity
</div>
</div>
Side note:
As Paulie D very well pointed out, dl/dt/dd is likely the most semantically appropriate markup, though my suggested styling might give you the wanted result. Feel free to combine the two
I think that using ::first-line pseudoelement is the best you can do in that case. Try:
::first-line {
text-indent: -40px;
}
You have to adjust text-indent by yourself.
It would be also a little bit easier with the sample of your code.

Should module child elements be nested in module modifiers?

When writing css using BEM if you need to make changes to a module element when it is in a sub-module do you nest the module-element in the sub-module or create a new class name for the module-element?
Creating a New Class
Creating a new class name(i.e. module--modifier__element) seems to be more in the spirit of BEM. It prevents unnecessary specificity. But it also adds a lot of extra work adding an extra class to each element within the module.
Nesting
Nesting the existing element class within the module modifier(i.e. module--modifier module__element {} will add some extra specificity but saves you a lot of work(at least for large modules) and makes the markup easier to maintain. For example if you needed to change the modifier of a module you would only have to change it one place in the markup rather than having to change it on every child element.
In addition to that if not all of the child elements change then you will have to refer to the css to figure out which child elements need a class added to them.
EXAMPLE CODE
.module {
display: block;
width: 90%;
height: 2rem;
margin: 2rem auto;
padding: 0.5em;
background: #fff;
border: 2px solid #333;
}
.module--modified1 {
background: #333;
border: none;
}
.module--modified2 {
background: #baa;
border: 3px solid #8f8;
}
.module__element {
color: #333;
text-align: center;
}
/* Option 1 */
/* In sass this would actually be nested within the module_modified1 block */
.module--modified1 .module__element {
color: #fff;
}
/* Option 2 */
.module--modified2__element {
color: #fff;
font-size: 1.3em;
}
<div class="module">
<div class="module__element">Module</div>
</div>
<div class="module module--modified1">
<div class="module__element">Module Modifier 1</div>
</div>
<div class="module module--modified2">
<div class="module__element module--modified2__element">Modulue Modifier 2</div>
</div>
Both options are valid. Reduce the specificity is a good practice, but make the code simple is also a good practice.
However, BEM blocks have to be context-free. If a block can be recursively included into itself, then cascades must be avoided. For example, a generic block fun-rounded-block could be recursively reused like this:
<div class="fun-rounded-block fun-rounded-block--blue-version">
<div class="fun-rounded-block__content">
<div class="some-block-here">
<div class="fun-rounded-block">
<p class="fun-rounded-block__content">element in the sub-block here</p>
</div>
</div>
</div>
</div>
In this example, you cannot use a cascade for styling elements because the selector .fun-rounded-block--blue-version .fun-rounded-block__content would interfere with the sub-block.

Need assistance with CSS - aligning data without tables

I am trying to learn CSS, especially I am trying to get away from tables, which are so easy to use.
I created jsfiddle to see what I have done:
http://jsfiddle.net/HMtSY/
I can't align all data into proportional cells. Please assist
<div class="cartItem">
<span class="cartProductTitle">Product</span> <span class="cartProductModel">
Model</span> <span class="cartProductPrice">Price</span>
<span class="cartProductQty">Qty</span> </div>
<div class="cartItem">
<span class="cartProductTitle">This is the product title</span>
<span class="cartProductModel">mdsdre12es</span>
<span class="cartProductPrice">9.95</span> <span class="cartProductQty">1</span>
</div>
<div class="cartItem">
<span class="cartProductTitle">Product 2</span>
<span class="cartProductModel">mds12es</span> <span class="cartProductPrice">
1119.95</span> <span class="cartProductQty">199</span> </div>
<div class="cartItem">
<span class="cartProductTitle">This is the product title product 100000</span>
<span class="cartProductModel">as</span> <span class="cartProductPrice">9.95</span>
<span class="cartProductQty">22221</span> </div>
//CSS
.cartItem
{
display: table-cell;
padding: 5px;
width: 600px;
min-width: 600px;
float:left ;
}
.cartProductTitle
{
display: table-cell;
padding: 5px;
width: 350px;
min-width: 350px;
}
.cartProductModel
{
display: table-cell;
padding: 5px;
width: 150px;
min-width: 150px;
}
.cartProductPrice
{
display: table-cell;
padding: 5px;
width: 30px;
min-width: 30px;
}
.cartProductQty
{
display: table-cell;
padding: 5px;
width: 30px;
min-width: 30px;
}
Not all tables are evil!
Tables for layout are, but this isn't tables for layout, you're displaying tabular data, as in, data which should be displayed with a table!
This means that using a table in your case is perfectly acceptable, and even the correct solution.
So yes, use a table in this case. It's not layout, so it's fine :)
You are creating problems rather than solving them, since an HTML table is the right approach here, but if someone insists, it is possible to simulate HTML tables in CSS (and this might even be meaningful if your data format is generic XML and not HTML). You just need to specify display: table-row for elements that structurally correspond to table rows, like .cartItem elements in your case. (It would also be natural to wrap all such elements in a container, for which you set display: table.)
So just set .cartitem { display: table-row } and remove the float settings. It is natural to remove all the width settings, letting browsers determine the widths of columns, which is one of the basic advantages of using tables (in HTML or as emulated in CSS). Moreover, the last two cells of each row should be right-aligned, as they contain numeric data.
See jsfiddle.

Resources