Using CSS Modules with ReactJS: Styling parent and child components separately

I'm currently working on a React application and I have a question. I have two separate components: and with CSS classes navigation.css and navigationLogo.css respectively. In navigation.css, I defined a class called .main, and in navigationLogo.css, I want to create a class like this:

.main .main_in_logo {
 color: red;
}

However, I am facing limitations with CSS Modules that prevent me from achieving this. Any suggestions for a workaround?

Answer №1

It seems that the explanations provided here are lacking in detail. In CSS, you would use .parentSelector .childSelector to target a child element. The same principle applies to CSS modules, but in your HTML/JSX, you need to assign the relevant className to both the parent and child elements -> styles.parentSelector , styles.childSelector.

<div className={styles.container}>text</div>

This approach allows you to define styles in your CSS like:

.banner .container{
background-color:red;
}
.banner .container{
background-color:blue;
}

At times, when using libraries, you may need to make changes to elements deep inside the library without being able to modify its source code. In such cases, you can utilize the :global selector like this:

.parentElement :global(div)
.parentElement :global(#some-lib-element-selector)

Answer №2

After searching for a solution to the same problem and coming up empty here, I realized that the post is quite outdated at 3 years old. The accepted answer, in my opinion - shared by others as well, is not very scalable.

It may not be anything groundbreaking, but I ended up figuring out my own approach in vanilla CSS that could be adapted to CSS modules.

Here's what I came up with that perfectly meets my requirements:


/* parent.css */
.main {
   ...some CSS...
}

/* logo.css */
@value main from "./parent.css";

.logo {
   ...some CSS...
}

.main .logo {
   color: red
}

In this solution, we utilize @value, a CSS modules variable, which allows us to link with another file to construct a selector incorporating the actual name of the parent like "main".

Although it seemed unusual at first, discovering this approach did take some time. Hopefully, sharing this will save others time and assist them too!

Answer №3

It is best practice for the child component to have its own independent CSS rules, rather than relying on the parent's CSS classname.

In this case, the child component should simply be:

.main_in_logo { color: red; }

If there is a need for styles that involve both the parent and child components, it is recommended to define these styles entirely in the parent component:

/* navigation.css */
.main .main_in_logo {
   color: red;
}

The parent component can then pass the CSS class to the child component and instruct it to use it:

// Navigation.js
<NavigationLogo className={navigationCss.main_in_logo} />

// NavigationLogo.js
<div className={"foo " + this.props.className}>stuff</div>

Answer №4

Creating .main .main_in_logo is essential for maintaining the integrity of your CSS styles in the long run. By styling parent elements, you can prevent interference from other styles down the line. However, this becomes a challenge with CSS modules as your styles become permanently unique.

If you absolutely need to style these two components together, consider using global CSS. You can find more information on how to do this in the documentation for react-css-modules.

Answer №5

When utilizing CSS modules in ReactJS, there is no need to explicitly state which child class you are targeting.

For example:

.main_in_logo {
     color: red;
}

This declaration will suffice in the stylesheet.

Answer №6

I opted for a traditional CSS approach but implemented it using the BEM convention.

Essentially, CSS modules simply append '[this_name].module.css' to your css classes. If you inputted it correctly from the start, there would be no need for this. It's essentially an abstraction that helps beginners handle class name conflicts.

// Main.jsx
import './Main.css'
import Logo from './Logo.jsx'

const Main = () => {
  return (
    <div className="main">
      <Logo className="main__logo" />
    </div>
  )
}
/* Main.css */
.main {/* apply styles */}
.main__logo {/* apply specialized styles for the Logo component */}

For example, if you had a `Logo` component like this..

// Logo.jsx
import './Logo.css'

const Logo = () => {
  return (
    <div className="logo">
      <img className="logo__img" />
    </div>
  )
}
/* Logo.css */
.logo {/* style rules for logo */}
.logo__img {/* specific styling for the logo's image */}

This method feels more intuitive and organic.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

having difficulty resolving the problem when utilizing bootstrap classes

I am currently facing two issues with my code. The first one is that the header is not remaining fixed, and the second issue is that word wrapping is not working for the headers/rows. Even though I have used bootstrap classes, these problems persist. I am ...

Is it advisable to start a function within the componentDidMount() method in ReactJS when using promises?

I am developing an application that utilizes promises to manage animations. After a few attempts, I encountered the following error message: Warning: Can’t call setState on a component that is not yet mounted. This is a no-op, but it might indica ...

Modify the fixed div's class when the user scrolls past a certain section

My page includes a fixed menu with various sections, each assigned a specific class name using data attributes (e.g. data-menu="black"). I want the fixed menu to change its class based on the section that is currently underneath it as the user scrolls. Y ...

What is causing my page to automatically refresh whenever I click on buttons?

The code snippet below shows the structure of my webpage : HTML : <button class="add-col"><i class="fas fa-columns"> Add a column</i></button> <div class="table-responsive"> <table class="table"> ...

Sorting tables in Material UI by default

I am trying to display data in a material UI table sorted by average attendance from lowest to highest. Is there a way to achieve this sorting by default when the table loads in the browser? Here is a snippet of my table and some sample data. I want the ...

Encountering an issue in next.js with dynamic routes: getting a TypeError because the property 'id' of 'router.query' cannot be destructured since it is undefined

I am working on creating a dynamic page in next.js based on the ID. Here is the basic structure of my project: File path: app/shop/[id]/page.tsx This is the code snippet: "use client" .... import { useEffect, useState } from 'react' ...

Having Trouble With Your Font Display?

I am confident that my code is correct. Here's a snippet from what I've done: <!DOCTYPE html> <html> <head> <link rel="stylesheet" href="homepage.css"/> </head> <body> <div id="menu"> &l ...

Is there a way for me to adjust my navbar menu items so they are aligned to the right

Currently, I'm designing a navbar and I'm facing an issue with aligning a specific part to the right side: Here is the current setup I have: Moreover, the collapsible navbar feature seems to be malfunctioning. When I try to shrink the screen, t ...

Difficulty enforcing mandatory checkboxes

Seeking assistance on making checkboxes required. I am creating a form using bootstrap 4 and validating it using the JS example from bootstrap documentation. I have added "novalidate" to the form, "required" to inputs, and included the following script: ...

Encountering Typescript problem following the upgrade to create-react-app 4.0.0

After updating create-react-app to version 4.0.0, I faced several issues. The first one being: TypeError: Cannot add property noFallthroughCasesInSwitch, object is not extensible To resolve this, I added "noFallthroughCasesInSwitch": true, to m ...

Executing Javascript code from a specified web address

Let's say I have an image that needs to be shifted vertically, and I achieve it using the following code snippet: document.getElementById('ImgID1').style.verticalAlign = However, the value by which I need to shift the image is provided thr ...

Develop a gallery similar to YouTube or Vimeo

Is there a way to display a collection of SWF movies in a single DIV, with one SWF already set as the default? Something like a photo gallery but for SWFs. I would like to implement this using JQuery. Any suggestions or tips on how to achieve this? ...

Matching up irregular rows in div-made table

I have created a table using div elements that contain images as cell data. When an image is missing, I would like to center the remaining images in the row like this: With all images present: xxxxx xxxxx Missing images (2 in the second row): xxxxx xx ...

Ensure the background image within the ::before selector spans across the entire screen

My CSS code snippet is as follows: div#bodyContainer:before { content: url(/image/colorbar.png); width: 100%; display: block; } Below is the corresponding HTML: <body> <div id="bodyContainer"> ...

Customize the height of a Textfield in React Material UI

Is there a proper way to adjust the height of React Material UI v4 Textfield without affecting the label? I am seeking a straightforward solution that does not cause any issues. export const useTextFieldStyles = makeStyles({ root: { minHeight: ' ...

Having difficulty populating a select input with data from the state

declaring an empty object as the initial state const [categories, setCategories] = useState({}); fetching data from an API using axios and updating the state with the response const res = await axios.get(`${API}/categories`); setCategories(res.data ...

Setting up the Bootstrap grid structure

Struggling to find the right configuration for this Bootstrap 3 setup... https://i.stack.imgur.com/ZsTdI.png I have an input field, but I'm having trouble placing the image in that position. <div class="row"> <div class="col-sm-4 col-m ...

How to turn off a sticky header on Mobile using CSS

Below is the code I am using to create a fixed header on my website. <?php } ?> <header id="header" class="<?php if ( theme_option( THEME_OPTIONS, 'enable_header_fixed' ) == 'true' ) : ?> fixed_header <?php else : ?&g ...

Utilize viewport activation to determine browser width

Is there a way to dynamically add the viewport-meta tag only for devices with screen widths larger than 680px? If the screen is smaller than 680px, then the responsive style file should be enabled instead. I attempted to achieve this by placing the follow ...

The CSS fullscreen background appears to function properly in Dev-tools, but fails to display correctly in an actual browser

I recently created a Meteor App/Website and I am encountering an issue with the fullscreen background image at the top of the page (). While the image displays correctly in Chrome Developer tools and Safari Responsive Design mode, it appears zoomed in on ...