At this point, I think it will be useful to consider a more detailed example module structure. It's similar to the structure in which I'm used to employing ECSS. It's a little more involved than our prior examples and gives another subtly different variation on how files could be organised and selectors named. As ever, from our CSS point of view our aim is isolation, consistency and solid developer ergonomics. Let's take a look.
Suppose we have a module. Its job is to load the sidebar area of our site. The directory structure might initially look like this:
SidebarModule/ => everything SidebarModule related lives in here /assets => any assets (images etc) for the module /css => all CSS files /min => minified CSS/JS files /components => all component logic for the module in here css-namespaces.json => a file to define all namespaces SidebarModule.js => logic for the module config.json => config for the module
In terms of the example markup structure this module should produce, we would expect something like this initially:
<div class="sb-SidebarModule"> </div>
The CSS that styles this initial element should live inside the css
folder like this:
SidebarModule/
/assets
/css
/components
SidebarModule.css
/min
/components
css-namespaces.json
SidebarModule.js
config.json
Now, suppose we have a component inside the SidebarModule
that creates a header for the SidebarModule
. We might name the component with a file called Header.js
and store it inside the components sub-folder of our SidebarModule
like this:
SidebarModule/
/assets
/css
/components
SidebarModule.css
/min
/components
Header.js
css-namespaces.json
SidebarConfig.js
SidebarModule.js
config.json
With that in place, the Header.js
might render markup like this:
<div class="sb-SidebarModule"> <div class="sb-Header"> <div class="sb-Header_Logo"></div> </div> </div>
Note how the Header
component, due to being within the context of the SidebarModule
carries the sb-
micro-namespace to designate its parentage. And the nodes created by this new component are named according to the logic that creates them.
In terms of the general conventions to follow:
Components should carry the micro-namespace of the originating logic. If you are creating a component that sits within a module, it should carry a/the namespace of the originating module (possible namespaces for a module are defined in css-namespaces.json
).
HTML classes/CSS selectors should be named according to the file name/components that generated them. For example, if we created another component inside our module called HeaderLink.js
which renders its markup inside a child of the Header.js
component, then the markup it generates and the applicable CSS selectors should match this file name.
For example:
<div class="sb-SidebarModule"> <div class="sb-HeaderPod"> <div class="sb-HeaderPod_Logo"></div> </div> <div class="sb-HeaderPod_Nav"> <div class="sb-HeaderLink">Node Value</div> <div class="sb-HeaderLink">Node Value</div> <div class="sb-HeaderLink">Node Value</div> <div class="sb-HeaderLink">Node Value</div> </div> </div>
In terms of the folder structure, it would now look like this:
SidebarModule/ /assets /css /components Header.css HeaderLink.css SidebarModule.css /min /components Header.js HeaderLink.js css-namespaces.json SidebarConfig.js SidebarModule.js tsconfig.json
Notice how there is a 1:1 correlation between component logic (the *.js
file) and the associated styles (the *.css
files) – both sit within a components
sub-folder. Although both logic and styles don't share the same immediate parent folder, they both live within the same module folder, making removal of the entire module simple if needed.
To recap. Used in this way, the ECSS naming convention of nodes within a component should always be:
ns-Component_Node-variant
ns
: The micro-namespace (always lower-case)-Component
: The Component name (always upper camel-case)_Node
: The child node of a component (always upper camel-case preceded by an underscore)-variant
: The optional variant of a node (always lower-case and preceded by a hyphen)Note that the -variant
part of a node within a component is optional and should only be used to denote subtle variations on otherwise identical items. For example, multiple headers that are identical apart from a differing background image might be rendered like this:
<div class="sb-Classification_Header sb-Classification_Header-2"></div>
Remember, we discussed the use of variant selectors a little more in Chapter 5, File Organisation and Naming Conventions.
3.142.136.226