thecodingtrain.com
thecodingtrain.com copied to clipboard
Add Dark Mode Feature to thecodingtrain Website
Dark Mode Feature Proposal
Description: As a user of thecodingtrain website, I often find myself browsing late at night or in low-light environments where a dark mode would be more comfortable for my eyes. I propose adding a dark mode feature to the website to enhance user experience and accessibility.
Benefits:
- Improves user experience, especially in low-light environments.
- Provides greater accessibility options for users with sensitivity to bright light.
- Aligns with current web design trends and user preferences.
Additional Notes:
- This feature could be made toggleable via a button in the website's header or through a settings menu.
- browser preferences to enable easy switching between light and dark modes.
Preview:
Dark Mode
Desktop
Small Screen (Mobile/Tablet)
Light Mode
Desktop
Small Screen (Mobile/Tablet)
Feel free to provide any feedback or suggestions for improving this feature.
Once I complete the user preferences part, I will proceed to create a pull request. @shiffman
Hi @Yashasewi thank you for this! This is widely requested and would be wonderful to integrate. @runemadsen this affects the design quite significantly, would you mind offering any feedback or thoughts before we proceed with any implementation?
This will be very cool! I would just make sure that the softness coming from the light grays are transferred to the dark mode layout by using blacks that are not fully black. I would make sure to use CSS variables so this is easy to tweak, and I'll be happy to take a look once the initial PR is in :)
Thank you @runemadsen! It occurred to me that @jasontheillustrator might also want to take a look as dark mode may affect the illustrations and logos on the site as well. Thank you again @Yashasewi!
Thanks Dan! This looks really good. I think the majority of the characters work just fine with dark mode. There's a couple that might be a little tricky depending on the black that is used for the background. This one for example is starting to look a bit weird because the eyes don't have much contrast to the background.
Right now it's probably ok. If the black background is toned down a bit, there will be less contrast with the eyes and mouth. Could we show a "dark mode" version of this character where the colors are tweaked slightly so that they show up better on a dark background? Either that or we just swap out this character for one that works better on light and dark mode.
Ah sorry, I completely missed the previews π¬ I think this is looking really good!
I would consider making the darks a bit lighter. It doesn't have to be much (perhaps closer to what we do on our site so it doesn't come off as contrasted. I think we should find a way to keep the soft red lines on the background, but we can take all of that once there's a PR to check.
Hi everyone! Thank you for the valuable feedback and suggestions regarding the dark mode feature. I've been working on the implementation, I try to implement this feature as early as possible. Create an initial pr for feedback.
Hi everyone,
Before proceeding with the pull request, I'd like to discuss the approach I've taken for implementing the dark mode feature.
Implementation Approach:
Instead of using CSS variables, I've implemented dark mode using the CSS filter
property, specifically
filter: invert(100%) hue-rotate(180deg);
This approach was inspired by the blog post Implementing dark mode in a handful of lines of CSS with CSS filters.
Advantages:
- Simple and lightweight implementation without the need for complex CSS variables or JavaScript manipulation of styles.
- Provides a consistent dark mode experience across the entire website, including third-party components and user-generated content.
Potential Drawbacks:
- May lead to undesirable effects on certain elements or images, requiring additional CSS rules or exceptions.
- Limited control over individual element colors compared to using CSS variables or separate stylesheets.
Implementation Details: I've included the CSS and JavaScript code snippets for reference. Here's a brief overview:
Please ignore comments.
-
CSS: The dark mode styles apply the
filter
property to thebody
element, effectively inverting the colors. Additional rules are included to handle specific elements like images, SVGs, code blocks, and list item markers.CSS Code ππ
body { /* background-color: var(--html-bg-color); */ filter: var(--filter-bg); /* color: var(--gray-dark); */ } html { /* background-color: #000000; */ background-color: var(--html-bg-color); /* background-color: #ffffff; */ } /* Do not invert media (revert the invert). */ img, video, iframe { /* filter: invert(100%) hue-rotate(180deg); */ filter: var(--filter-bg); /* filter: none; */ } svg { /* filter: invert(95%) hue-rotate(180deg); */ filter: var(--svg-filter-bg); /* filter: none; */ } /* Re-enable code block backgrounds. */ pre { /* filter: invert(6%); */ filter: var(--filter-pre-bg); } /* Improve contrast on list item markers. */ li::marker { /* color: #666; */ color: var(--color-li-bg); }
-
JavaScript: The
ThemeProvider
component manages the theme state (dark
) and provides atoggle
function to switch between light and dark modes. It usesuseLayoutEffect
to apply the theme and persist the user's preference inlocalStorage
.JavaScript code ππ
import React, { useState, useLayoutEffect } from 'react'; /** * ThemeContext is a Context that holds the state of the theme and the method to toggle it * @type {React.Context<{dark: boolean, toggle: () => void}>} * @returns {JSX.Element} * @constructor * @param {boolean} dark - the current state of the theme * @param {() => void} toggle - the method to toggle the theme * @returns {JSX.Element} * */ export const ThemeContext = React.createContext({ dark: false, toggle: () => {} }); /** * ThemeProvider component is a Context Provider that passes down the state and the method to toggle the theme * @param children - the child components wrapped by the ThemeProvider * @returns {JSX.Element} * */ export default function ThemeProvider({ children }) { const [dark, setDark] = useState(false); useLayoutEffect(() => { const storedPreference = localStorage.getItem('darkModePreference'); if (storedPreference !== null) { setDark(JSON.parse(storedPreference)); } else { const prefersDarkMode = window.matchMedia( '(prefers-color-scheme: dark)' ).matches; setDark(prefersDarkMode); } }, []); useLayoutEffect(() => { applyTheme(); }, [dark]); const applyTheme = () => { let theme; if (dark) { theme = darkTheme; localStorage.setItem('darkModePreference', 'true'); } else { theme = lightTheme; localStorage.setItem('darkModePreference', 'false'); } const root = document.getElementsByTagName('html')[0]; root.style.cssText = theme.join(';'); }; const toggle = () => { const body = document.getElementsByTagName('body')[0]; body.style.cssText = 'transition: background .5s ease'; setDark(!dark); }; return ( <ThemeContext.Provider value={{ dark, toggle }}> {children} </ThemeContext.Provider> ); } // styles const lightTheme = [ '--filter-bg: none', // '--red-lightest: #fffcfc', '--html-bg-color: #ffffff', // '--gray-light: #ededed', // '--gray-dark: #3c3c3c' '--svg-filter-bg: none', '--filter-pre-bg: none', '--color-li-bg: inherit' ]; const darkTheme = [ '--filter-bg: invert(100%) hue-rotate(180deg)', // '--red-lightest: #1e1d20', // '--html-bg-color: #1e1d20', '--html-bg-color: #000000', // '--gray-light: #1e1d20', // '--gray-dark: #f5f5f5' '--svg-filter-bg: invert(100%) hue-rotate(180deg)', '--filter-pre-bg: invert(6%)', '--color-li-bg: #666' ];
Updated preview ππ
Dark Mode Desktop
Next Steps: While this approach seems promising, I wanted to get your feedback and opinions before proceeding with the pull request. Are there any potential issues or concerns with using CSS filters for dark mode implementation? Is there a better approach that aligns with the project's design principles and ensures a seamless user experience?
I'm open to suggestions and willing to explore alternative implementations if deemed more suitable.
Please let me know your thoughts, and I'll be happy to address any concerns or make adjustments as needed.
Thank you for your valuable input and collaboration!
@shiffman @runemadsen @jasontheillustrator
Thanks for this description @Yashasewi. It's super helpful to understand the approach. Having thought about it for a bit, I would highly recommend to not do the dark mode with CSS filters, as all the brand colors will have random opposites applied without us being able to select those colors. I think a better solution would be to apply a theming class to the body and override the CSS variables that we're already using throughout the site. It won't be much more work, and it would allow us to pick the individual colors, which is much preferred compared to just inverting the entire color scheme.
Thank you, @runemadsen, for your valuable feedback and suggestion. I appreciate you taking the time to review the CSS filter approach and providing your insights.
Based on your recommendation, I have implemented the dark mode feature using CSS variables and theming classes. This approach allows for better control over individual colors and ensures that the branding and design elements retain their intended appearance.
Remaining Issues:
While implementing the dark mode with CSS variables, I encountered a few instances where colors were hard-coded instead of using variables. I have identified and updated most of these instances, but there may still be some areas that need further attention.
If you or the team members notice any inconsistencies or issues with the dark mode implementation, please feel free to point them out, and I'll address them promptly.
Dark Mode Colors:
I have carefully selected the new dark mode colors to ensure a visually appealing and consistent experience. However, I would appreciate your feedback and input from the design team (@runemadsen, @jasontheillustrator) to ensure that the chosen colors align with the project's branding and design principles.
Next Steps:
I plan to create a pull request with the updated dark mode implementation. This will allow the all of you to review the changes, provide feedback, and contribute to further refinements if necessary.
Please let me know if you have any additional suggestions or concerns. I'm happy to make any necessary adjustments to ensure a successful integration of the dark mode feature.
Thank you again for your guidance and collaboration!
@shiffman @runemadsen @jasontheillustrator
That sounds amazing @Yashasewi! It's wonderful that you took the time to make the use of CSS variables even better. Can't wait to review the PR, so let me know when it's ready :)
That sounds amazing @Yashasewi! It's wonderful that you took the time to make the use of CSS variables even better. Can't wait to review the PR, so let me know when it's ready :)
Thank you, @jasontheillustrator! I'm glad you liked CSS variables approach. I'll keep you updated and notify you once ready for review. Kind of little busy with some thingsπ₯²
Hi everyone,
I've completed the implementation of the dark mode feature, and I'm excited to share that I've created a pull request for your review and feedback.
Pull Request: #1554 Dark Mode Implementation
In this pull request, I've addressed the following:
- Implemented dark mode using CSS variables
- Created a dedicated
theme.js
component to manage CSS variables for light and dark modes - Updated existing styles to reference the appropriate CSS variables for theming
- Addressed instances of hard-coded colors and updated them to use CSS variables
Please take a look at the pull request description for more details on the implementation, potential issues, screenshots, and next steps.
I would greatly appreciate it if you could review the changes and provide your feedback. I'm happy to address any concerns or make further adjustments as needed.
Thank you for your collaboration and support throughout this process. I'm looking forward to your valuable insights and working together to ensure a seamless integration of the dark mode feature.
@shiffman @runemadsen @jasontheillustrator