Using BEM methodology and a small file size - css

I'm trying to dive into the BEM methodology. Even though it seems to be the 'must have' methodology for all project sizes, I'm kind of unhappy with it or am I just trying to use it the wrong way?
Using BEM the CSS gets divided into something like this.
.block {
/* Block code goes here */
}
.block--is-hidden {
/* Block modifier code goes here */
}
.block__element {
/* Element code goes here */
}
This seems to be pretty fine for me, as long as you do not reuse some code. Let's assume I'm using Bootstrap or any other CSS Framework/Library. Doing so I just want to use the grid. That being said my markup could look somehow like that.
<div class="container">
<div class="row">
<div class="col-xs-12">
...
</div>
</div>
</div>
According to BEM this would be a no go. Instead all the grid classes should be wrapper up in our corresponding block and element classes. A possible way to achieve this would be through SASS and it's #include. For me this basically results in redundant code.
So my question right now is. Am I missing something? I mean, using BEM while for e.g. loading Bootstraps .container code into every single of my own block styling would just result in an massive output CSS file. Is my approach correct? And if so - would I really sacrifice initial loading time just for the idea of better organized CSS and better readable markup?

Is there a reason your blocks have to begin at the container level? I'm not sure if it's a violation of BEM methodology exactly, but I personally "begin" my blocks more at the html>body>.container level. So:
<html>
<body>
<div class="container">
<div class="cheesecake">
<h1 class="cheesecake__heading"></h1>
</div>
</div>
</body>
</html
With SCSS looking something like:
.cheesecake {
&__heading {}
}
And so on.

Related

Naming A Wrapper Element Class When Using BEM

I understand that when using BEM, the classnames should not directly reflect the HTML structure, but how should a wrapper element be named? Please ignore my particular syntax(close to SUIT); it still follows BEM, just with a different way of differentiating the elements.
For example:
<div class="?">
<footer class="PageFooter">
<h4 class="PageFooter-brand>…</h4>
<ul class="PageFooter-contactDetails">…</ul>
</footer>
<div>
I would currently class the wrapper in this instance as PageFooterWrapper, but this feels clunky because the wrapper is not independent - it exists purely for the PageFooter. Obviously prefixing everything with PageFooter- is ridiculous, so that only leaves treating the wrapper as a part of PageFooter: PageFooter-wrapper. This irks me as there is an implied suggested applied by this.
So what should the class of the wrapper be?
The way i've always treated it is the wrapper should always be the block so:
<div class="PageFooter">
<footer class="PageFooter-inner">
<h4 class="PageFooter-brand">...</h4>
<ul class="PageFooter-contactDetails">...</ul>
</footer>
</div>
The Block contains Elements so instead of having something around my Block i just followed along with the Element principle and started using inner's instead of containers
I've actually used two classes successfully, my pattern is as follows:
<div class='page-section bem-block'>
<div class='bem-block__element'>
<!-- etc etc -->
</div>
</div>
Effectively using a utility class to perform certain wrapper functions. The css would likely be similar to this:
.page-section {
width: 100%;
}
#media screen and (min-width: 1200px) {
margin: 0 auto;
width: 1200px;
}
I've found this works well in practice. It would also be possible for .bem-block and it's contemporaries to inherit from .page-section.
This solution complements Dan Gamble's.

How to write this 'OR' CSS selector?

Here is an HTML fragment:
<div class="wrapper">
<div class="ebook">
<div class="page"></div>
</div>
<div class="book">
<div class="page"></div>
</div>
<div class="document">
<div class="page"></div>
</div>
</div>
I want to match all divs with the page class with parents divs having ebook or book classes only. This selector can be used:
div.ebook div.page, div.book div.page
However is there a CSS engine suporting the following syntax ?
(div.ebook, div.book) div.page
or better
div.?book div.page
I'm not interested with a solution like this: div:not(.document) > div.page.
The proposed syntax takes the form of a functional pseudo-class called :matches():
/* As this is a pseudo-class, you can make it a little DRYer by saying
div:matches(.ebook, .book) div.page instead */
:matches(div.ebook, div.book) div.page
If you really want to get technical, Firefox implements it as :-moz-any():
:-moz-any(div.ebook, div.book) div.page
and Chrome implements it as :-webkit-any():
:-webkit-any(div.ebook, div.book) div.page
(and these actually came first prior to the selector being specced as :matches())
But if you're using them in CSS you will have to duplicate your rulesets because of certain CSS parsing rules, which is as good as not using them at all (in fact, worse). These selectors are meant for internal use only, not for production.
What you currently have is the only viable option for now.
If you want to cheat a little, you could use a substring attribute selector, but that assumes each of those elements will have exactly one class only, and no other class names will match by this particular substring (this is similar to the div.?book example you have, but it comes with the limitations of an attribute selector that are not present in a class selector):
div[class$="book"] div.page
Personally, I'd just stick with the verbose option because it's more robust.
Check out this Fiddle that should do what you're looking for:
http://jsfiddle.net/Delorian/L44u0p8r/
div[class$="book"] {
background-color: yellow;
}
Further details: https://stackoverflow.com/a/9836182/3264286
There is no such thing as an OR selector in CSS, except for as in the example you gave, where a comma (,) can be used to separate multiple selectors e.g;
div.ebook div.page,
div.book div.page{
// CSS properties
}

