Vue-loader: Option to use hashed classnames with scoped css

Created on 2 Apr 2019  ·  4Comments  ·  Source: vuejs/vue-loader

What problem does this feature solve?

Vue achieves scoped css by combining classnames with randomly generated attributes. This increases the specificity of the selectors, making it hard to combine with other CSS libraries.

What does the proposed API look like?

This is a feature request for scoped css through classnames with a hash, without using attribute selectors.

.my-class-j04ckg578h

There should be a way to configure this option on a project level

Initial discussion: https://github.com/vuejs/vue/issues/9801

All 4 comments

Are you trying to override existing scoped styles in a component? That seems to be the direct opposite of what scoped styles are supposed to do (encapsulation). Can you provide more details on the use case? What libraries are you talking about?

As said in https://github.com/vuejs/vue/issues/9801#issuecomment-478792920:

Vue Loader’s scoped styles implementation works not only for class selectors. Scoped styles allow any selector so generating hashed class names is not enough.

@Justineo That is a good point, no feature parity. At the same time I can't see a good use for that feature. Can you think of an example where that would actually be a good practice?

@yyx990803 At the moment, the main result of scoped styles is preventing styles defined in a component from leaking outside. It doesn't prevent outside styles from targeting classes defined in the component, or even overriding the styles defined in the component, if you use a selector with specificity >= 2.

Hashed classes, on the other hand, would actually achieve what you are suggesting more reliably. It wouldn't be possible to accidentally target classes defined in the component, with styles defined outside.

Atomic css libraries are a good example. tailwind.css was mentioned in the previous discussion. I would like to have a button component with some default styles, including margin: 10px. I would also like to add some extra space between 2 of the buttons so I would conveniently use tailwind because there is nothing special about that button to warrant a new classname, just some extra space. The following doesn't work if scoped is enabled:

<template>
    <div>
        <button class="button"></button>
        <button class="button"></button>
        <button class="button mt-20"></button>
        <button class="button"></button>
    </div>
</template>

<style scoped>
.button {
    margin: 10px;
    background: yellow;
    color: blue;
    border-radius: 3px;
}
</style>

One way to make this work without disabling the scoped styles is to enable the !important option in tailwind.css. However, modifier selectors like :hover or .button.is-active would stop working, unless we also write !important after every property.

I would use CSS modules, but the extra markup required is enough to dissuade me. In alternative we could add some syntax sugar to CSS modules to make more similar to scoped css usage. Maybe something along this lines? https://github.com/gajus/babel-plugin-react-css-modules#example-transpilations

在不同的项目中.vue文件使用了相同的名字,经过scoped转化后data-v-* 是相同的;当我把不同的项目产出的css文件import中同一个第三方项目中时,css文件会对相同命名的两个vue组件产生影响;所以,希望能自定义data-v字段或者能通过入参的形式额外添加一个唯一标识符@yyx990803

Was this page helpful?
0 / 5 - 0 ratings

Related issues

lijialiang picture lijialiang  ·  3Comments

jorgy343 picture jorgy343  ·  3Comments

Makio64 picture Makio64  ·  4Comments

C0deZLee picture C0deZLee  ·  3Comments

ryanelian picture ryanelian  ·  3Comments