# Styling Best Practices & Guidelines
**Version:** 2.0.0
**Last Updated:** 2025-11-19
**Status:** ✅ Complete
---
## Quick Reference
### Golden Rules
1. ✅ **Use global patterns first** - Check [CSS_PATTERNS.md](./CSS_PATTERNS.md)
2. ✅ **Use design tokens** - `var(--color-primary)` not `#2563eb`
3. ❌ **No `:deep()` in components** - PrimeVue styles in `vendor/primevue-overrides.css`
4. ❌ **No duplication** - Write CSS once, use everywhere
5. ❌ **No hardcoded values** - Use tokens for all values
---
## Design Token Usage
### Colors
```css
/* ✅ GOOD */
color: var(--color-primary);
background: var(--color-bg);
border-color: var(--color-border);
/* ❌ BAD */
color: #2563eb;
background: #ffffff;
border-color: #e5e7eb;
```
### Spacing
```css
/* ✅ GOOD */
padding: var(--space-md);
margin: var(--space-lg);
gap: var(--space-sm);
/* ❌ BAD */
padding: 16px;
margin: 24px;
gap: 8px;
```
### Typography
```css
/* ✅ GOOD */
font-size: var(--text-base);
font-weight: var(--font-semibold);
line-height: var(--leading-normal);
/* ❌ BAD */
font-size: 16px;
font-weight: 600;
line-height: 1.5;
```
---
## File Organization
```
src/assets/css/
├── core/ # Foundation (DO NOT MODIFY without team approval)
│ ├── variables.css # Base CSS variables
│ ├── tokens.css # Extended design tokens
│ ├── reset.css # CSS reset
│ └── typography.css # Font definitions
│
├── patterns/ # Reusable interactive patterns
│ ├── interactive.css # Spinners, trends, collapse
│ ├── dashboard.css # Page headers, metrics, breakdowns
│ └── animations.css # Transitions & animations
│
├── components/ # Component library
│ ├── cards.css # All card variants
│ ├── buttons.css # All button styles
│ ├── forms.css # Form patterns
│ ├── tables.css # Table styles
│ └── stats.css # Statistics displays
│
├── layout/ # Page structure
│ ├── containers.css # Content containers
│ ├── grid.css # Grid system
│ └── navigation.css # Navigation components
│
├── utilities/ # Utility classes
│ ├── colors.css # Color utilities
│ ├── text.css # Typography utilities
│ ├── spacing.css # Margin/padding utilities
│ ├── flex.css # Flexbox utilities
│ └── display.css # Display utilities
│
└── vendor/ # Third-party overrides
└── primevue-overrides.css # PrimeVue customization
```
---
## Naming Conventions
### Classes
```css
/* Component classes: .component-name */
.card { }
.btn { }
.form-input { }
/* Variant classes: .component-variant */
.btn-primary { }
.btn-secondary { }
.card-elevated { }
/* State classes: .state */
.active { }
.disabled { }
.invalid { }
/* Utility classes: .utility-value */
.text-center { }
.flex { }
.mt-lg { }
```
### BEM (When Needed)
```css
/* Block__Element--Modifier */
.metric-card { } /* Block */
.metric-card__header { } /* Element */
.metric-card--compact { } /* Modifier */
```
---
## Performance
### CSS Bundle Optimization
```css
/* ✅ GOOD: Group related selectors */
.btn,
.btn-primary,
.btn-secondary {
display: inline-flex;
align-items: center;
}
/* ❌ BAD: Repeat properties */
.btn { display: inline-flex; align-items: center; }
.btn-primary { display: inline-flex; align-items: center; }
.btn-secondary { display: inline-flex; align-items: center; }
```
### Animations
```css
/* ✅ GOOD: Use transform & opacity (GPU-accelerated) */
.card-hover:hover {
transform: translateY(-2px);
opacity: 0.9;
}
/* ❌ BAD: Animate layout properties */
.card-hover:hover {
top: -2px; /* Forces reflow */
height: 110%; /* Forces reflow */
}
```
---
## Accessibility
### Color Contrast (WCAG 2.1 AA)
```css
/* ✅ GOOD: 4.5:1 contrast ratio */
color: var(--color-text); /* #111827 on #ffffff = 16.9:1 */
background: var(--color-bg);
/* ✅ GOOD: Large text (18px+) needs 3:1 */
.heading {
font-size: var(--text-xl);
color: var(--color-text-secondary); /* #6b7280 = 4.6:1 */
}
```
### Focus States
```css
/* ✅ GOOD: Visible focus indicator */
.btn:focus-visible {
outline: 2px solid var(--color-primary);
outline-offset: 2px;
}
/* ❌ BAD: Removing focus */
.btn:focus {
outline: none; /* Never do this! */
}
```
### Touch Targets (Mobile)
```css
/* ✅ GOOD: Minimum 44x44px */
.btn {
min-height: 44px;
min-width: 44px;
padding: var(--space-sm) var(--space-md);
}
```
---
## Browser Compatibility
### Supported Browsers
- Chrome 90+
- Firefox 88+
- Safari 14+
- Edge 90+
### Use Modern CSS
```css
/* ✅ GOOD: Modern CSS features */
.grid {
display: grid;
gap: var(--space-md);
}
.card {
aspect-ratio: 16 / 9;
}
/* ⚠️ If using very new features, check caniuse.com */
```
---
## Testing
### Before Committing
```bash
# 1. Build check
npm run build
# 2. Visual regression tests
npm run test:e2e
# 3. Check bundle size
ls -lh dist/assets/*.css
```
### Manual Testing Checklist
- [ ] Desktop (1920x1080, 1366x768)
- [ ] Tablet (768x1024)
- [ ] Mobile (375x667, 414x896)
- [ ] Dark mode (if applicable)
- [ ] Print view (`@media print`)
- [ ] Keyboard navigation (Tab through elements)
- [ ] Screen reader (test with NVDA/JAWS)
---
## Code Review Standards
### CSS in PRs
Reviewers check for:
1. **No duplication** - Pattern exists in global CSS?
2. **Design tokens** - All values use `var(--*)`?
3. **No `:deep()`** - PrimeVue overrides in correct file?
4. **Scoped CSS justified** - < 50 lines & documented?
5. **Responsive** - Works on all breakpoints?
6. **Accessible** - Focus states, contrast ratios?
7. **Performance** - No layout thrashing animations?
8. **Tested** - Build passes, E2E tests pass?
---
## Common Mistakes
### ❌ Mistake #1: Not Checking Pattern Library
```vue
```
### ❌ Mistake #2: Hardcoded Values
```css
/* Wrong */
padding: 16px;
color: #2563eb;
border-radius: 8px;
/* Correct */
padding: var(--space-md);
color: var(--color-primary);
border-radius: var(--radius-md);
```
### ❌ Mistake #3: Using `:deep()` for PrimeVue
```vue
```
---
## Resources
- **Pattern Library:** [CSS_PATTERNS.md](./CSS_PATTERNS.md)
- **Component Guidelines:** [COMPONENT_STYLING.md](./COMPONENT_STYLING.md)
- **Form Template:** [FORM_TEMPLATE.md](./FORM_TEMPLATE.md)
- **Design Tokens:** [DESIGN_TOKENS.md](./DESIGN_TOKENS.md)
- **Onboarding:** [ONBOARDING_CSS.md](./ONBOARDING_CSS.md)
---
**Last Updated:** 2025-11-19
**Version:** 2.0.0
**Maintained By:** Frontend Team