Comments (9)
So here a proposal. Itβs a mix of BEM/SUIT and Chainable Modifiers, but customized for Atom's use case.
Example
Below the commit box as a possible example:
<div class='git-CommitBox'>
<div class='git-CommitBox-editor'></div>
<footer class='git-CommitBox-footer'>
<button class='git-CommitBox-button'>Commit to sm-branch</button>
<div class='git-CommitBox-counter is-warning'>50</div>
</footer>
</div>
And when styled in Less:
.git {
&-CommitBox {
&-editor {}
&-footer {}
&-button {}
&-counter {
background: red;
&.is-warning {
color: black;
}
}
}
}
Breakdown
Here another example:
<button class='git-CommitBox-commitButton is-primary is-disabled'>
And now let's break it down into all the different parts.
<button class='namespace-ComponentName-childElement is-modifier is-state'>
namespace
git
-CommitBox
Every class starts with a namespace, in this case it's the package name. Since packages are unique (well, at least for all the packages published on atom.io), it avoids style conflicts. Using a namespace like this makes sure that no styles leak out. And even more importantly that no styles leak in.
ComponentName
git-CommitBox
Components use PascalCase. This makes it easy to spot them. Especially if package names use dashes. For example in settings-view-List
, it's easy to see that the component is List
and not view
.
childElement
git-CommitBox-commitButton
Elements that are part of a component use camelCase and are appended to the component's class name.
is-modifier/is-state
git-CommitBox-commitButton is-primary is-disabled
Modifier and states are prefixed with a short verb, like is-
or has-
. Since these class names probably get used in many different places, it should never be styled stand-alone and always be a chained selector.
.is-primary {
// nope
}
.git-CommitBox-commitButton.is-primary {
// yep
}
If multiple words are needed, camelCase is used: is-firstItem
, has-collapsedItems
.
More awesome guidelines
- The
/styles/
filenames should match the filenames in/lib/
. That way it's easy to know where the markup for certain styles can be found. - If possible, the class name in Less should match the class name used in JS.
- Styling elements (like
div
) should be avoided. This makes it easier to switch elements, like from a<button>
to<a>
. - No utility classes. Themes and user styles can only override CSS but not change the markup. Therefore having utility classes doesn't make as much sense once you override them.
- Components can be nested or share the same element. A pattern often found is that a new Component starts where a childElement ends. e.g.
<li class="git-List-item git-Commit">
. In this example,git-List-item
is responsible for the "container" and layout styles.git-Commit
is responsible for the "content" inside.
Benefits
- Just by looking at a class in the DevTools you already get a lot of information about where the source can be found (what package, what component). What relationship each element has (parent/child). What class names are states and might be changed/removed. There should be less "what does this class do" moments.
- Reduces specificity. Mostly there is just a single class. More when using modifiers and states. This reduces the specificity war when trying to override styles in packages/themes and
styles.less
. - Using a single class makes it easier to change the markup later. Once a selector like
.class > div > .class
is in the wild, removing thediv
later would break the styling. - Easier to refactor/move code around because you can see what class belongs to what component.
Concerns
Class names get quite long
Only in the DOM. During authoring class names can be split into different parts and glued together with &
.
.git-CommitBox {
&-editor {
// styles
}
}
will output as
.git-CommitBox-editor {
// styles
}
I don't like nesting selectors
The whole selector (or just different parts) can of course also be written out as a whole. Nesting just makes sure selectors are grouped together.
.git-CommitBox {}
.git-CommitBox-editor {}
.git-CommitBox-footer {}
from github.
This looks great. I'm happy to defer to whatever you think is best π
from github.
Hello @simurai! Just wanted to draw your attention to the documentation the design systems team have been putting together: https://github.com/github/design/blob/styleguide-principles/docs/code/principles.md - We're discussing some very similar things.
I am a fan of approaches like BEM, and reference SUITCSS a fair bit (as well as BASSCSS) - all of them have approaches to scoping styles so they don't leak all over the place - so I'm really happy to discover this conversation happening on another GitHub product.
I don't want to push our approach on the Atom team, but it might be good for the two teams to discuss and see if we can work with the same approach so that it's easier for designers and developers to be able to work on both GitHub and Atom.
We have been having bi-weekly design systems team meetings, and the next one is tomorrow. I'll add you to the invite and if that time works for you we could discuss it then? If not, I'm happy to find another time when we can all meet.
from github.
π @broccolini
see if we can work with the same approach so that it's easier for designers and developers to be able to work on both GitHub and Atom.
That would awesome. I'll take a look at the "Styleguide principles". The βοΈ above conventions are a bit customized for Atom's use-case. Would be interesting to see if both could be aligned. The environments are bit different. Like sending CSS over the wire (.com) vs. reading from disk (Atom). Or be able to change markup and styles at any time (.com) vs once a selector is out it needs to be supported till the next major version (of Atom).
If not, I'm happy to find another time when we can all meet.
I'm in the Japanese time-zone. Sometime around HQ's afternoon/evening would work best for me. I'll also be at the upcoming Mini Summit where we can have a session about it.
from github.
@simurai this proposal looks good to me! I think it borrows the right concepts from BEM without requiring the unsightly double-underscore delimiter and such.
from github.
@broccolini + @github/design-systems I tried to look a bit more into the main differences between the naming convention above βοΈ and https://github.com/github/design/blob/styleguide-principles/docs/code/principles.md. Here some of the main points that stood out:
Multiple words
- github.com: Separated with
-
- Atom: camelCase
For example when seeing the class .tabs-bar-group
, it isn't always easy to guess what is the Block and what is the Element? Using camelCase helps to see what belongs together. A .tabsBar-group
must be a child element of the .tabsBar
component.
Atom's convention actually uses PascalCase for the main component to make it stand out even more. So that when a namespace is used, it shows where the component starts. e.g. tabs-TabsBar-group
.
I guess to differentiate like that isn't so important if you pick commonly known class names. But in Atom's case, there might be more exotic packages and components where the name isn't that common.
Utilities
- github.com: Yes
- Atom: No
Since there are many 3rd party themes for Atom, it makes it harder to use utility classes. That's because themes can only override existing classes, but not change the markup. For example .rounded
, would make less sense if a theme doesn't want to have rounded corners.
Instead of utility classes, themes define variables. Like @border-radius: 5px;
that then get used everywhere. This results it larger CSS files, but maybe not a big concern for Atom because the CSS can be read straight from disk and doesn't have to be downloaded over a network.
Modifiers
- github.com:
btn btn-primary
- Atom:
Button is-primary
In Atom's convention there is no difference between a modifier and a state. Often itβs hard to classify what is a modifier and what is a state. For example a button that initially is a "primary" button, might change to an "error" button later. So you could say that "primary" and "error" are states. It might help to know which classes are the default and got added on initial load and use modifiers for those. But for something that constantly changes or the state gets restored when opening Atom, it maybe matters less what the initial state used to be.
One downside to use the SMACSS style .Button.is-primary {}
for modifiers is that it increases specificity. So thatβs something that still needs to be tested in practice and see if it has a negative impact.
Conclusion
So yeah.. I think for Atom's use-case, having as few classes as possible, might be the better approach. Basically the opposite of Atomic/BASSCSS/OOCSS. As mentioned above, themes and user styles can't make changes to the markup, so they need to rely on overriding. To make that easier, Atom would define just a single class as an "identifier", together with a few modifier/states. It's like a public API. Once a class gets added, it shouldn't change anymore until the next major version of Atom. Which could take 1-2 years.
Does that make sense? π¬
from github.
Thanks @simurai for explaining how Atom's use-cases in detail! π
Multiple words
I'm not opposed to github.com CSS using PascalCase too. I don't think we have as strong as need for it but I do think it makes the markup easier to scan and identify component vs non-components, and if it helped keep things be a little more consistent between the two systems then perhaps it's worth doing. I'd like to discuss with the rest of the @github/design-systems team first though and see how they feel about that.
Utilities
π Totally understand why utilities won't work for you. Do you think there is any value in keeping Atom variables consistent with github.com utility class names?
Modifiers
a "primary" button, might change to an "error" button later. So you could say that "primary" and "error" are states.
I'd argue that primary
is a property and not a state. I think is-error
is a fairly common state, however that's not how we are handling button modifiers on github.com. There are many use cases for something like a red button that are not an error, the most obvious being a button that deletes something.
It might help to know which classes are the default and got added on initial load and use modifiers for those. But for something that constantly changes or the state gets restored when opening Atom, it maybe matters less what the initial state used to be.
I'm finding this a little harder to follow tbh. This might because I don't fully understand how Atom works with CSS though π , so maybe better to discuss this on video π
I'll try and find a spot on the calendars that works so we can discuss in person.
from github.
I'll try and find a spot on the calendars that works so we can discuss in person.
Sounds good. π
from github.
Let's move this to https://github.com/atom/design/blob/master/specs/css-naming-convention.md so we can close this issue.
Then once the GitHub package is public, we can open a new PR in https://github.com/atom/design-decisions to finalize this proposal.
from github.
Related Issues (20)
- .
- knknkn
- Default branch name of new git repositories is `master`, despite init.defaultbranch settings HOT 1
- Cannot stage changes, make commits, make branches
- Can't open tlauncher
- Cannot see autocomplete in Search Input
- [email protected] HOT 1
- Credit HOT 1
- Credit HOT 1
- Can't push to organization repo HOT 3
- Port these views to VSCode? HOT 2
- Startup & Hydrogen issues HOT 3
- Can't push from Atom to Github
- Profiles
- ## Environment
- Github Desktop deleted all files in folder (pls help i spent so much time on these projects)
- Jusc HOT 1
- unstaged changes do not show up in git panel HOT 3
- I'm HOT 1
- Not
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from github.