Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
150 changes: 149 additions & 1 deletion docs/css/best-practices/accessibility.mdx
Original file line number Diff line number Diff line change
@@ -1 +1,149 @@
<ComingSoon />
---
title: "CSS Accessibility Best Practices"
description: "Essential guidelines for using CSS to create accessible web interfaces, focusing on color contrast, focus indicators, responsive design, and motion control."
keywords: [CSS accessibility, WCAG, color contrast, focus indicators, prefers-reduced-motion, responsive design, accessibility best practices]
tags: ['css', 'accessibility', 'best-practices', 'a11y']
sidebar_label: Accessibility
---

Accessibility in CSS is about ensuring that the presentation layer of your website—the styles, layout, and visual interactions—supports users with disabilities, including those using screen readers, keyboard navigation, or specialized input devices.

Accessible design starts with semantic HTML, but CSS is responsible for ensuring the interface is usable for *everyone*.

<AdsComponent />
<br />

## 1. Color Contrast and Readability

Insufficient color contrast is the most common accessibility issue. Users with low vision, color blindness, or those viewing screens in bright sunlight need strong contrast to read text and distinguish interactive elements.

### WCAG Standards

The **Web Content Accessibility Guidelines (WCAG)** define minimum contrast ratios:

* **AA Standard (Minimum):**
* Normal Text: **4.5:1** contrast ratio.
* Large Text (18pt or 14pt bold): **3:1** contrast ratio.
* **AAA Standard (Enhanced):**
* Normal Text: **7:1** contrast ratio.

:::warning Do Not Rely on Color Alone
Do not use color as the *only* visual means of conveying information. For instance, in a form, don't just turn an invalid input red; add a text error message or an icon.
:::

### Utility Tips

Use tools or built-in utilities (if available in your framework) that check contrast automatically. If styling manually, use a contrast checker tool for every text-background pairing.

```css title="styles.css"
/* Ensure strong contrast */
.text-dark {
color: #333333; /* Contrast 12.8:1 against white */
}

/* Ensure accessible link colors against the background */
.link {
color: #007bff; /* Must have 4.5:1 ratio against the background */
}
```

## 2. Focus Indicators (`:focus`)

Keyboard users (who often use the `Tab` key) rely entirely on a visible focus indicator to know which element they are currently interacting with. Removing the default browser outline is a critical accessibility failure.

### A. Never Remove, Always Enhance

It is bad practice to use `outline: none;` without immediately replacing it with a more visible indicator.

```css title="styles.css"
/* Bad Practice: Removes crucial visual feedback */
button:focus {
outline: none; /* DO NOT DO THIS without replacement */
}

/* Good Practice: Replace the default outline with a clear, visible box-shadow or border */
button:focus-visible {
outline: 3px solid transparent; /* Ensure default is gone first (if needed) */
box-shadow: 0 0 0 4px #4f46e5; /* Use a high-contrast color */
border-radius: 4px;
}
```

<AdsComponent />
<br />

### B. `:focus-visible` (Modern Standard)

The `:focus-visible` pseudo-class is highly recommended. It ensures the focus style is only displayed when the element is focused via the keyboard, *not* when clicked with a mouse. This satisfies accessibility requirements without annoying mouse users.

## 3. Controlling Motion and Animation

Users with vestibular disorders can experience dizziness, nausea, or motion sickness from excessive, sudden, or large-scale animations.

### The `prefers-reduced-motion` Media Query

Use the `prefers-reduced-motion` media query to respect a user's operating system setting that requests minimal animation.

```css title="styles.css"
/* Default animation */
.hero-image {
transform: translateX(0);
transition: transform 0.5s ease-in-out;
}

/* Override for users who prefer reduced motion */
@media (prefers-reduced-motion: reduce) {
.hero-image {
/* Disable all animation */
transition: none;
/* Set final state immediately */
transform: translateX(0) !important;
/* Or only use opacity changes */
/* transition: opacity 0.5s; */
}
}
```

:::tip Animation Policy
When designing interactions, your policy should be: **Animations are decorative, never mandatory.** If an animation is essential to understanding the content, provide an alternative, static presentation.
:::

## 4. Layout and Responsive Accessibility

Responsive design is an accessibility requirement. Content must be easily viewable and usable regardless of screen size, zoom level, or orientation.

### A. Zooming and Scaling

