Expand my Community achievements bar.

Don’t miss the AEM Skill Exchange in SF on Nov 14—hear from industry leaders, learn best practices, and enhance your AEM strategy with practical tips.
SOLVED

CSS optimization for DarkMode

Avatar

Level 3

Hi Everyone,

We are working to achieve Dark Mode functionality for our components. We have achieved the functionality ,but the point where we need suggestions/solutions is for optimizing CSS.
We have tried the below ways to include CSS :

1. Place the CSS in the clientlibs : placing the CSS in the clientlibs is creating an issue for us.The issue is
it generates <link> tag  like this  <link rel="stylesheet" type="text/css" href="mystyle.css"> . This is an issue because our components are used on email clients , and some of the email clients will not support this and it will break the component and the content.

2. Tried placing the CSS in Component's HTML (internal style sheet) - does not work as expected.

3. used wcmBindings- helper class, not working (found it on some article , very less knowledge about it.)

 

Our aim is to optimize CSS, or load the css classes dynamically for the component, so that the page load is faster, and when we author the page and check the page source, we should see only the CSS class relatable to us, instead of other CSS class, which is not required for that component.

Note : I've tried to explain the scenario in simpler way, if it's not clear, please ask more questions in comments. Thanks.

@kautuk_sahni 

1 Accepted Solution

Avatar

Correct answer by
Community Advisor

Hi @adi411 

To use CSS Modules, you can create a separate CSS file for each component and import it into the component's JavaScript file. Then, you can use the CSS classes defined in that file in your component's HTML. This way, you can ensure that only the CSS classes required for that component are loaded on the page.

import React from 'react';
import styles from './MyComponent.module.css';

const MyComponent = () => {
  return (
    <div className={styles.container}>
      <h1 className={styles.title}>Hello World</h1>
      <p className={styles.description}>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
    </div>
  );
};

export default MyComponent;

we have a component called MyComponent and a CSS file called MyComponent.module.css. We import the CSS file into the component's JavaScript file using the import statement and assign it to a variable called styles. We can then use the CSS classes defined in the file by accessing them as properties of the styles object.

<div class="MyComponent_container_abc123">
  <h1 class="MyComponent_title_abc123">Hello World</h1>
  <p class="MyComponent_description_abc123">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</div>

As you can see, the CSS classes are automatically given unique names based on a hash of the file contents. This ensures that the CSS is scoped to the component and won't interfere with other components on the page. 



View solution in original post

6 Replies

Avatar

Correct answer by
Community Advisor

Hi @adi411 

To use CSS Modules, you can create a separate CSS file for each component and import it into the component's JavaScript file. Then, you can use the CSS classes defined in that file in your component's HTML. This way, you can ensure that only the CSS classes required for that component are loaded on the page.

import React from 'react';
import styles from './MyComponent.module.css';

const MyComponent = () => {
  return (
    <div className={styles.container}>
      <h1 className={styles.title}>Hello World</h1>
      <p className={styles.description}>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
    </div>
  );
};

export default MyComponent;

we have a component called MyComponent and a CSS file called MyComponent.module.css. We import the CSS file into the component's JavaScript file using the import statement and assign it to a variable called styles. We can then use the CSS classes defined in the file by accessing them as properties of the styles object.

<div class="MyComponent_container_abc123">
  <h1 class="MyComponent_title_abc123">Hello World</h1>
  <p class="MyComponent_description_abc123">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</div>

As you can see, the CSS classes are automatically given unique names based on a hash of the file contents. This ensures that the CSS is scoped to the component and won't interfere with other components on the page. 



Avatar

Community Advisor

@adi411 

Here is an earlier adobe community question related to dark mode in AEM if is of any use

https://experienceleaguecommunities.adobe.com/t5/adobe-experience-manager/dark-light-mode-in-aem/td-...

 

