Nested class selectors not working in next.js sass
Asked Answered
T

3

12

I'm using scss modules in next.js and want to use nested class selectors like this:

.div {
  .x {
    color: red;
  }
}

But it seems that this won't work with the following component:

import React from 'react'
import styles from './my-component.module.scss'

export default class MyComponent extends React.Component {
  public render() {
    return (
      <div className={styles.div}>
        <span className='x'>ololo</span>
      </div>
    )
  }
}

For some reason, the styles do not apply to the <span> tag. Whats wrong with this code?

Teets answered 5/12, 2020 at 4:50 Comment(0)
T
8

You can use :global to make nested class work:

.div {
  :global .x {
    color: red;
  }
}

then you can use like this:

import React from 'react'
import styles from './my-component.module.scss'

export default class MyComponent extends React.Component {
  public render() {
    return (
      <div className={styles.div}>
        <span className='x'>ololo</span>
      </div>
    )
  }
}
Thickskinned answered 10/11, 2021 at 15:43 Comment(2)
Is that a Nextjs thing? I can't find it in the docs.Smukler
it is a css-module thing supported by next. Explained here in the nextjs documentationHardtack
T
3

It was a bit unclear for me, but it seems that I need to extract both classes from the module. Like this:

import React from 'react'
import styles from './my-component.module.scss'

export default class MyComponent extends React.Component {
  public render() {
    return (
      <div className={styles.div}>
        <span className={styles.x}>ololo</span>
      </div>
    )
  }
}

The code above works just fine.

Teets answered 5/12, 2020 at 5:56 Comment(2)
so what's the point to use scss ? If we need to use styles.div and styles.x, it's like a regular css module.Canonize
Yes that is very lame... not really nesting at allUranalysis
F
0

You can use global differently to the various answers I have seen on this problem and it works great.

.headerBlock :global {
    //nothing goes here
    .wrapper {
        //block styling goes here
        &.hasBackground {
        }
        .headerLeft {
        }
    }
}

.

<header className={styles.headerBlock}>
  <div className="wrapper hasBackground">
    <div className="headerLeft">

You only have to add :global after the top class, which is the only one you have to reference using {styles.class}. Child classes then work just by specifying the name as a string.

The only downside is this breaks using & in your scss on direct children of the top parent. Easily solved by adding a wrapper and treating that as the root for your styles.

Faunie answered 15/9, 2023 at 3:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.