CSS Position from non-parent element

I have a coding restriction that I cannot change and trying to find a way around it, to position a div based on a non parent.
I have the following code structure, which cannot be changed:
<div class="row">
<div class="sub-row01"></div>
<div class="sub-row02"></div>
</div>
<div class="row">
<div id="sub-row03"></div>
</div>
What I am trying to do is position #sub-row03 in relation to .sub-row02. Anything that I have tried, will only allow me to position #sub-row03 in relation to first .row
Is what I am trying to achieve even possible? If so, what would be the proper way to style it?
To answer your question it is not possible with pure css since it only allows styling using the parent or a preceding child.
For example
a + b { } will style b
a ~ b { } will style b
a > be {} will style b
but there is no way to style a in these cases.
You can however do this via javascript. If you want to go this route you could do something like:
document.getElementById("sub-row03").style.left = document.getElementById("sub-row02").offset().left;
I can write something a bit more concrete if necessary as I have not tested it but it should help with the basic concept.

Using CSS selector specifity over selector ID's?

In class we are teached to avoid creating ID's in your HTML so you can use them to identify that element in your CSS file. Instead we must use selector specifity as much as possible.
Take for example this simple HTML:
<body>
<div>
<div>
<div>
The div you want to style.
</div>
</div>
</div>
</body>
Is it better to use this:
body > div > div > div{
color: blue;
}
or give the element an id (let's take 'middle') and use this:
#middle{
color: blue;
}
What are the differences (if any at all) performance and usability wise?
The difference in speed between IDs and Classes in modern browsers is so negligible in real world situations it is really not an issue. Therefore current main-line thinking is to use classes where extra clarity and specifity is needed. This way you avoid specifity wars and balances maintainability with code purity.
<body>
<div>
<div class="more-specific-if-needed">
<div class="middle">
The div you want to style.
</div>
</div>
</div>
</body>
.make-more-specific-if-needed .middle {
/* cool styles */
}
Or even use chained selectors to gain extra specifity. You could then split styles in to separate structure based build styles and appearance based theme styles.
<body>
<div>
<div>
<div class="semantic-role theme">
The div you want to style.
</div>
</div>
</div>
</body>
.semantic-role.theme {
/* cool styles */
}
For further reading:
http://csswizardry.com/2011/09/writing-efficient-css-selectors/
Why do browsers match CSS selectors from right to left?
Performance wise it's fastest to get an element by its id than it is to traverse the dom.
From a usability point of view I would be careful using too many id's since they can be only used once for an element.
So it's a question of what you think is more important and how many items we are talking about. Is the speed gain worth the losing of re-usability
Much better to use ID. Performance difference is minimal, and not the important point. I think code readability / maintainability is more important.
One advantage of using ID, is that you could move your element to a different part of the page, and it would retain it's style rules - without counting the containing elements.

Calculate a margin using CSS percentage and unit together

margin-left: 100 + 20%;
I want to do something the same as above. But CSS does not have any format. How can I successfully use these together ?
Without javascript? Only by wrapping that content into another element (usually <div>) and splitting that margin to two elements.
Something like:
<div style="margin-left:20%">
<div style="margin-left:100px">
<!-- content -->
</div>
</div>
Hi there and welcome to StackOverflow. Unfortunately CSS doesn't have this (good) behaviour, but LESS will. For a JavaScript implementation, look here. If you want a PHP implementation, look here. You may be confused as to why I'm talking about JS and PHP, but what LESS will do is take your .less file and turn it into a vanilla CSS file, either on the client (JS), or on your server (PHP).

Resources