CSS Style Guide
Table of Contents
- CSS Style Rules
- CSS Formatting Rules
- Modern CSS Features
- Responsive Design
- CSS Architecture
- Performance
- Accessibility
- Animations and Transitions
CSS Style Rules
Protocol
Use HTTPS for embedded resources where possible.
Always use HTTPS for scripts unless each file is available via HTTPS.
// Wrong
body {
background-image: url("http://api.pelagornis.com/...");
}
// Right
body {
background-image: url("https://api.pelagornis.com/...");
}
Class Naming
Use meaningful or generic class names.
Instead of presentational or cryptic names, always use class names that reflect the purpose of the element in question, or that are otherwise generic.
// Wrong - meaningless
.css-102837 {
}
// Right - specific
.video {
}
Class Name Style
Use a class name that has as short as possible but necessary information.
// Wrong
.navigation {
}
// Right
.nav {
}
Class Name Delimiters
Separate words in class names by a hyphen.
// Wrong
.example_video {
}
// Right
.example-video {
}
Type Selectors
Avoid qualifying class names with type selectors.
// Wrong
section.example {
}
// Right
.example {
}
ID Selectors
Avoid ID selectors.
Unique ID properties are difficult to ensure if they contain many components that multiple engineers have worked on.
// Wrong
#nav {
}
// Right
.nav {
}
Shorthand Properties
Use shorthand properties where possible.
// Wrong
padding-top: 1em;
padding-left: 2em;
padding-right: 2em;
padding-bottom: 1em;
// Right
padding: 1em 2em;
0 and Units
Omit unit specification after “0” values, unless required.
// Wrong
padding: 0px;
// Right
padding: 0;
Hexadecimal Notation
Use 3 character hexadecimal notation where possible.
// Wrong
color: #aabbcc;
// Right
color: #abc;
Important Declarations
Avoid using !important
declarations
// Wrong
h1 {
font-weight: bold !important;
}
// Right
h1 {
font-weight: bold;
}
CSS Formatting Rules
Indentation
Indent by 2 spaces at a time.
Don’t use tabs or mix tabs and spaces for indentation.
.pelagornis_logo {
color: white;
}
Capitalization
Use only lowercase.
// Wrong
color: #f5f5f7;
// Right
color: #f5f5f7;
Trailing Whitespace
Remove trailing white spaces.
// Wrong
.pelagornis {
color: black_;
}
// Right
.pelagornis {
color: black;
}
Declaration Order
Alphabetize declarations
To achieve consistent code, we recommend placing declarations in alphabetical order.
background: white;
color: red;
text-align: center;
Declaration Stops
Use a semicolon after every declaration.
// Wrong
.example {
color: black;
text-align: center;
}
// Right
.example {
color: black;
text-align: center;
}
Property Name Stops
Use a space after a property name’s colon.
// Wrong
h1 {
font-weight: bold;
}
// Right
h1 {
font-weight: bold;
}
Selector and Declaration Separation
Separate selectors and declarations by new lines.
// Wrong
h1,
h2,
h3 {
font-weight: bold;
color: black;
}
// Right
h1,
h2,
h3 {
font-weight: bold;
color: black;
}
Rule Separation
Separate rules by new lines.
html {
background: #fff;
}
body {
margin: auto;
padding: 0;
}
CSS Quotation Marks
Use single (''
) rather than double (""
) quotation marks for attribute selectors and property values.
Do not use quotation marks in URI values (url()
).
// Wrong
@import url("https://pelagornis.com/...");
html {
font-family: "open sans", arial, sans-serif;
}
// Right
@import url(https://pelagornis.com/...);
html {
font-family: "open sans", arial, sans-serif;
}
Modern CSS Features
CSS Custom Properties (Variables)
Use CSS custom properties for maintainable theming and dynamic values.
:root {
/* Color palette */
--color-primary: #007bff;
--color-secondary: #6c757d;
--color-success: #28a745;
--color-danger: #dc3545;
--color-warning: #ffc107;
--color-info: #17a2b8;
/* Typography */
--font-family-base: "Inter", -apple-system, BlinkMacSystemFont, sans-serif;
--font-size-base: 1rem;
--line-height-base: 1.5;
/* Spacing */
--spacing-xs: 0.25rem;
--spacing-sm: 0.5rem;
--spacing-md: 1rem;
--spacing-lg: 1.5rem;
--spacing-xl: 3rem;
/* Layout */
--container-max-width: 1200px;
--border-radius: 0.375rem;
--box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
}
/* Dark theme */
[data-theme="dark"] {
--color-primary: #0d6efd;
--color-secondary: #6c757d;
--color-background: #212529;
--color-text: #ffffff;
}
/* Usage */
.button {
background-color: var(--color-primary);
color: white;
padding: var(--spacing-sm) var(--spacing-md);
border-radius: var(--border-radius);
font-family: var(--font-family-base);
}
CSS Grid Layout
Use CSS Grid for complex two-dimensional layouts.
/* Grid container */
.grid-container {
display: grid;
grid-template-columns: repeat(12, 1fr);
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header header header header header header header header header header header"
"sidebar main main main main main main main main main main main"
"footer footer footer footer footer footer footer footer footer footer footer footer";
gap: var(--spacing-md);
min-height: 100vh;
}
/* Grid items */
.header {
grid-area: header;
background: var(--color-primary);
color: white;
padding: var(--spacing-md);
}
.sidebar {
grid-area: sidebar;
background: #f8f9fa;
padding: var(--spacing-md);
}
.main {
grid-area: main;
padding: var(--spacing-md);
}
.footer {
grid-area: footer;
background: #343a40;
color: white;
padding: var(--spacing-md);
}
/* Responsive grid */
@media (max-width: 768px) {
.grid-container {
grid-template-columns: 1fr;
grid-template-areas:
"header"
"main"
"sidebar"
"footer";
}
}
/* Card grid */
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: var(--spacing-lg);
padding: var(--spacing-md);
}
Flexbox Layout
Use Flexbox for one-dimensional layouts and component alignment.
/* Flexbox container */
.flex-container {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
gap: var(--spacing-md);
}
/* Navigation with flexbox */
.nav {
display: flex;
justify-content: space-between;
align-items: center;
padding: var(--spacing-md);
}
.nav-links {
display: flex;
list-style: none;
gap: var(--spacing-lg);
margin: 0;
padding: 0;
}
/* Card component */
.card {
display: flex;
flex-direction: column;
background: white;
border-radius: var(--border-radius);
box-shadow: var(--box-shadow);
overflow: hidden;
}
.card-header {
padding: var(--spacing-md);
border-bottom: 1px solid #e9ecef;
}
.card-body {
flex: 1;
padding: var(--spacing-md);
}
.card-footer {
padding: var(--spacing-md);
border-top: 1px solid #e9ecef;
background: #f8f9fa;
}
/* Button group */
.button-group {
display: flex;
gap: var(--spacing-sm);
}
.button-group .button {
flex: 1;
}
CSS Container Queries
Use container queries for component-based responsive design.
/* Container query context */
.card-container {
container-type: inline-size;
container-name: card;
}
/* Container queries */
@container card (min-width: 300px) {
.card {
display: flex;
flex-direction: row;
}
.card-image {
width: 40%;
}
.card-content {
width: 60%;
}
}
@container card (max-width: 299px) {
.card {
display: flex;
flex-direction: column;
}
.card-image {
width: 100%;
}
.card-content {
width: 100%;
}
}
Responsive Design
Mobile-First Approach
Start with mobile styles and progressively enhance for larger screens.
/* Base styles (mobile) */
.container {
width: 100%;
padding: 0 var(--spacing-md);
margin: 0 auto;
}
.hero {
padding: var(--spacing-xl) 0;
text-align: center;
}
.hero h1 {
font-size: 2rem;
margin-bottom: var(--spacing-md);
}
/* Tablet styles */
@media (min-width: 768px) {
.container {
max-width: 750px;
}
.hero h1 {
font-size: 2.5rem;
}
.grid-2 {
display: grid;
grid-template-columns: 1fr 1fr;
gap: var(--spacing-lg);
}
}
/* Desktop styles */
@media (min-width: 1024px) {
.container {
max-width: 1200px;
}
.hero h1 {
font-size: 3rem;
}
.grid-3 {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: var(--spacing-lg);
}
}
/* Large desktop styles */
@media (min-width: 1440px) {
.container {
max-width: 1400px;
}
}
Responsive Typography
Create fluid typography that scales with screen size.
/* Fluid typography */
:root {
--font-size-min: 1rem;
--font-size-max: 1.25rem;
--viewport-min: 320px;
--viewport-max: 1200px;
}
h1 {
font-size: clamp(2rem, 5vw, 4rem);
line-height: 1.2;
margin-bottom: var(--spacing-lg);
}
h2 {
font-size: clamp(1.5rem, 4vw, 2.5rem);
line-height: 1.3;
margin-bottom: var(--spacing-md);
}
p {
font-size: clamp(var(--font-size-min), 2.5vw, var(--font-size-max));
line-height: 1.6;
margin-bottom: var(--spacing-md);
}
/* Responsive spacing */
.section {
padding: clamp(var(--spacing-lg), 5vw, var(--spacing-xl)) 0;
}
Responsive Images
Implement responsive images with proper sizing and optimization.
/* Responsive images */
.responsive-image {
width: 100%;
height: auto;
display: block;
}
/* Aspect ratio containers */
.aspect-ratio-16-9 {
aspect-ratio: 16 / 9;
overflow: hidden;
}
.aspect-ratio-4-3 {
aspect-ratio: 4 / 3;
overflow: hidden;
}
.aspect-ratio-1-1 {
aspect-ratio: 1 / 1;
overflow: hidden;
}
/* Object fit for images */
.aspect-ratio-16-9 img {
width: 100%;
height: 100%;
object-fit: cover;
}
/* Responsive video */
.responsive-video {
position: relative;
width: 100%;
height: 0;
padding-bottom: 56.25%; /* 16:9 aspect ratio */
}
.responsive-video iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
CSS Architecture
BEM Methodology
Use BEM (Block, Element, Modifier) for maintainable CSS architecture.
/* Block */
.card {
background: white;
border-radius: var(--border-radius);
box-shadow: var(--box-shadow);
overflow: hidden;
}
/* Element */
.card__header {
padding: var(--spacing-md);
border-bottom: 1px solid #e9ecef;
}
.card__title {
margin: 0;
font-size: 1.25rem;
font-weight: 600;
}
.card__body {
padding: var(--spacing-md);
}
.card__footer {
padding: var(--spacing-md);
background: #f8f9fa;
border-top: 1px solid #e9ecef;
}
/* Modifier */
.card--featured {
border: 2px solid var(--color-primary);
}
.card--large .card__header {
padding: var(--spacing-lg);
}
.card--large .card__title {
font-size: 1.5rem;
}
/* Button example */
.button {
display: inline-flex;
align-items: center;
justify-content: center;
padding: var(--spacing-sm) var(--spacing-md);
border: none;
border-radius: var(--border-radius);
font-family: var(--font-family-base);
font-size: var(--font-size-base);
text-decoration: none;
cursor: pointer;
transition: all 0.2s ease;
}
.button--primary {
background-color: var(--color-primary);
color: white;
}
.button--secondary {
background-color: var(--color-secondary);
color: white;
}
.button--large {
padding: var(--spacing-md) var(--spacing-lg);
font-size: 1.125rem;
}
.button--small {
padding: var(--spacing-xs) var(--spacing-sm);
font-size: 0.875rem;
}
CSS Modules Structure
Organize CSS files using a modular approach.
/* Base styles */
@import "base/reset.css";
@import "base/typography.css";
@import "base/variables.css";
/* Layout components */
@import "layout/header.css";
@import "layout/footer.css";
@import "layout/sidebar.css";
@import "layout/grid.css";
/* UI components */
@import "components/button.css";
@import "components/card.css";
@import "components/form.css";
@import "components/modal.css";
/* Utilities */
@import "utilities/spacing.css";
@import "utilities/display.css";
@import "utilities/text.css";
/* Pages */
@import "pages/home.css";
@import "pages/about.css";
@import "pages/contact.css";
Utility Classes
Create utility classes for common styling patterns.
/* Spacing utilities */
.m-0 {
margin: 0;
}
.m-1 {
margin: var(--spacing-xs);
}
.m-2 {
margin: var(--spacing-sm);
}
.m-3 {
margin: var(--spacing-md);
}
.m-4 {
margin: var(--spacing-lg);
}
.m-5 {
margin: var(--spacing-xl);
}
.p-0 {
padding: 0;
}
.p-1 {
padding: var(--spacing-xs);
}
.p-2 {
padding: var(--spacing-sm);
}
.p-3 {
padding: var(--spacing-md);
}
.p-4 {
padding: var(--spacing-lg);
}
.p-5 {
padding: var(--spacing-xl);
}
/* Display utilities */
.d-none {
display: none;
}
.d-block {
display: block;
}
.d-inline {
display: inline;
}
.d-inline-block {
display: inline-block;
}
.d-flex {
display: flex;
}
.d-grid {
display: grid;
}
/* Text utilities */
.text-left {
text-align: left;
}
.text-center {
text-align: center;
}
.text-right {
text-align: right;
}
.text-justify {
text-align: justify;
}
.text-uppercase {
text-transform: uppercase;
}
.text-lowercase {
text-transform: lowercase;
}
.text-capitalize {
text-transform: capitalize;
}
/* Color utilities */
.text-primary {
color: var(--color-primary);
}
.text-secondary {
color: var(--color-secondary);
}
.text-success {
color: var(--color-success);
}
.text-danger {
color: var(--color-danger);
}
.text-warning {
color: var(--color-warning);
}
.text-info {
color: var(--color-info);
}
.bg-primary {
background-color: var(--color-primary);
}
.bg-secondary {
background-color: var(--color-secondary);
}
.bg-success {
background-color: var(--color-success);
}
.bg-danger {
background-color: var(--color-danger);
}
.bg-warning {
background-color: var(--color-warning);
}
.bg-info {
background-color: var(--color-info);
}
Performance
Critical CSS
Inline critical CSS for faster initial page load.
/* Critical CSS - Above the fold */
* {
box-sizing: border-box;
}
body {
margin: 0;
font-family: var(--font-family-base);
font-size: var(--font-size-base);
line-height: var(--line-height-base);
color: #333;
}
.header {
background: var(--color-primary);
color: white;
padding: var(--spacing-md);
}
.hero {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: var(--spacing-xl) 0;
text-align: center;
}
/* Non-critical CSS loaded asynchronously */
.nav-links {
display: flex;
list-style: none;
gap: var(--spacing-lg);
}
.card {
background: white;
border-radius: var(--border-radius);
box-shadow: var(--box-shadow);
}
CSS Optimization
Optimize CSS for better performance.
/* Use efficient selectors */
/* Good - specific and fast */
.button-primary {
}
/* Avoid - overly specific */
div.container > ul.nav > li.item > a.link {
}
/* Use transform and opacity for animations */
.animate-fade-in {
opacity: 0;
transform: translateY(20px);
transition: opacity 0.3s ease, transform 0.3s ease;
}
.animate-fade-in.visible {
opacity: 1;
transform: translateY(0);
}
/* Use will-change sparingly */
.animate-element {
will-change: transform, opacity;
}
.animate-element.animation-complete {
will-change: auto;
}
/* Optimize for GPU acceleration */
.gpu-accelerated {
transform: translateZ(0);
backface-visibility: hidden;
perspective: 1000px;
}
Accessibility
Focus Management
Implement proper focus styles for keyboard navigation.
/* Focus styles */
*:focus {
outline: 2px solid var(--color-primary);
outline-offset: 2px;
}
/* Skip links */
.skip-link {
position: absolute;
top: -40px;
left: 6px;
background: var(--color-primary);
color: white;
padding: 8px;
text-decoration: none;
border-radius: 4px;
z-index: 1000;
}
.skip-link:focus {
top: 6px;
}
/* Button focus */
.button:focus {
outline: 2px solid var(--color-primary);
outline-offset: 2px;
box-shadow: 0 0 0 4px rgba(0, 123, 255, 0.25);
}
/* Form focus */
input:focus,
textarea:focus,
select:focus {
border-color: var(--color-primary);
box-shadow: 0 0 0 3px rgba(0, 123, 255, 0.1);
}
Screen Reader Support
Provide proper support for screen readers.
/* Screen reader only content */
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
/* Skip to content link */
.skip-to-content {
position: absolute;
top: -40px;
left: 6px;
background: var(--color-primary);
color: white;
padding: 8px 16px;
text-decoration: none;
border-radius: 4px;
z-index: 1000;
}
.skip-to-content:focus {
top: 6px;
}
/* High contrast mode support */
@media (prefers-contrast: high) {
.button {
border: 2px solid currentColor;
}
.card {
border: 1px solid #000;
}
}
/* Reduced motion support */
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
Animations and Transitions
Smooth Transitions
Create smooth transitions for interactive elements.
/* Transition variables */
:root {
--transition-fast: 0.15s ease;
--transition-normal: 0.3s ease;
--transition-slow: 0.5s ease;
}
/* Button transitions */
.button {
transition: all var(--transition-normal);
}
.button:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
.button:active {
transform: translateY(0);
transition: all var(--transition-fast);
}
/* Card hover effects */
.card {
transition: transform var(--transition-normal), box-shadow var(--transition-normal);
}
.card:hover {
transform: translateY(-4px);
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
}
/* Form focus transitions */
input,
textarea,
select {
transition: border-color var(--transition-normal), box-shadow var(--transition-normal);
}
input:focus,
textarea:focus,
select:focus {
border-color: var(--color-primary);
box-shadow: 0 0 0 3px rgba(0, 123, 255, 0.1);
}
Keyframe Animations
Create engaging keyframe animations.
/* Fade in animation */
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.fade-in {
animation: fadeIn 0.6s ease forwards;
}
/* Slide in from left */
@keyframes slideInLeft {
from {
opacity: 0;
transform: translateX(-100%);
}
to {
opacity: 1;
transform: translateX(0);
}
}
.slide-in-left {
animation: slideInLeft 0.5s ease forwards;
}
/* Pulse animation */
@keyframes pulse {
0% {
transform: scale(1);
}
50% {
transform: scale(1.05);
}
100% {
transform: scale(1);
}
}
.pulse {
animation: pulse 2s infinite;
}
/* Loading spinner */
@keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
.spinner {
width: 20px;
height: 20px;
border: 2px solid #f3f3f3;
border-top: 2px solid var(--color-primary);
border-radius: 50%;
animation: spin 1s linear infinite;
}