# 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