A small guide for naming stuff in front-end code
blog.frankmtaylor.com
blog.frankmtaylor.com
Somewhere else on my blog is an article about using BEM with content management systems (which is my area of specialization). I basically endorsed your exact practice, but with __content models__.
The idea being that a content model could have multiple presentations (views), but still relies on a single core .... data model. So the Block is that data model and the modifier is the view.
So your practice is 100% what I would endorse. This is a sample of the CSS guidelines I'd produce for my teams where you'll see that I explain it a bit more: https://gist.github.com/paceaux/f31e278613ab29b74a412a7eb504...
Doesn't this go against the conventions of the most popular CSS libraries that your code will likely be used with? It's a pain and ugly that JavaScript and CSS don't use the same conventions though.
The IDE select issue is probably fixable e.g. https://stackoverflow.com/questions/45590695/visual-studio-s...
// you have a variable isFoo
<SomeComponent className={classNames({isFoo})} />
is a lot better than: // you have a variable isFoo
<SomeComponent className={classNames({'is-foo': isFoo})} />
(also, I personally shorten `classNames` to `cn` because it's so universally useful)So, for that reason, when I wrote these guidelines internally some years ago, we weren't concerned in the least with what CSS libraries were doing because we didn't use them. We were concerned with consistency, more than anything
We went with camelCase because we liked that it was the same convention we followed in our JavaScript, AND it was easy to select stuff in the IDE.
Even WITH there being a VSCode extension, I still wouldn't change my reasoning because that kinda breaks the guidance of, "least disruptive to the team." I wouldn't want to have a project that required some IDE extension to keep teammates productive the way they want.
ALL THAT SAID, as I explained in the start of the guidelines, they are just that...guidelines. The goal is to be consistent and not have teammates present or future curse your name. So developers should really favor team cohesiveness over my opinions based on my specific experience.
Is the iterator un-used within the body of the loop to do more than address a collection?
If it is actually used, it suggests that it's representing more than just an iterator and should be named appropriately.
If it isn't used within the body of the loop then it's purely for the sake of iterating across a collection (or just looping a given number of times) and should be named i.
> Use .qa
Generally, I'd recommend trying to query elements in a test using accessible selectors, if possible. For example, look for the input[type=email] or button[aria-label~="Submit"]. That helps prevent people from forgetting to update or accidentally removing these often invisible properties.
I'd especially recommend testing-library for this purpose, which allows you to easily query by e.g. role and the accessible name of an element: https://testing-library.com/
BTW, the _reason_ he had to add classnames was because we worked in enterprise content management and there were all sorts of situations where, for WHATEVER reason, we couldn't change the markup, or we could only modify the markup in VERY specific ways via the CMS. So finding a way to stick `qa` on an element was a more straightforward path than writing some ridiculous selector like `body > div > div > header ~ article:first-child`
Suffice to say, YES, I agree that adding a class just so you can run a test is bad, but, we hit situations where we had to, and when that happened, it was worth while to have a convention for knowing how to identify classes that served just that purpose.
Here's a guide I would recommend instead: https://github.com/labs42io/clean-code-typescript
May this continue.
All of the examples are within the last 2 years. My area of specialization is enterprise content management; I build the CMS AND the front-end for very large companies that use decoupled CMSs and web sites. And very often, the web app is a typical server-side .net app where a front-end team has written static HTML and handed it off to back-end developers to be sliced into views. So all of this stuff kinda comes from over a decade of doing THAT; it's fair to say that maybe this doesn't all apply if you're an app dev.
But even when I DO build SPAs (like I am for one client), I still use CSS in traditional stylesheets as much as possible because any inline styling that doesn't invoke the CSSOM directly like it should seems like a massive waste of DOM resources ... and also I feel like I lose out on reusability that way.
That "clean code for typescript" is really good. I may drop a link to it in mine. I wasn't trying to be exhaustive. I was just trying to set a good baseline for where to go ;)
Your code example for isHot() seems round the wrong way; also doing something like “return temperature > 100” is probably more idiomatic than using if/else just to return true/false.
This is enabled by tooling. The tooling is largely still using classes under the hood. If you know how to use the underlying tech well you can solve problems your framework of choice doesn’t solve for you.
Not every web page is an SPA. . Mant projects are small enough that frameworks are overkill, but good practice is still useful. Sites that are mostly content probably shouldn’t be built as if they were SPAs anyway (although many are now).
“If you remove or rename this class, the code will break.”
if (this.finished) { ...
or <div v-if="showMainContent>...
With your convention, these could easily be functions, but they are never evaluated without parens. Nor is any error thrown. Instead, the fact that the function exists is truthy and you get the true case always.In our teams's js code we even include "get" for "is" properties (getIsEnabled() rather than isEnabled()) so that it's perfectly obvious if you're ever using a function without calling it.
In which case I still see it as just a personal preference. The prefix of "is" becomes reassurance that something is intended to have a boolean value, which may be more important.
Of course it goes without saying that both of these things are (usually) addressed by a system like Typescript.
function f() {}
if (f) {}
produces: This condition will always return true since this function is always defined. Did you mean to call it instead?(2774)
https://www.typescriptlang.org/play?#code/GYVwdgxgLglg9mABMA...if (getBooleanProperty) { ... }
omitting the parens.
Some people feel that symmetry in names is important when achievable, since it makes them more predictable and the entire API more easy to figure out.
That's valid and maybe I'll update the guide to explain a bit more when/where I have found getProperty() useful:
I often do it when I end up having to have parity in API request: a get AND a set. If there's more than one thing i'm doing with temperature, it's helpful to show WHAT I'm doing with it, specifically. I'll noodle on your thoughts a bit and see how I can incorporate them.
They were useful in cases where we needed to pass in additional information (e.g. data-qa="onClick"). But what we found was
- whether class or attribute, it was the same dependency on markup - selecting with [data-qa] was the same specificity as .qa - selecting with [data-qa] was just a little more verbose than the teams liked
But, this isn't me arguing against data attributes. I'm just stating that my experience went in the direction where we didn't see any huge benefit.
They're guidelines so, by all means, take what works, throw away the rest. This was a small guideline about how to name stuff, not build entire apps. So if that's the thing that doesn't work for your workstream, my feelings aren't hurt. Thanks for reading it, though, and sharing your thoughts.
Also when I’m writing forms, I usually name every field e.g. email-field so and then assign them in the grid using the class name:
.email-field {
grid-area: email
}When I see devs using scoped css the class names always end up like `.box` or `.name`.
Having to think about classnames and writing Sass makes me much more aware of the structure of the components I'm styling.
Also scoped CSS kinda makes you skip the steps of thinking about your component in the bigger picture of your site, since you don't care about having meaningful and unique classnames, then you're much less inclined to think about good guidelines like OP's conventions. What does it matter? Since we can just put a `.box` in the scoped <style> and call it a day.
Frankly I think only JS oriented devs like scoped CSS and frontend who love html/css and the challenges of architecturing good CSS don't egt any benefit out of styled components (since you're using atomic css like Tailwind and/or BEM-style which always "scopes" classnames with the component name.
In general any solid guidelines makes CSS instantly 10x better and that's all most projects needs, and it's often what most projects lack.
SuitCSS works great with Vue in my experience, and can even be linted with postcss-bem-linter :
https://github.com/suitcss/suit/blob/master/doc/naming-conve...
Suffice to say, the SuitCSS convention is extremely close to what we've put into use over the years.
I actually REALLY like SuitCSS' recommendation and I definitely wouldn't object to it.
I intentionally didn't address project architecture (folder names, file names) because ... to be honest... I still haven't quite figured that out.
But I'm going to think on it and maybe add something to the guidelines that echos your suggestion.
These aren’t functions; these are effects.