Css-loader: Trouble with scss and nested selectors

Created on 27 Sep 2016  路  10Comments  路  Source: webpack-contrib/css-loader

So, I was trying to achieve something like

.pagination{
    display:flex;
    justify-content: center;
    ...
    li{
        border: 1px solid #ccc;
        ...
    }
    a{
        display: block;
        padding: 10px 15px;
        ...
    }
    .active {
        a{
            background: #eee;
            ...
        }
    }

}

Im using React btw, and also using a library based on material design called react-toolbox. React toolbox is using css-modules to manage CSS.

I basically create my scss file, then import them into my component and assign them like {style.pagination} for example.

Now my problem is that this approach works well including the nested selectors 'without' any classes. In the above example, '.active a' doesnt work at all and i have no idea how to solve this. It does work only if i resort to using the 'global:' flag.

In this particular case, it is not that much of a problem using the :global flag, but i had other cases where i had to target elements to which i had no control over classnames, and even using :global wouldnt help.

Most helpful comment

ramiel,

I was struggling with this too. I think I was able to get the result, where the nested class doesn't change to a random class name by doing the following:

.top {
  :global .inner {
    color: blue;
  }
}

which results in something like:

.top_random {
  .inner {
    color: blue;
  }
}

At least, that was my experience.

Good luck.

All 10 comments

I have the same problem with nested classes.

The only way is to make nested selector global:

.pagination{
    display:flex;
    justify-content: center;
    ...
    li{
        border: 1px solid #ccc;
        ...
    }
    a{
        display: block;
        padding: 10px 15px;
        ...
    }
    :global .active {
        a{
            background: #eee;
            ...
        }
    }

}

oh i had no idea we could use :global as a nested option

Closing due to inactivity. Please test with latest version and feel free to reopen if still regressions. Also some sass/scss feature can be incompatibility with css modules. Better place for this problem is css modules repo (we just use postcss plugin). Thanks!

Not sure if this still actual for someone.
Whatever - I think, you can just use benefits of complex css selectors.
it's a bit ugly, but works for my scss modules.
From your example:

.pagination {
    display:flex;
    justify-content: center;
   ....
    [class*="active"] {
        a {
            background: #eee;
            ...
        }
    }

}

Why css-loader is changing the name of sub-classes? I have:

:local(.top) {
  .inner {

  }
}

I expect it to be transformed into

.top__random{
    .inner {
    }
}

so that later the sass plugin can do its job. Instead I get

.top__random{
    .inner__randomtoo {
    }
}

Is this the expected behavior? It was working with version 0.28.x but it's broken in 1.x

@ramiel use

:local(.top) {
  :local(.inner) {

  }
}

Because sass and css modules is difference technologies.

But, if do like that I should receive the

.top__random{
    .inner__randomtoo {
    }
}

right? It's what I want to avoid

ramiel,

I was struggling with this too. I think I was able to get the result, where the nested class doesn't change to a random class name by doing the following:

.top {
  :global .inner {
    color: blue;
  }
}

which results in something like:

.top_random {
  .inner {
    color: blue;
  }
}

At least, that was my experience.

Good luck.

@muellerkyle this is correct, and was my experience as well.

I think that the :global keyword is misleading, as it suggests that the enclosed selector will be moved to the global scope, but that's not the case. All it does is prevent it from receiving the random prefix string, but it is still nested within its containing selector.

Was this page helpful?
0 / 5 - 0 ratings