CSS Style Guide¶
Background¶
This document is intended to outline the style rules for CSS here at Miva. This style guide applies to anywhere that CSS is written with the purpose and intent of being rendered in a browser to an end user. This includes: static CSS, SCSS, and SASS files, CSS written inline or embedded, etc.
Key Points¶
- Code according to our Stylelint standards.
- Follow our CSS & BEM naming conventions.
- Follow the Style Rules below.
Recommended Reading¶
- CSS Guidelines
- SASS Guidelines
- sass-lang.com Code Style Guide
- Quick Tip Name Your Sass Variables Modularly
- CSS Architecture For Design Systems
Style Rules¶
ID and Class Names¶
Class names and ID names should either be meaningful and describe the element they effect, or be generic and self descriptive. Names that are reflective of the element they effect are preferable to generic names.
Incorrect
/* Not Meaningful */
#mvt-123 {}
/* Not Generic */
.bluebutton {}
/* Not Descriptive */
.left {}
Correct
/* Meaningful */
#left-sidebar {}
/* Generic */
.primary-button {}
/* Self Descriptive */
.align-left {}
Type Selectors¶
Avoid using type selectors for specificity whenever possible.
Incorrect
div#left-sidebar {}
a.c-button {}
Correct
#left-sidebar {}
.c-button {}
CSS Shorthand¶
We recommend using shorthand CSS properties whenever possible. Using shorthand makes code more readable and understandable.
Incorrect
.element {
border-top-style: solid;
border-top-width: 1px;
border-top-color: #000000;
padding-bottom: 1em;
padding-left: 0.75em;
padding-top: 0;
padding-right: 0.75em;
}
Correct
.element {
border: 1px 0 0 0 solid #000000;
padding: 0 0.75em 1em 0.75em;
}
Unit Value With 0s¶
When a value is specified as 0, it is preferred that you omit the the unit unless it is required.
Incorrect
.element {
flex: 0px;
margin: 0em;
padding: 0px;
}
Correct
.element {
flex: 0px /* flex requires a unit be passed */
margin: 0;
padding: 0;
}
Leading 0s¶
We prefer including a leading 0 for values between -1 and 1.
Incorrect
.element {
margin: 0 .5em;
}
Correct
.element {
margin: 0 0.5em;
}
Hexadecimal Color Codes¶
Using the long form 6 character code is preferred over the shorthand 3 character code.
Incorrect
.element {
color: #FFF;
background-color: #eee
}
Correct
.element {
color: #FFFFFF;
background-color: #EEEEEE;
}
Name Delimiters¶
ID and Class Names should be delimited with a hyphen. Please avoid using underscores, CamelCase, pascalCase, or any other means of delimiting names.
Incorrect
.leftElement {}
.right_element {}
Correct
.left-element {}
.right-element {}
Important Hack¶
Avoid using !important
in your rules unless you absolutely have to. The only time this should be acceptable is if you need to overwrite styling coming from a 3rd party script you have no control over.
Incorrect
.element {
margin-left: 15px !important;
}
Correct
.more-specific-element .element {
margin-left: 15px;
}
Formatting Rules¶
Order of Rule Declaration¶
Rules should be declared in alphabetized order to maintain readability and consistency across the code base.
Incorrect
.element {
height: 7px;
background: #6976bc;
display: inline-block;
content: "";
position: relative;
border-radius: 100%;
width: 7px;
opacity: 0;
left: -7px;
top: -1px;
}
Correct
.element {
background: #6976bc;
border-radius: 100%;
content: "";
display: inline-block;
height: 7px;
left: -7px;
opacity: 0;
position: relative;
top: -1px;
width: 7px;
}
Indentation¶
Rules and declarations should be indented with a single tab character with respect to their parent to display relationship between declarations.
Incorrect
@media screen {
.element {
margin: 0;
padding: 0;
border: 1px solid #000000;
}
}
Correct
@media screen {
.element {
margin: 0;
padding: 0;
border: 1px solid #000000;
}
}
Line Terminations¶
Every rule declaration must be terminated with a semi-colon character.
Incorrect
.element_one {
position: absolute
left: 0
top: 10px
}
Correct
.element_one {
position: absolute;
left: 0;
top: 10px;
}
Line Breaks and Separation¶
Properties should be separated from their declarations by a single space after the colon.
The opening brace should be on the same line as the selector.
Separate selectors and declarations by new lines.
Incorrect
.c-primary-title {
line-height:1.5rem;
}
.c-sub-heading{ font-weight:bold; }
Correct
.c-primary-title {
line-height: 1.5rem;
}
.c-sub-heading {
font-weight: bold;
}
Quotation Characters¶
When using quotation marks for attribute and property values, use single quotes vs double quotes.
Incorrect
@import url("https://www.miva.com/css/main.css");
.c-primary-title {
font-family: "open sans", Helvetica, Arial;
}
Correct
@import url('https://www.miva.com/css/main.css');
.c-primary-title {
font-family: 'open sans', Helvetica, Arial;
}
BEM Naming Convention¶
"BEM (Block, Element, Modifier) is a component-based approach to web development. The idea behind it is to divide the user interface into independent blocks. This makes interface development easy and fast even with a complex UI, and it allows reuse of existing code without copying and pasting."
.<namespace>-<block>__<element>--<modifier>
Recommended Reading¶
Block:¶
- Summary: The sole root of the component.
- Features: The block name describes its purpose ("What is it?" — menu or button), not its state ("What does it look like?" — red or big).
- Examples:
modal
x-product-card
- Guidelines
Incorrect
<!-- Describes the appearance -->
<div class="red-text"></div>
Correct
<!-- Describes the semantically meaning -->
<div class="error"></div>
Element:¶
- Summary: A component part of the Block that can't be used separately from it.
- Features:
- The element name describes its purpose ("What is this?" —
item
,text
, etc.), not its state ("What type, or what does it look like?" —red
,big
, etc.). - The structure of an element's full name is
block-name__element-name
. The element name is separated from the block name with a double underscore (__
).
- The element name describes its purpose ("What is this?" —
- Examples:
modal__overlay
x-product-card__footer
- Guidelines
Modifier:¶
- Summary: An entity that defines the appearance, state, or behavior of a block or element.
- Features:
- The modifier name describes its appearance ("What size?" or "Which theme?" and so on —
size_s
ortheme_islands
), its state ("How is it different from the others?" —disabled
,focused
, etc.) and its behavior ("How does it behave?" or "How does it respond to the user?" — such asdirections_left-top
). - The modifier name is separated from the block or element name by a two dashes (
--
).
- The modifier name describes its appearance ("What size?" or "Which theme?" and so on —
- Examples:
modal--small
x-product-card__image--rounded
Namespaces¶
- Object:
o-
- Signify that something is an Object, and that it may be used in any number of unrelated contexts to the one you can currently see it in. Making modifications to these types of class could potentially have knock-on effects in a lot of other unrelated places. Tread carefully.
- Component:
c-
- Signify that something is a Component. This is a concrete, implementation-specific piece of UI. All of the changes you make to its styles should be detectable in the context you’re currently looking at. Modifying these styles should be safe and have no side effects.
- Utility:
u-
- Signify that this class is a Utility class. It has a very specific role (often providing only one declaration) and should not be bound onto or changed. It can be reused and is not tied to any specific piece of UI. You will probably recognize this namespace from libraries and methodologies like SUIT.
- Theme:
t-
- Signify that a class is responsible for adding a Theme to a view. It lets us know that UI Components’ current cosmetic appearance may be due to the presence of a theme.
- Scope:
s-
- Signify that a class creates a new styling context or Scope. Similar to a Theme, but not necessarily cosmetic, these should be used sparingly—they can be open to abuse and lead to poor CSS if not used wisely.
- State:
is-
,has-
- Signify that the piece of UI in question is currently styled a certain way because of a state or condition. This stateful namespace is gorgeous, and comes from SMACSS. It tells us that the DOM currently has a temporary, optional, or short-lived style applied to it due to a certain state being invoked.
- Hack:
_
- Signify that this class is the worst of the worst—a hack! Sometimes, although incredibly rarely, we need to add a class in our markup in order to force something to work. If we do this, we need to let others know that this class is less than ideal, and hopefully temporary (i.e. do not bind onto this).
- JavaScript:
js-
- Signify that this piece of the DOM has some behavior acting upon it, and that JavaScript binds onto it to provide that behavior. If you’re not a developer working with JavaScript, leave these well alone.
- QA Automation:
qa-
- Signify that a QA or Test Engineering team is running an automated UI test which needs to find or bind onto these parts of the DOM. Like the JavaScript namespace, this basically just reserves hooks in the DOM for non-CSS purposes.