-
Notifications
You must be signed in to change notification settings - Fork 546
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Scoped Style Changes #119
Scoped Style Changes #119
Conversation
|
||
## One-Off Global Rules | ||
|
||
Currently to add a global CSS rule we need to use a separate unscoped `<style>` block. We are introducing a new `::v-global()` pseudo class for one-off global rules. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
does this bring any improvement in performance or anything? I find the separate style
easier to read and more intuitive because it's just like a regular style
tag.
Unless scoped
becomes the default but that would be even harder to migrate
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Technically, yes. For webpack, an extra <style>
block becomes a separate module with a whole pipeline (i.e. all the loaders configured for CSS are invoked for this block again). Putting them in the same block improves bundler build performance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That makes sense, I think it's worth indicating that as a benefit even if it seems to be a marginal gain
Hi @yyx990803 I have a question about how to use How do I write a nesting selector with deep selector? In Vue.js 2.x, I could write: .foo ::v-deep .bar {
& .baz {
/* ... */
}
} .foo ::v-deep .bar {
/* ... */
&--baz {
/* ... */
}
} |
@ota-meshi to convert to the new syntax, just put everything after .foo {
& ::v-deep(.bar) {
/* ... */
}
} Note that |
I'm sorry. I made a mistake in the example code. Then I rewrote the question. The code I want to ask is: .foo ::v-deep .bar {
& .baz {
/ * ... * /
}
} |
I'm afraid the function syntax won't play well with nesting as the old "combinator" did. As I understand, the whole selector inside |
Oops. Sorry for closing this by mistake. |
Does that mean nested selectors after I like the new syntax than the old syntax, which disguised the pseudo-class as a combinator. |
The previous syntax looks a bit more flexible. Correct me if I'm wrong. Let's say how the new syntax can be matched with <style scoped>
::v-deep :is(header, footer, p) {
/* ... */
}
</style> Or nested selectors with some preprocessors <style scoped lang="scss">
::v-deep {
header, footer, p {
/* ... */
}
}
</style> |
Your first example can be written as: ::v-deep(:is(header, footer, p)) {
/* ... */
} While for nesting, the new syntax is indeed a bit less convenient. Maybe we can keep the special case of |
Current syntax is ideal for scenarios when you want to mark a single rule (selector + styles) as deep or global. However, how about scenarios when you need to mark more than one group of rules? I do not know how this scenario is common in the community, but if it is in demand then why not implement the following syntax: <template> ... </template>
<style>
/* Global styles (as in Vue 2)*/
</style>
<style scoped>
/* Scoped styles */
</style>
<style deep>
/* Scoped deep styles */
</style>
<style slotted>
/* Scoped slotted styles */
</style> As far as I understand it corresponds to the syntax of Vue 2 |
|
||
We later switched to `/deep/`, which was once an actual proposed addition to CSS (and even natively shipped in Chrome), but later dropped. This caused confusion for some users, since they worry that using `/deep/` in Vue SFCs would make their code not supported in browsers that have dropped the feature. However, just like `>>>`, `/deep/` is only used as a compile-time hint by Vue's SFC compiler to rewrite the selector, and is removed in the final CSS. | ||
|
||
To avoid the confusion of the dropped `/deep/` combinator, we introduced yet another custom combinator, `::v-deep`, this time being more explicit that this is a Vue-specific extension, and using the pseudo-class syntax so that any pre-processor should be able to parse it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To avoid the confusion of the dropped `/deep/` combinator, we introduced yet another custom combinator, `::v-deep`, this time being more explicit that this is a Vue-specific extension, and using the pseudo-class syntax so that any pre-processor should be able to parse it. | |
To avoid the confusion of the dropped `/deep/` combinator, we introduced yet another custom combinator, `::v-deep`, this time being more explicit that this is a Vue-specific extension, and using the pseudo-element syntax so that any pre-processor should be able to parse it. |
|
||
The previous versions of the deep combinator are still supported for compatibility reasons in the current [Vue 2 SFC compiler](https://github.com/vuejs/component-compiler-utils), which again, can be confusing to users. In v3, we are deprecating the support for `>>>` and `/deep/`. | ||
|
||
As we were working on the new SFC compiler for v3, we noticed that CSS pseudo classes are in fact semantically NOT [combinators](https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Selectors/Combinators). It is more consistent with idiomatic CSS for pseudo classes to accept arguments instead, so we are also making `::v-deep()` work that way. The current usage of `::v-deep` as a combinator is still supported, however it is considered deprecated and will raise a warning. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As we were working on the new SFC compiler for v3, we noticed that CSS pseudo classes are in fact semantically NOT [combinators](https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Selectors/Combinators). It is more consistent with idiomatic CSS for pseudo classes to accept arguments instead, so we are also making `::v-deep()` work that way. The current usage of `::v-deep` as a combinator is still supported, however it is considered deprecated and will raise a warning. | |
As we were working on the new SFC compiler for v3, we noticed that CSS pseudo elements are in fact semantically NOT [combinators](https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Selectors/Combinators). It is more consistent with idiomatic CSS for pseudo elements to accept arguments instead, so we are also making `::v-deep()` work that way. The current usage of `::v-deep` as a combinator is still supported, however it is considered deprecated and will raise a warning. |
::v-deep .bar {} | ||
``` | ||
|
||
Instead, use it as a pseudo class that accepts another selector as argument: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead, use it as a pseudo class that accepts another selector as argument: | |
Instead, use it as a pseudo element that accepts another selector as argument: |
|
||
Notice the `-s` postfix which makes it target slot content only. | ||
|
||
- New pseudo class `::v-global()` can be used to apply global rules inside a `<style scoped>` block: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- New pseudo class `::v-global()` can be used to apply global rules inside a `<style scoped>` block: | |
- New pseudo element `::v-global()` can be used to apply global rules inside a `<style scoped>` block: |
@Justineo can you make it into a single PR to the |
@yyx990803 Sure |
Evan mentioned having one style block is better for webpack performance as each block would be a separate module. It's also very nice to colocate rules that are conceptually related to each other within the same style block (similar to the readability benefits of the composition API) and why we don't have multiple template tags to cover different scenarios.. we have v-if instead |
This RFC is now in final comments stage. An RFC in final comments stage means that: The core team has reviewed the feedback and reached consensus about the general direction of the RFC and believe that this RFC is a worthwhile addition to the framework. |
I think the ability to nest is very important and should not be removed. While everything that can be done with the old In some cases you have third party components that you have no control over, but you want to customise them. So you have to overwrite many styles in the scoped child component. Until now these styles could all be written in one block. With the new system this does not work anymore. .slider::v-deep
.vue-slider-rail
background-color: transparent
.vue-slider-dot
cursor: pointer
.vue-slider-process
background-color: transparent
border-radius: 0
&::after
content: ''
display: block
position: absolute
top: 0
left: 0
right: 0
bottom: 0
.vue-slider-process,
.vue-slider-dot,
.vue-slider-mark
z-index: auto
.vue-slider-mark-step
display: none
.vue-slider-dot-tooltip
pointer-events: none
.vue-slider-dot-tooltip-top
top: 0 Instead you have to convert it to this which is not nice: .slider::v-deep(.vue-slider-rail)
background-color: transparent
.slider::v-deep(.vue-slider-dot)
cursor: pointer
.slider::v-deep(.vue-slider-process)
background-color: transparent
border-radius: 0
.slider::v-deep(.vue-slider-process::after)
content: ''
display: block
position: absolute
top: 0
left: 0
right: 0
bottom: 0
.slider::v-deep(.vue-slider-process),
.slider::v-deep(.vue-slider-dot),
.slider::v-deep(.vue-slider-mark)
z-index: auto
.slider::v-deep(.vue-slider-mark-step)
display: none
.slider::v-deep(.vue-slider-dot-tooltip)
pointer-events: none
.slider::v-deep(.vue-slider-dot-tooltip-top)
top: 0 I don't think v-deep's nesting functionality should be deprecated or removed. |
Hii, I think the new selectors have some issues when used with example:: with ::v-deep ::v-deep .b-user-card {
width: 100%;
padding-bottom: 16px;
&__profile {
p {
margin: 0 0 4px;
}
}
&__info {
p {
margin: 0 0 8px;
}
}
.q-card__section--vert {
padding-bottom: 0 !important;
}
} This old syntax worked perfectly with BEM. But with the new .b-user-card {
width: 100%;
padding-bottom: 16px;
&::v-deep(__profile) {
p {
margin: 0 0 4px;
}
}
&::v-deep(__info) {
p {
margin: 0 0 8px;
}
}
::v-deep(.q-card__section--vert) {
padding-bottom: 0 !important;
}
} it worked correctly for the last line |
I've found these below don't work... <style deep>
/* Scoped deep styles */
</style>
<style slotted>
/* Scoped slotted styles */
</style> |
Provide more consistent custom CSS extensions in Single File Component scoped styles.
Rendered