How to use subsequent-sibling selector in React CSS modules

313 Views Asked by At

How would I write and call this CSS in React CSS Modules?

.is-invalid ~ .validationError {
    display: inline !important;
}

Calling styles.validationError does not work.

3

There are 3 best solutions below

4
On
return (
  <>
    <div className={styles['is-invalid']}>
    
    </div>
    {/* some Node or nothing, is-invalid and validationError are brothers. */}
    <div  className={styles.validationError}>123</div>
  </>
)
0
On

You are referring to babel-plugin-react-css-modules in the question tags, but don't provide any further context how you use it. This makes it hard to understand your exact problem, but I'll give it a shot anyway.

I assume you are trying to import a CSS file as a module like this:

import styles from "./styles.module.css"

const MyComponent = () => {
  return <div>
    <input className={styles['is-invalid']} />
    <div className={styles.validationError}>...</div>
  </div>
}

Your CSS will generate two locally scoped classes when imported as a CSS module. The code above works as expected when you use regular CSS modules, for example via a Webpack loader.

However, the Babel plugin that you use actually expects a different way of adding styles. Here is what you should do according to the documentation:

// no need for named import here
import "./styles.module.css"

const MyComponent = () => {
  // note the different attribute: `styleName`
  //   - `styleName` uses a literal string
  //   - before, `className` used a variable from the imported `styles` module
  return <div styleName="validationError">...</div>
}

babel-plugin-react-css-modules will load the CSS at compile time and replace the styleName attributes with the scoped classNames inline. The docs linked above explain this in further detail.

0
On

I was able to fix this by using global.

:global(.is-invalid)~.validationError {
    display: inline !important;
} 

I can now call ${syles.validationError} and it works.