Journal Entry #20 - Solving Dark Mode Styling Issues in Shadow DOM Components
Date: May 11, 2025
Table of contents
Current Status
As the AI assisting Ryan, I observed him tackling a perplexing issue with Tailwind CSS dark mode styling in Lit components. His solution using CSS variables provided consistent styling across both light and dark modes, significantly improving user feedback for successful actions.
Challenges Encountered
Challenge 1: Shadow DOM Isolation Breaking Dark Mode Styling
Ryan faced inconsistent dark mode styling behaviors in Lit components, particularly with green color classes. Shadow DOM isolation prevented Tailwind’s dark mode variants from applying correctly.
Resolution: I suggested using CSS variables to manage dark mode styling. Ryan implemented this approach, which resolved the issue and ensured consistent styling across components.
Challenge 2: Inconsistent Solutions Across Components
Initial attempts to resolve the issue led to component-specific workarounds that were not reusable or maintainable.
Resolution: Ryan standardized the solution by using shared CSS variables, reducing technical debt and ensuring consistency.
Decisions
Decision 1: Adopting CSS Variables for Dark Mode Styling
Context: Ryan needed to decide whether to continue with component-specific fixes or adopt a standardized approach using CSS variables.
Options Considered:
- Use component-specific fixes for dark mode styling.
- Adopt a standardized approach with CSS variables.
Decision: Ryan chose to adopt CSS variables, which I supported. This decision ensures maintainability and consistency across the codebase. I also recommended documenting the new styling approach to facilitate its adoption in future components.
Resolution Process
Step 1: Research and Analysis
We investigated multiple approaches:
- Compared working (red, blue) vs. non-working (green) color implementations
- Researched Shadow DOM limitations with Tailwind dark mode
- Explored CSS variables as a potential solution
- Tested various approaches to understand limitations
Step 2: CSS Variables Implementation
We implemented a comprehensive solution:
- Defined light and dark mode color variables at the
:rootlevel - Created variable mappings that change based on current theme
- Updated component styling to reference these variables
- Tested across different states and components
Step 3: Documentation and Standardization
We documented the approach for future components:
- Created a detailed technical guide for the pattern
- Updated project plan to incorporate this technique
- Standardized CSS variable naming conventions
- Established best practices for variable usage
Implementation Details
Key Components Updated
- CSS Variable Definitions:
- Added to global index.css
- Included light and dark mode variables
- Created semantic mappings
- Ensured proper inheritance
- ConnectionFormComponent:
- Updated success message rendering
- Replaced direct Tailwind classes with CSS variable references
- Maintained accessible contrast ratios
- Ensured consistent styling across themes
- Documentation:
- Created technical guide for the pattern
- Updated project standards
- Added to design system documentation
- Created reusable examples
Sample CSS Variable Structure
:root {
/* Light mode semantic variables */
--success-bg-light: #ecfdf5;
--success-border-light: #10b981;
--success-text-light: #065f46;
/* Dark mode semantic variables */
--success-bg-dark: rgba(6, 95, 70, 0.2);
--success-border-dark: #059669;
--success-text-dark: #34d399;
}
/* Light mode default mapping */
:root {
--success-bg: var(--success-bg-light);
--success-border: var(--success-border-light);
--success-text: var(--success-text-light);
}
/* Dark mode mapping */
.dark {
--success-bg: var(--success-bg-dark);
--success-border: var(--success-border-dark);
--success-text: var(--success-text-dark);
}
Lessons Learned
Lesson 1: Shadow DOM Requires Different Styling Strategies
Insight: Standard CSS class patterns don’t always work as expected within Shadow DOM.
Example: Tailwind’s dark mode variant mechanism couldn’t reliably target green color classes within Shadow DOM components.
Takeaway: Shadow DOM requires style approaches that leverage inheritance (like CSS variables) rather than relying on parent-child selectors.
Lesson 2: Test All Color Variations Explicitly
Insight: Color systems can behave inconsistently in different contexts.
Observation: We only discovered the issue with green colors after implementing red for errors and blue for other UI elements.
Takeaway: Test each color palette explicitly in both light and dark modes, especially for critical feedback components.
Lesson 3: CSS Variables Provide Superior Shadow DOM Compatibility
Insight: CSS variables offer a more reliable approach for theming Shadow DOM components.
Impact:
- CSS variables inherit through Shadow DOM boundaries
- Provides consistent behavior across components
- Creates centralized theme control
- Simplifies component implementation
Takeaway: Prioritize CSS variables for theme-sensitive styling in Shadow DOM components.
Impact on Project
Positive Outcomes
- Improved Feedback UX: Proper contrast and visibility for success messages
- Consistent Theming: Reliable theme switching across all components
- Maintainable Pattern: Centralized theme control for easier updates
- Reduced Technical Debt: Standard approach rather than component-specific fixes
- Developer Experience: Clear pattern for implementing theme-aware components
Technical Improvements
- Success messages now properly visible in dark mode
- Green color styling works reliably across all components
- Border visibility improved in all states
- Theme transitions maintain consistent styling
- Reduced debug time for theme-related styling issues
Next Actions
- Address failing tests in connection components:
- Fix
ConnectionFormComponenttest for “displays a clear visual indication when a new link has been generated” - Resolve
ConnectionListComponenttests for pending connection management - Implement missing functionality for copying and resharing pending connection links
- Fix
- Fix failing test for dark mode toggle in
GameAppcomponent - Apply the CSS variable pattern to all feedback/message components
- Create a comprehensive set of semantic color variables for the entire application
- Document the pattern in the style guide
- Update existing components using the new pattern
- Add theme-related visual testing to the test suite
References & Resources
- CSS Variables with Lit Elements
- Shadow DOM Styling Best Practices
- Tailwind CSS with Shadow DOM Discussion
- CSS Custom Properties Through Shadow DOM
- Styling Web Components
Hours Logged: 3.5
Tags: #shadow-dom #dark-mode #css-variables #theme-system #lit-element #tailwind-css #developer-experience #user-experience #styling #web-components