The use of fixed pixel values (`px`) for font sizes and widths can break layouts when a user zooms in.

* **Font Size:** Use relative units like `rem` or `em` to ensure text scales with the user's browser settings.
* **Layout:** Use fluid units (`%`, `vw`, `fr`) or flexible layouts (Flexbox/Grid) to allow the page to adapt gracefully without horizontal scrolling.

<AdsComponent />
<br />

### B. Hiding Content Accessible

Sometimes, you need to visually hide content (e.g., a search label) while keeping it available for screen readers.

* **Do NOT use `display: none` or `visibility: hidden`:** These hide content from *all* users, including screen readers.
* **Use the Visually Hidden Technique:** Apply a set of styles that hides the element visually but keeps it in the accessibility tree.

```css title="styles.css"
/* Visually hides content but keeps it available for screen readers */
.visually-hidden {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px; /* Avoid margin collapsing issues */
overflow: hidden;
clip: rect(0, 0, 0, 0); /* Legacy hiding technique */
white-space: nowrap;
border-width: 0;
}
```

## Conclusion

By following these CSS accessibility best practices, you can create web interfaces that are inclusive and usable for all users. Always test your designs with real users and assistive technologies to ensure your accessibility efforts are effective. Remember, accessibility is not just a checklist, it's a commitment to providing equal access to information and functionality for everyone.
207 changes: 206 additions & 1 deletion docs/css/best-practices/maintainability.mdx
Original file line number Diff line number Diff line change
@@ -1 +1,206 @@
<ComingSoon />
---
title: "CSS Maintainability and Architecture"
description: "Learn best practices for writing scalable, readable, and easy-to-maintain CSS, focusing on architecture, naming conventions, and style separation for large projects."
keywords: [CSS maintainability, CSS architecture, BEM, component-based CSS, style organization, OOCSS, SMACSS, CSS guidelines]
tags: ['css', 'maintainability', 'best-practices', 'architecture', 'bem', 'oocss', 'smacss']
sidebar_label: Maintainability
---

Writing CSS for small projects is straightforward. Writing CSS for large, evolving, and collaborative applications requires a structured, architectural approach to ensure the codebase remains **readable, scalable, and easy to debug** over time.

Maintainable CSS is predictable CSS.

<AdsComponent />
<br />

## 1. The Core Principles of Maintainability

### A. Predictability

Styles should apply consistently, and developers should immediately know what an element will look like just by looking at its class names. This is where specificity control (e.g., using Cascade Layers) and naming conventions (e.g., BEM) are crucial.

### B. Scalability

The architecture must support growth without increasing complexity. Adding a new component should not require modifying existing, unrelated CSS files.

### C. Readability

Styles should be organized logically, comments should explain complex intent, and naming should be explicit, not cryptic.

## 2. Naming Conventions: BEM and Utility-First

A robust naming convention is the backbone of maintainable CSS. It minimizes naming conflicts and reduces the need for high specificity.

### A. Block, Element, Modifier (BEM)

BEM is an organization strategy that ensures CSS selectors are flat, highly specific (via single classes), and highly descriptive. It enforces modularity by limiting selectors to a single class, removing dependency on the HTML structure.

| Part | Notation | Example | Description |
| :--- | :--- | :--- | :--- |
| **Block** | `block` | `.card` | Independent, reusable component (e.g., a header, a card). |
| **Element** | `block__element` | `.card__title` | A part of a block that cannot be used separately. |
| **Modifier** | `block--modifier` | `.card--dark` | A flag on a block or element to change its appearance or behavior. |

```css title="styles.css"
/* BEM Example */

/* Block: Defines the container structure */
.card {
border: 1px solid #ccc;
padding: 16px;
}

/* Element: Only applies inside the .card block */
.card__title {
font-size: 1.5rem;
margin-bottom: 8px;
}

/* Modifier: A variant of the Block */
.card--dark {
background-color: #333;
color: white;
}
```

<AdsComponent />
<br />

### B. Utility-First (Tailwind CSS)

Frameworks like Tailwind prioritize maintainability by eliminating custom CSS entirely. Maintainability comes from:

1. **Scope Control:** Styles are applied directly to the element via classes, making the scope local.
2. **No Naming Decisions:** Developers spend no time on complex naming conventions.
3. **Encapsulation:** Every component carries its styles with it, guaranteeing predictability.

