Move styles from Tailwind to CSS using our styles
Context
As our codebase grows, we're moving away from inline Tailwind CSS classes toward a more maintainable CSS architecture using component-specific stylesheets. This transition helps improve code readability, reduces duplication, and creates a more consistent design system.
Objective
Refactor components to move Tailwind CSS classes into dedicated component-level CSS files following our established styling patterns and variable naming conventions.
Implementation Guidelines
1. Create Component-Specific CSS Files
For each component that needs styling, create a corresponding CSS file in the same directory:
text
/components/reference/VocabularyPreviewCard.astro
/components/reference/VocabularyPreviewCard.css
2. Use Project CSS Variables
Leverage our existing CSS variables defined in
global.css
and other base stylesheets:- Color variables like
--clr-lossless-primary-dark
,--clr-lossless-accent--brightest
- Gradient variables like
--grd--lossless-eastern-crimson
- Opacity variants like
--white--pure--20p
3. Naming Convention for CSS Classes
Follow our established naming pattern:
- Use component name as prefix:
.vocabulary-preview-card
- Use BEM-like modifiers for variants:
.vocabulary-preview-card__title
- Maintain semantic naming:
.vocabulary-preview-card__alias-list
4. Import CSS in Component
At the top of each Astro component file, import the corresponding CSS:
astro
---
// Component logic here
---
<style>
@import './ComponentName.css';
</style>
<!-- Component markup -->
5. Example Refactoring
Before (Tailwind):
astro
<div class="bg-gray-800 p-4 rounded-lg">
<h3 class="text-sm font-bold mb-2">
<a href={url} class="text-blue-400 hover:underline">
{entry.data.title}
</a>
</h3>
<p class="text-xs text-gray-400 mb-2">
Also known as: {entry.data.aliases.join(', ')}
</p>
</div>
After (Component CSS):
astro
<div class="vocabulary-card">
<h3 class="vocabulary-card__title">
<a href={url} class="vocabulary-card__link">
{entry.data.title}
</a>
</h3>
<p class="vocabulary-card__aliases">
Also known as: {entry.data.aliases.join(', ')}
</p>
</div>
With corresponding CSS:
css
.vocabulary-card {
background-color: var(--clr-lossless-primary-dark);
padding: 1rem;
border-radius: 0.5rem;
}
.vocabulary-card__title {
font-size: 0.875rem;
font-weight: 700;
margin-bottom: 0.5rem;
}
.vocabulary-card__link {
color: var(--clr-lossless-accent--brightest);
}
.vocabulary-card__link:hover {
text-decoration: underline;
}
.vocabulary-card__aliases {
font-size: 0.75rem;
color: var(--white--pure--70p);
margin-bottom: 0.5rem;
}
6. Continuous Refactoring Strategy
- Start with the most frequently used components
- Refactor one component at a time
- Update all instances where the component is used
- Add comprehensive comments explaining the styling choices
- Document any new CSS variables in a central location
7. Benefits of This Approach
- Improved readability: Class names are semantic and self-documenting
- Better maintainability: Style changes can be made in one place
- Reduced duplication: Common styles are centralized
- Stronger typing: CSS classes can be documented with TypeScript interfaces
- Better performance: Reduced CSS payload in production builds
8. Testing After Refactoring
- Verify visual consistency across all screen sizes
- Check for any unintended style inheritance
- Ensure proper dark/light mode support
- Validate accessibility (contrast, focus states, etc.)
Example Components to Refactor
- VocabularyPreviewCard
- ConceptPreviewCard
- Navigation tabs in more-about pages
- Section headers and containers