I am aware that this is asking for a very opinionated answer, as are all naming-convention related questions, I guess.
I am using Harry Roberts BEMIT naming convention, which augments BEM with prefixes/namespaces for object-oriented css.
That allows organizing classes into objects, using the o- prefix, for decoration-free design patterns like the famous media object, and styled ui-components, using the c- prefix (plus some more).
Here is the (generic) example, that is often used in the context of explaining BEM, augmented with the problematic namespaces:
.o-btn {
width: 100%;
}
And here the competing scope, targeting the same (bem)block
.c-btn {
color: white;
background: gray;
}
.c-btn--positive {
background: green;
}
.c-btn--negative {
background: red;
}
To quote the relevant part from Harry Roberts CSS Guidelines (not enough cred to post 2nd link, sorry):
Above, we can see how the .btn {} class simply provides structural styling to an element, and doesn’t concern itself with any cosmetics. We supplement the .btn {} object with a second class, such as .btn--negative {} in order to give that DOM node specific cosmetics.
This explanation to me sounds like the exact justification to do as I did.
Still, it feels incorrect, to use two different namespaces on the same block, possibly confusing.
Which namespace do I chose, if two of them are competing?
Don't be afraid of having different BEM entities on the same DOM node.
Actually pure BEM itself solves this issue with the help of mixes (see https://en.bem.info/methodology/key-concepts/#mix).
The idea is that you should keep button block as universal component with maximum reusability. Then you may add all the cosmetics with the help of theme modifier. And finally add positioning with a help of mix with parent's element (e.g. form__submit).
So you may end up with something like this:
<form class="form">
<button class="button button--theme_awesome form__submit">Send</button>
</form>
You use what your projects require, in my case I much prefer the prefixed syntax (o-, c-, u-), because you're telling to your html elements what they are, a short example using sass syntax:
.c-button{
&.c-button--dark{}
&.c-button--orange{}
}
and you can overwrite bootstrap classes, for example, you don't have to take care about other classes, with this specification you are able to overwrite the default classes you might have, and you can have a mix of css classes in your hmtl element, for example:
<input type="text" class="btn btn-primary c-button c-button-dark" />
Related
I just wanted to know whether the following code follows BEM methodology best practices? Creating an element for the block modifier i.e. in this case "block--mod" is a modifier for the "block" block. Is it allowed to create a nested element with this pattern: "block--mod__elm".
<div class="block block--mod">
<div class="block__elm block--mod__elm">
</div>
In situations like theming or similar I would use nested selectors. This saves some classes in your HTML and as #Jonathan Nicol said those sub-elements can be hard to follow. Also it will be easier to remove the "branding" later, just remove block class instead of all it's elements.
For example Xmas branding of your header.
.header--xmas .header__logo {
/* Jingle bells, jingle bells, jingle all the way.*/
}
Source: http://getbem.com/faq/#can-a-block-modifier-affect-elements-
I could not find an example of a the .block--mod__elem pattern in Yandex's BEM documentation (Yandex devised the BEM methodology), but an early article about BEM on CSS Wizardry does show an example of a modifier with a sub-element, .person--female__hand:
.person {}
.person__hand {}
.person--female {}
.person--female__hand {}
.person__hand--left {}
Source: MindBEMding – getting your head ’round BEM syntax
Modifiers with sub-elements can be a little hard to follow, but I do not shy away using from them if it seems like the logical approach.
Edit: #NikolayMihaylov's answer gives an alternative approach that I wholeheartedly support. It is more readable and more maintainable.
Hello and thank you for taking your time to read my question. My question pertains to html best practices.
I have a html skeleton that looks like this..
<!DOCTYPE html>
<html lang="en">
<head>
<title>Template</title>
<meta charset="utf-8">
</head>
<body>
<header>
</header>
<main>
</main>
<footer>
</footer>
</body>
</html>
and I want to start adding HTML elements that I will later select these elements by ID and CLASS within CSS and JavaScript. My "Best Practice" related questions are..
Do ID and CLASS have identical naming conventions?
What is the minimum and maximum recommended ID and CLASS attribute length?
Why do websites like facebook name there ID and CLASS atributes with random
numbers and letters?
Should I use camelcase?
Should I use underscores or numbers?
Should I shorten words with abbreviates like "Detail" becomes "Det" when naming?
Should I give ever elements that is a child of body a ID and CLASS atribute?
Would I ever need to specify an ID or CLASS attribute for a element within the HEAD element?
Some of these answers are down to personal preference:
Do ID and CLASS have identical naming conventions?
The naming conventions are up to you.
What is the minimum and maximum recommended ID and CLASS attribute length?
There are, as far as I know, no such recommendations.
Why do websites like facebook name there ID and CLASS atributes with random numbers and letters?
To avoid accidental duplication and for tracking purposes.
Should I use camelCase?
It's one good option.
Should I use underscores or numbers?
These are more good options.
My own system (I don't know anyone else who uses it) is the following:
HTML - <div class="my-string"> [hyphens]
CSS - .my-string [hyphens]
Javascript - var myString = ''; [camelCase]
PHP - $My_String = ''; [underscores]
By using different syntax for variables and classes, I avoid mixing up different types of data.
Should I shorten words with abbreviates like "Detail" becomes "Det" when naming?
You can but personally I wouldn't. But it's up to you.
Should I give ever elements that is a child of body a ID and CLASS atribute?
Not sure I understand this question.
Would I ever need to specify an ID or CLASS attribute for a element within the HEAD element?
No. There is no need for this.
I feel like an updated answer is warranted here. These are obviously guidelines and opinions, but also informed by my observations of what conventions are defacto community standards and/or widely adopted.
PHP
Variables, functions and method names should be camelcase:
$myVariable = 'foo';
Class names and interfaces should be Pascal Case
class MyClass implements MyInterface { .. }
PHP has two widely adopted standards that cover this and much more in regards to code standardization, and many of these standards are followed by the major PHP project like Laravel and Symfony. Those standards are documented in PSR-1 and expanded/revised in PSR-12.
HTML
HTML5 is the document standard, which also expanded content specific tags.
Beyond that, there's been a move towards lowercasing everything, where in the early days people often uppercased the names of any tags, even though that didn't matter.
As of 2023, lowercase your names. If you have multiple words in a name separate the words with hyphens.
Consider attribute naming of things like the data attributes as representing the emergence of this convention.
<div id="my-products" name="my-products" data-category="5">
CSS
I've seen fairly wide adoption of BEM as well as the emergence of css frameworks beyond bootstrap, like materialUI and Tailwind.
BEM also is helpful in thinking about how to organize styles for html "components" where you have a nested grouping of elements that equate to a page component.
<style>
.btn {
border: none;
color: white;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
padding: 12px 28px;
cursor: pointer;
}
.btn--submit {
background-color: green;
}
/* a product card component with styles for each child element of the component */
.product-card { .. }
.product-card__title { .. }
.product-card__image { .. }
.product-card__price { .. }
.product-card__description { .. }
.product-card__order-button { .. }
/* used if item out of stock */
.product-card__order-button--disabled { .. }
</style>
Javascript
Javascript and PHP conventions are very similar. Google has published a js coding style guide similar to those that came from the PHP framework interop group I linked to above.
The major js frameworks (angular, react, vue, etc) sometimes have conventions specific to them, that are worth researching.
Variables camelcase
let myObj = { name: 'Michael' }
Classes uppercase
class MyClass {
constructor() { .. }
}
PYTHON
The Python manual has a link to 2 extension proposal documents
PEP-8 For Coding Style
PEP-257 For Docstrings
To summarize the basics:
Variables and functions should be lowercase with underscores between words
Use Pascal Case/Studly caps for Classes
my_variable = 'Something'
class MyClass:
Python styles is explored more fully in this question.
I only included the languages most typically involved in Web Development as that was the focus of the original question, as well as the accepted answer.
So I want to select the <div> element with the class .thisClass, but not any other elements with class of .thisClass:
<div class="thisClass"></div>
<p class="thisClass"></p>
CSS Selector by class name and tag: div.thisClass { ... }:
div.thisClass {
background-color: red;
}
<div class="thisClass">thisClass (div)</div>
<p class="thisClass">thisClass (p)</p>
But this is a bad way to write selectors:
Don’t qualify class rules with tag names
The previous concept also applies here. Though classes can be used many times on the same page, they are still more unique than a tag.
One convention you can use is to include the tag name in the class name. However, this may cost some flexibility; if design changes are made to the tag, the class names must be changed as well. (It’s best to choose strictly semantic names, as such flexibility is one of the aims of separate stylesheets.)
BAD
treecell.indented {…}
GOOD
.treecell-indented {…}
BEST
.hierarchy-deep {…}
Using JavaScript
document.querySelector('div.thisClass')
Using jQuery
$("div.thisClass")
Using CSS:
<style>
div.thisClass{}
</style>
The following code illustrates how to select the first class from the list of classes in both CSS and Javascript.
CSS
.thisClass:first-child {
/*css property*/
}
JAVASCRIPT:
var divElement = document.getElementsByClassName('thisClass')[0];
Instead of using the standard class="someclass", I deviated from this pattern and "tagged" the div thus:
<html>
<head>
<style type="text/css">
div[tag1]
{
background-color:Red;
}
</style>
</head>
<body>
<div tag1>test</div>
<div>test</div>
</body>
</html>
What are the drawbacks of this approach (besides the obvious fact that it might confuse some developers)?
Will it work in any browser? (I checked FF, IE and Chrome - it worked in all of them)
To me, it looks more concise than using "class".
Thanks!
I see a few drawbacks to your approach
Specificity: All attributes in the element, with exception to the ID, are parsed as classes. By choosing to go with <div someAtt>, this is always going to have the specificity of a class: 0,0,1,0.
Selectors: You don't make shorter selectors:
The class of an element is also an attribute. You could select an element that has a class like so:
[class="tag1"]{
color:red;
}
This, in fact, is the "normal" way to select an element with an attribute which has a value. The manner in which we select classes is more of a shorthand for the above rule:
.tag1{
color:red
}
Because you're proposing a custom attribute, your selector will be:
[tag1]{
color:red
}
If you're counting characters, the "longhand" attribute selector takes the most space and the class selector the least. You're not making a stylesheet shorter with your approach. Your selector will always be longer by at least one character. Is this a huge deal? No. But it will be over time, and now you have to train someone who takes over your stylesheet on your approach.
Extensibility: Another issue with adding an invalid attribute to your markup is extensibility. Your goal should be extensible markup and CSS, so you want a pattern that's reusable. if you're going to have tag1, tag2, etc, this isn't an extensible pattern.
How do you plan on dealing with reusable styles? What you're saying is that <div tag1 tag2 tag3 tag4> could happen at some point in the future. How do you plan on styling that?
div[tag1][tag2][tag3][tag4]{
color:red;
border-color:red;
outline-color: red;
background-color: red;
}
[tag1]{
color:red
}
[tag2]{
border-color:orange
}
[tag3]{
outline-color:yellow
}
I see tag as a reusable attribute which can accept a changing value:
<div tag="one">
Which results in this selector:
[tag="one"]{
color: green
}
Which ultimately means you have replicated the "class" approach, but with a longer selector and no means to a shorthand (like the . that's the same as [class=""].
Valid Markup: The next issue I see in your approach is that you're using invalid attributes. In HTML5, you can use the data-* approach to pretty much create whatever attributes you want in a somewhat normalized pattern. But invalid attributes such as tag1 could throw off any HTML validators. Additionally, I don't know how screen readers or other accessibility devices might struggle with invalid or unknown attributes.
The Neighborly Way: The final issue that I see is more philosophical. We get a heck of a lot more freedom and flexibility in HTML and CSS than in other development languages. Web browsers are much, much more forgiving of mistakes that we make in HTML and CSS than compiled languages. We shouldn't equate the freedom to be different to the wisdom of following standards and best practices.
The only drawback I can think of is that you lock your css to a tag type. ie with class you could do:
<div class="alignRight"> Some thing </div>
<table class="alignRight">table data</table>
Your approach does not allow for this. Apart from this I don't think it's any technical issue with using your approach.
As HTML code reviewer, sometimes reading an html code I see something like this:
<form class='form' …>
Even if it is allowed, I am wondering if this kind of stuffs, having class name equal to the tag name, should be deprecated independently by the context.
P.S.:
possible context:
<form class='form'>
</form>
<div class='form'>
</div>
It would make no sense to have the class be the same name, the whole point of classes is so you can assign an obvious naming structure to an element so e.g.
.login-form { }
.shopping-form { }
If the form has the class name of form to it just means it has a poor naming structure and if the form class is applied to all forms then they may as well of just applied to it to:
form { }
not
.form { }
So while it's allowed it's just bad practice and unnecessary if they are just using one class for all forms.
Class names should be considered as being selectable by authors or communities of authors by agreement. I don’t think it’s appropriate to “deprecate” names just because they look odd on first sight. The word “form” may have different meanings in different languages and communities. There might be all kinds of reasons for something apparently odd like <form class="form"> even if class names have been taken from English. In inspecting code, such constructs should raise question, not trigger automatic disapproval.
(I almost proposed closing the question as non-constructive. But maybe there is some value in pointing out the problems in the assumptions behind the question.)