**For Example:**

```html title="index.html"
<!-- Tailwind CSS Example -->
<div class="border border-gray-300 p-4">
<h2 class="text-2xl mb-2">Card Title</h2>
<p class="text-gray-700">This is a simple card component.</p>
</div>
```

## 3. Architectural Separation (SMACSS/OOCSS)

For projects using traditional CSS or preprocessors, styles should be separated into logical files based on their purpose.

### A. SMACSS (Scalable and Modular Architecture for CSS)

SMACSS suggests organizing files based on five style categories:

| Category | Description | Examples |
| :--- | :--- | :--- |
| **Base** | Default, unclassed element styles. | `body`, `h1`, `a`, `input` |
| **Layout** | Major structural components and grid. | `#header`, `.l-sidebar`, `.grid-layout` |
| **Module** | Reusable, independent components. | `.card`, `.button`, `.modal` |
| **State** | Styles describing transient states. | `.is-hidden`, `.is-active`, `[aria-expanded="true"]` |
| **Theme** | Overrides for colors, fonts, and images. | `.t-dark-mode` |

<AdsComponent />
<br />

### B. Object-Oriented CSS (OOCSS)

OOCSS promotes two core concepts to increase code reuse:

1. **Separate Structure and Skin:** Keep the structural properties (`width`, `height`, `margin`) separate from the visual properties (`color`, `border`, `background`).
* *Example:* A `.media-object` class defines the padding and display, while `.red-theme` defines the border color.
2. **Separate Container and Content:** Styles should not be dependent on where they are placed. Avoid location-dependent selectors (e.g., `#sidebar h2`).

**For Example:**

```css title="styles.css"
/* Structure */
.media-object {
display: flex;
padding: 16px;
}
.media-object__image {
margin-right: 16px;
}
.media-object__content {
flex: 1;
}
/* Skin */
.red-theme {
border: 2px solid red;
background-color: #ffe5e5;
}
```

## 4. Documentation and Comments

CSS is often the least documented part of a codebase. Good documentation is crucial for maintenance.

### A. File-Level and Section Comments

Every CSS file should start with a header explaining its purpose, dependencies, and author. Within the file, use large comment blocks to delineate major sections.

```css title="styles.css"
/* ------------------------------------
/* COMPONENTS: CARD MODULE (.card)
/* Dependencies: none
/* Description: Reusable container for content blocks.
/* ------------------------------------ */
```

### B. Explaining Specificity Hacks

If you *must* use `!important` or high specificity (e.g., an ID selector), provide a clear, detailed comment explaining:

1. *Why* the high specificity was necessary (e.g., "Must override third-party library X").
2. What styles the selector is intended to override.

<AdsComponent />
<br />

## 5. Preprocessor and Postprocessor Organization

If using a tool like Sass or Less, leverage its features for maintainability:

1. **Variables and Mixins:** Centralize common values (colors, fonts, breakpoints) into variables and reuse blocks of code via mixins.
2. **Nesting (Use Sparingly):** Limit nesting to a maximum of two or three levels deep to prevent complex, high-specificity selectors that break predictability.
3. **Partials:** Use `@import` or `@use` to break the monolithic CSS file into smaller, focused partials (e.g., `_buttons.scss`, `_variables.scss`, `_layout.scss`).

<Tabs>
<TabItem value="scss" label="styles.scss">
```scss
// Variables
$primary-color: #1d4ed8;
$secondary-color: #9333ea;
// Mixin
@mixin button-styles {
padding: 8px 16px;
border: none;
border-radius: 4px;
cursor: pointer;
}

.button {
@include button-styles;
background-color: $primary-color;
color: white;
}
```
</TabItem>
<TabItem value="css" label="styles.css">
```css
.button {
padding: 8px 16px;
border: none;
border-radius: 4px;
background-color: #1d4ed8; /* $primary-color */
color: white;
cursor: pointer;
}
```
</TabItem>
</Tabs>

## Conclusion

Maintainable CSS is essential for large-scale web applications. By following structured naming conventions like BEM, organizing styles using architectural patterns like SMACSS or OOCSS, and documenting your code effectively, you can ensure that your CSS remains scalable, readable, and easy to maintain over time. Always prioritize predictability and clarity in your styles to facilitate collaboration and future development.
Loading