dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.44k stars 10.02k forks source link

A reversed ::deep for scoped css files #40370

Open JelleHissink opened 2 years ago

JelleHissink commented 2 years ago

Is there an existing issue for this?

Is your feature request related to a problem? Please describe the problem.

I have components where I would like different css depending on the parent element.

Describe the solution you'd like

Currently we have ::deep that from that selector on ignores the tag[xxx] decorations. It would be very helpful if there would be an inverse. E.g:

::global .dialog ::local div

That would translate to something like

.dialog div[tag]

Additional context

No response

javiercn commented 2 years ago

@JelleHissink thanks for contacting us.

It's not clear to us what you are suggesting nor why you can't achieve this directly with regular CSS.

ghost commented 2 years ago

Hi @JelleHissink. We have added the "Needs: Author Feedback" label to this issue, which indicates that we have an open question for you before we can take further action. This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time.

JelleHissink commented 2 years ago

It would be only possible currently with the css scoped feature to do something like:

::deep .global div

Effectively discarding the scope, or I have to add my own "scope" tag to the elements.

javiercn commented 2 years ago

@JelleHissink I'm still not sure how this would work.

Could you write some sample HTML that further clarifies the scenario?

ghost commented 2 years ago

Hi @JelleHissink. We have added the "Needs: Author Feedback" label to this issue, which indicates that we have an open question for you before we can take further action. This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time.

ghost commented 2 years ago

This issue has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for 4 days. It will be closed if no further activity occurs within 3 days of this comment. If it is closed, feel free to comment when you are able to provide the additional information and we will re-investigate.

See our Issue Management Policies for more information.

JelleHissink commented 2 years ago

I really want this, but have been driving to the border between Slowakia and Ukraine to pick up refugees, I'll try to make an example later.

javiercn commented 2 years ago

@JelleHissink No worries.

I'll put it in the backlog and we can look at it when the timing is better.

ghost commented 2 years ago

We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.

lonix1 commented 2 years ago

Unless I'm misunderstanding the OP's use case, I've also encountered this.

We have Foo.cshtml and Foo.cshtml.css. Everything is scoped to the component. You cannot target the parent markup, because the generated css applies tags to every selector e.g. [dsfsd34].

But sometimes you want to target the parent markup. For example - like OP explained - based on something in the parent, you style the component differently. Since that cannot be done, you have to put that styling in a different stylesheet, e.g. Site.css - but you lose encapsulation.

It would be nice to be able to "break out" of the child scope in the Foo.cshtml.css. For example, using ::global.

EXAMPLE

If on page foo, set component's background to green If on page bar, set component's background to blue

Foo.cshtml.css:

::global body.isPageFoo .component { background-color: green; }
::global body.isPageBar .component { background-color: blue; }
/* note no ::deep is necessary, because ::global breaks out of scoping completely */

MyProject/obj/Debug/net6.0/scopedcss/Foo.cshtml.rz.scp.css:

body.isPageFoo .component { background-color: green; }
body.isPageBar .component { background-color: blue; }
JelleHissink commented 2 years ago

I think you understood correctly... I'm still a bit playing catch up with work. My son also got a complicated appendix removal, he has been in hospital for 6 weeks... so sorry I could not clarify more.

But @lonix1 understood my intention correctly I think. I specified the ::local because from the next tag then the [] component tag selector could be applied again. So the ::local would specify that the component tag selector should be applied not on the first element, but starting somewhere in the selector.

suchoss commented 1 year ago

I would welcome this ::global pseudo element as well, because in my case for one specific page I want to setup different font size for the whole body.

So my file's (blazor page) css EventEditor.razor.css could look like following:

::global @media screen {
    body {
        font-size: 12px !important;
    }
}

and the body tag (which is defined somewhere in _layout) would be styled properly.

JelleHissink commented 1 year ago

I'd really love to be able to include some styles and more control over ::deep. I just also saw this issue, it seems related #https://github.com/dotnet/aspnetcore/issues/44634

jstrandelid commented 1 year ago

I also would like support for a ::global to escape the scope.

In my case I have a component that includes an external component (a dropdown menu). The dropdown menu component injects a menu part into a html element outside of my component, so the menu part is not a descendent to my component. I am able to set a CSS class on the drop down menu component and therefore being able to target the menu in a non scoped css file. However, I would be much better to have CSS for the component in the same CSS file instead of spread out in multiple files.

If it was possible to use ::global to declare that the css selector that starts with ::global should not be scoped it is possible to mix scoped selectors with selectors that escapes the scope and have all css for the component in the same css file.

tankbob commented 1 year ago

It would also be useful to be able to escape the scope partially, specifying to only apply the scoped part of the rule if there is a parent element matching.

e.g.

::global body[data-theme="material"] ::scoped h1 {
  ....
}

So if the body has data-theme="material" then apply the style to any h1 in my component.

Should translate to

body[data-theme="material"] h1[scope-id] {
...
}

It would also be nice to do

body[data-theme="material"] ::deep h1 {
...
}
tankbob commented 1 year ago

Actually I was just trying the other way

I have a component that is two nested divs and I created a isolated css with the rule div>div and it converts it to

div>div[b-....] {}

Which was actually what I wanted in previous comment, however I now don't know how to make an isolated css to output

div[b-....]>div[b....] {}
ghost commented 11 months ago

We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.