Here are some of the things you can do for optimization or different way to implement this

  • Use Sling Dynamic Include to get the dynamic cache state from the server and set the necessary mode on page load. This approach allows you to retrieve the theme mode from the server during page rendering, ensuring the correct mode is applied initially.
  • Add a blocking script on the client-side JavaScript that will run during the body loading. This script can check the user's preference (e.g., from local storage or cookies) and apply the appropriate styles before the page is fully rendered.
  • Inject inline CSS styles dynamically using JavaScript. By defining your dark and light mode styles as JavaScript objects or strings, you can dynamically create <style> elements and inject them into the page's <head> section based on the desired mode. This approach avoids the need for external stylesheets and is compatible with email clients that may not support external CSS.
  • Use a clientlib with the category cq.authoring.editor.hook. This category allows you to add custom functionality to the AEM authoring interface, such as a button that toggles between dark and light modes for dialog boxes.
  • Set the theme color in the HTML node. This approach involves modifying the HTML markup to include the desired theme color, which can be used to apply dark or light mode styles.

The most suitable solution to optimize CSS and load it dynamically for components in Adobe Experience Manager (AEM) would be to use Client-Side Libraries (ClientLibs) along with the ui.frontend module and a webpack development server.

Avatar

Level 3

Hi @gkalyan  
Thank you for so many suggestions
Can you explain in details point number 1, 3 and 5.

Thanks
Aditya

Avatar

Community Advisor

Hi @adi411 ,

To optimize CSS for Dark Mode functionality in your components, you can consider the following approaches:

1. Use CSS Variables: CSS Variables allow you to define a set of variables that can be used throughout your CSS code. You can define variables for colors, fonts, and other properties that are used in your Dark Mode styles. By using CSS Variables, you can avoid duplicating CSS code and make it easier to switch between light and dark modes. Here's an example of how to define a CSS Variable for a color:

```
:root {
--primary-color: #007bff;
}

.button {
background-color: var(--primary-color);
}
```

2. Use CSS Preprocessors: CSS preprocessors like Sass or Less allow you to write CSS code with variables, mixins, and other features that make it easier to manage and optimize your styles. You can use preprocessors to define variables for your Dark Mode styles and generate optimized CSS code for your components.

3. Use Dynamic CSS Loading: You can use JavaScript to load CSS files dynamically based on the user's Dark Mode preference. For example, you can use the `matchMedia` API to detect if the user has enabled Dark Mode and load the appropriate CSS file. Here's an example of how to load a Dark Mode CSS file dynamically:

```
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
var link = document.createElement('link');
link.rel = 'stylesheet';
link.href = 'dark-mode.css';
document.head.appendChild(link);
}
```

4. Use Inline Styles: You can use inline styles to define styles for your components instead of using external CSS files. This can help reduce the number of HTTP requests and improve page load times. However, inline styles can be harder to manage and maintain, especially for larger components.

5. Use Critical CSS: Critical CSS is a technique that involves extracting the CSS code that is required to render the above-the-fold content of a page and inlining it in the HTML. This can help improve page load times and reduce the amount of CSS code that needs to be loaded. However, Critical CSS can be complex to implement and maintain, especially for dynamic content.

Overall, the best approach for optimizing CSS for Dark Mode functionality will depend on your specific requirements and constraints. You may need to experiment with different approaches and tools to find the best solution for your components.

Avatar

Level 3

Hi @gkalyan , @HrishikeshKa , @Raja_Reddy  

Thank you for your inputs, I found the Inlining of CSS can be done in AEM
and my team tried, but we faced lot of dependency errors. You can see the screenshot below from Adobe's article. Can you let me know, how it works

adi411_0-1716522971687.png
Link to the aritcle - https://experienceleague.adobe.com/en/docs/experience-manager-core-components/using/developing/inclu...

 

@kautuk_sahni  - I just want to know the above article and the Inlining approach mentioned in the adobe article, does it requires more dependency to be added in pom files to work.

 

Avatar

Administrator

@adi411 Did you find the suggestions from users helpful? Please let us know if you require more information. Otherwise, please mark the answer as correct for posterity. If you have found out solution yourself, please share it with the community.



Kautuk Sahni