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
34.59k stars 9.79k forks source link

CSS Isolation in Blazor Components #10170

Closed JustinCouto closed 3 years ago

JustinCouto commented 5 years ago

First of all, we love Blazor!

The only thing keeping us from moving to Blazor as our core front-end technology is the lack of CSS Isolation in Blazor Components. We currently use Angular and it has awesome support for CSS Isolation. This feature has changed the way we develop UI and we could never go back to not having it. We like the unopinionated approach you are taking with Blazor, but this is a feature we believe is essential and worth adding. We don't believe you need to have full web component support, but we do believe having the ability to turn on CSS Isolation at a component level or in an entire project would be an amazing addition that would enable better apps, app management, and a nicer experience for developers. Please add this feature.

@danroth27 @shanselman @SteveSandersonMS

RemiBou commented 5 years ago

IMO, CSS selector already provide enough complexity with selectors so you don't need this kind of feature.

And this adds coupling between the framework, the css extension you choose (less, sass) and the css building tool you choose (webpack). An external project might be a better fit as every Blazor user won't get all the dependencies this feature needs.

JustinCouto commented 5 years ago

@RemiBou I totally disagree. Using CSS without this feature is like writing code without namespaces. Sure, I can write super long and specific class names in code and not use namespaces, but that is an awful way to work. CSS Isolation is something that once you use it, like namespaces, you never want to go back to not using it. I think this is a feature that would be a great addition.

brianmtreese commented 5 years ago

@RemiBou yeah with CSS there's a lot you can do for sure but what we're referring to here is really support of Shadow DOM from the Web Components specification (https://www.w3.org/TR/css-scoping-1/#shadow-dom). It would be awesome to see these standards baked into the framework itself with the ability to toggle it on or off if you didn't want to use it.

Lupusa87 commented 5 years ago

I am sure it will be good what you offer but for now I build dynamic css and load it as part of blazor component so I don't need any isolation because css is constructed for particular component and loaded/unloaded with component.

Here is POC repo which is not updated to latest version I use in my blazor virtual grid.

JustinCouto commented 5 years ago

@Lupusa87 unfortunately, that doesn;t provide CSS Isolation. That means you still get CSS bleed and all the other issues of Global Scoped CSS.

ruicraveiro commented 4 years ago

I use CSS grids to define my pages' layouts. Each page or component will have a different css grid layout, which will also be responsive. CSS isolation is important for this use case to prevent me from having to guarantee each style has an application-wide unique name.

ghost commented 4 years ago

I agree with this request. I convert an Angular app to Blazor and missed this feature. Thank you for considering adding the opt-in capability.

alexandrereyes commented 4 years ago

Here is a workaround https://github.com/alexandrereyes/BlazorScopedCss

vertonghenb commented 4 years ago

why not use the style we already have, for example add the @css block?

In 1 file

Component.razor


<h1>My Component/h1>

@code{ // code goes here }

@css{ // scoped css )



## In multi files
- Component.razor
- Component.razor.cs
- Component.razor.css
buehler commented 4 years ago

@vertonghenb I totally love it! I'd just add the js edition as well:

@script {

}

So you could add the scoped javascript code as well. This should then be packed into the javascript that is loaded from blazor and should be accessible through JSInterop.

zzg890 commented 4 years ago

Without CSS Isolation, the css of different UI libraries will easily conflict each other. I always spent lots of time to fix the css conflict when develop the asp.net mvc applications. Please support it.

buehler commented 4 years ago

Well I'd suggest to use css and js isolation. So when one uses

@css {
  body: red;
}

@js {
  function foobar(){}
}

It should add some hashes or whatnot of the component itself to the classes and functions. With this, no css and js libraries would collide.

And as an addition: it would be nice to actually use the templating language (i.e. razor and the c# compiler) in css and js. For example if we have a design system in place:

// Colors.cs
static class Colors {
  public static readonly string White = "#fff";
}

// MyComponent.razor
<div class="foobar"></div>

@css {
  .foobar {
    background-color: {Colors.White};
  }
}

Maybe this could be compiled and the values of the class properties are compiled into the css of the component? With this, the values don't have to be repeated everytime.

And then there could be LESS / SASS? :-)

neilcamilleri commented 4 years ago

+1 for this feature and all other features that make the design story as good as React/Vue/Angular.

saborrie commented 4 years ago

My preferred JS library for CSS in JS is JSS. https://blazorstyled.io is doing a fairly good job of bringing similar functionality to Blazor:

<Styled @bind-Classname="@example1">
    background-color: hotpink;
</Styled>

<div class="@example1">The background of this div is hotpink</div>

@code {
    private string example1;
}

Even JS doesn't really do CSS isolation without interacting with a library - which is probably a good thing since you can control which plugins and features you want to have. But, it would be nice to have CSS syntax highlighting and intellisense available - perhaps hinted with Attributes - within Styled tags in libraries like Blazor Styled

mythrz commented 4 years ago

why not use the style we already have, for example add the @css block?

In 1 file

Component.razor


<h1>My Component/h1>

@code{
// code goes here
}

@css{
// scoped css
)

If the "css" also allows to "import url('sample01.css')", sure, I upvote. Same for "jss". The worthy functionality is "isolation of assets that affect only that component".

+1 with @JustinCouto . This functionality could/should be optional.

A razor component is meant to be re-usable, and in my tests, @zzg890 issues are similar to mine, I always get conflicts and waste time.

This could allow us to simply call the razor component, from a RCL for example, and be sure that component will render properly, and will not be affected by other styles, of the main site/project. A TRUE re-usable library, that is trustworthy.

RyoukoKonpaku commented 4 years ago

+1 @buehler This could possibly remove the node.js dependency that you'd mostly need if you need a css preprocessors while benefiting from being strongly typed. This is somewhat similar to how React inline styles work, with styles being an object (class in C#'s case) and exposes properties in one place and possibly compose them using existing .net classes that already does this (e.g. System.Drawing.Color etc...) to apply transformations and pre-computation on build like as follows

// App Themes.cs
public static class ThemeColors 
{
    public static Color Primary = Color.Blue;
}

// SomeComponent.razor

@css {
     .transparent-blue { color: Color.FromArgb(0.5, ThemeColors.Primary)  }
}

<button class="transparent-blue"> Transparent primary button </button>
veikkoeeva commented 4 years ago

I think it would be more beneficial to make it straightforward to use custom elements as they have CSS isolation and it's baked into them and otherwise have the case to be just like it is currently, "random fragments". This way Blazor can be used to author web components and be useable with web components authored elsewhere in a platform compatible way.

Though if thinking CSS isolation explicitly, a good integration with Web APIs and in this case up and coming feature such as Constructable Stylesheets would be nice. It looks, though that if one does something like web components already, this is either a prerequisite or follows from it (depending on which features one schedules first).

Something to think with Shadow DOM styles. Related: https://github.com/aspnet/AspNetCore/issues/6218. Maybe worth pointing ount the SPA frameworks are also moving towards custom elements (and web components) and that one should be able to build PWAs without SPAs.

huzaynbolt commented 4 years ago

I'm having a similar issue presently while working on nested components but with style isolation. it seems https://blazorstyled.io is the only option to make this work for now. But for Blazor to win the heart of many, it should have a baked in support for style isolation as it holds in major SPA frameworks.

saborrie commented 4 years ago

I think there should be a way to do CSS isolation in Blazor, but I'm not sure about the idea of baking anything into the core of Blazor

@huzaynbolt - The other main SPA frameworks don't do this. They, like Blazor work with the DOM. Which for styling purposes, includes setting inline-styles and class names on DOM elements. (which razor syntax already does just fine). The actual styles that get applied by the browser to a DOM element based on CSS selectors can come from style tags, css files etc.

The razor syntax can already achieve the same level of inline styling as React for example:

<div style="background: @Model.Bg">...</div>
<div style={{ background: bg }}>...</div>

There's loads of different ways of achieving CSS isolation (shadow DOM, JSS style injection, etc) and I don't think Blazor users should be stuck with one baked in one.

RyoukoKonpaku commented 4 years ago

@saborrie I agree somewhat now thinking it through. It shouldn't be a core Blazor feature since CSS a web construct while Blazor (or razor components) should be agnostic to these concepts since on other areas CSS doesn't apply. E.g. Android / iOS / Desktop for Blazor Native applications.

Maybe a better way is at least having an integration point on Razor components for other build-time tools to participate on the compilation process, being able to read attribute values or something similar without having to do Regex text parsing on the .razor file. This way styling is agnostic to Blazor but others can easily build one that integrates with Blazor's MSBuild pipeline.

JustinCouto commented 4 years ago

After posting this request months ago and following the responses, I feel that some people responding might not use CSS Isolation in large SPA applications and that they may be underestimating the need for this feature. To me, it doesn't matter if this is a core automatic feature or a separate library that you must include to get the feature, but I believe it is still core to building SPA apps using HTML/CSS as the view layer.

Being able to isolate the CSS for an individual component knowing with certainty there will be no CSS bleed or naming collision/accidental overrides is critical. The simplicity of being able to have a style called .item in many components at any level in your application is extremely freeing and useful. You can actually name your styles for what they are not worrying about how those names are impacting the rest of your application. This feature dramatically reduces accidental global cascading issues that developers have been dealing with for years. The global nature of CSS has always been problematic. Is global CSS still needed? Yes. However, like anything global, it should be used sparingly.

Here is the approach that is used in Angular:

Three Modes of Component Encapsulation

Developers who use component-scoped CSS in Angular will default to emulated mode for this encapsulation. In emulated mode, we generate and attach random attributes to each instantiated component, and then create styles that use those generated attributes as selectors.

We also support Native mode, which will use Shadow DOM to create additional contexts and prevent cross-component leakage of styles. This will work in any browsers with support for Shadow DOM v1. Native mode creates a shadow root under each component, which will isolate the component completely, even from styles defined globally (global styles DO pierce components with emulated view encapsulation).

The third and last encapsulation you can choose is None, which means that all of your CSS ends up being globally applied. You can use this if you want to opt-out of Angular’s style encapsulation completely. Source: https://blog.angular.io/the-state-of-css-in-angular-4a52d4bd2700

We have been using Angular for years and our team is simply not going to be willing to move to something that doesn't have a way of doing this. It is one of our favorite features and it helps to raise the quality level of our applications. It's one of those things that you simply don't realize the power of until you have leveraged it in a large application in a major way. It is a once you try it, you could never go back kind of things.

Hopefully, there will be a way to do this in blazer. I think it is critical enough that it should be part of the core framework even if you have to include it separately

datdefboi commented 4 years ago

16574

huzaynbolt commented 4 years ago

zor for thi @saborrie

By referring to other SPA frameworks doing it, I am not deliberating on the underlying functionality used but the syntactic sugar that came out of the box that makes it easy to work with. This is a sample style block in a Vuejs component that makes it easier to work with isolated styles.

N.B: All CSS styles are all isolated to the component hence reducing style conflicts <style lang="scss"> @import "@/assets/styles/common.scss"; body, html { margin: 0; padding: 0; height: 100%; } </style>
Do we have this in Blazor ATM? No, Will it be nice to have it? Yes

saborrie commented 4 years ago

@huzaynbolt

Do we have this in Blazor ATM? No,

actually *yes You can achieve this with the library I pointed out before: https://blazorstyled.io/

I know about the scoped css in Vue Loader (presumably that's what you're referring to) and it does the CSS isolation with data attributes to make the selectors unique:

so:

<style scoped>
.example {
  color: red;
}
</style>

<template>
  <div class="example">hi</div>
</template>

becomes:

<style>
.example[data-v-f3f3eg9] {
  color: red;
}
</style>

<template>
  <div class="example" data-v-f3f3eg9>hi</div>
</template>

Vue-Loader isn't Vue though, it's just one way of doing Vue. React has got a number of different competing popular styling libraries, but the state-of-the-art IMO is JSS (especially when used through material-ui - https://material-ui.com/)

JSS is closer to how BlazorStyled works where the classnames are actually variables like this:

const useStyles = createUseStyles({
  myButton: {
    color: 'green',
    margin: {
      // jss-expand gives more readable syntax
      top: 5, // jss-default-unit makes this 5px
      right: 0,
      bottom: 0,
      left: '1rem'
    },
    '& span': {
      // jss-nested applies this to a child span
      fontWeight: 'bold' // jss-camel-case turns this into 'font-weight'
    }
  },
  myLabel: {
    fontStyle: 'italic'
  }
})

const Button = ({children}) => {
  const classes = useStyles()
  return (
    <button className={classes.myButton}>
      <span className={classes.myLabel}>{children}</span>
    </button>
  )
}

So there's 2 different approaches, but there are more ways, including using Shadow DOM where you get CSS isolation properly provided by the browser.

I'm not advocating for no way of doing CSS isolation in Blazor, I'm just proposing that it shouldn't necessarily be "baked in" so that it is possible to choose which approach to use, especially if there is the possibility of targeting platforms besides the web. (think how React Native stylesheets work totally differently)

leebenson commented 4 years ago

I'd second an official approach. React et al spawned multiple approaches, because it's outside their scope. Libs sprung up out of necessity.

Blazor, OTOH, owns more of the stack. If there's a @code, it's not a stretch to imagine an official @js / @css with one 'right way' of scoping, baked in. This isn't a fringe feature; nearly 100% of Blazor devs will encounter the need to style. Supporting it at the source would make for more complete documentation and a more complete framework.

I think it should be exactly per this comment, with zero abstractions, and no extra thought required. We shouldn't ever need to consider scoping - the toolchain should just do it at compile time.

Choice via multiple libs/approaches isn't always a good thing. It leads to fragmentation and makes sharing components much harder. Every React developer has experienced trying to use a framework that's hard-bound to Sass/Less/Emotion/Styled Components and suffered interop headaches. Having this solved at the framework level, officially, would harmonise the ecosystem and give devs one less thing to think about.

toddpiltingsrud commented 4 years ago

The necessity for scoping in CSS is the same as the necessity for public and private code patterns in other languages.

Think of a component like a custom dropdown. It will likely have CSS rules that are critical to its inner workings (e.g. the display and positioning of the flyout). That code should be PRIVATE to the component AND that code should be encapsulated with the component to make it portable and reusable. We've all experienced the outcome of global-only styling: rule collisions that break your custom dropdown.

We still need global (public) CSS. Global CSS makes it possible to create public API's (e.g. utilities for responsive layout or common animations). Theming should also be public so it can be easily swapped out. That also makes components more reusable because they don't come with hard-coded themes that can't be changed.

It's the same pattern as building a class in languages like Java or C#: its API is public, but code that's critical to its proper function is private. This pattern has been around since long before CSS was even invented. Component-based architecture created the need (and the opportunity) for that same pattern in CSS.

jgomesmv commented 4 years ago

@vertonghenb Thanks for your input! When using the multi files option, how can I refer the .css file on the component view? I have added the file component.razor.css file but none of does styles are applied on the component html elements. The same way we refer the component controler file with the @inherits statement, I guess we must do something similar with the styles file. Any help?

vertonghenb commented 4 years ago

@jgomesmv, my comment was an idea of how we could potentially implement this change, not how it currently works.

rfcdejong commented 4 years ago

Here is a workaround https://github.com/alexandrereyes/BlazorScopedCss

In my opinion is this workaround the only solution currently available. I tried BlazorStyled.io but that isn't as good.

It is also possible to use sass, which will generate the css and minified version where BlazorScopedCss can reference to. (After manually setting the build action to "Embedded resource")

idchlife commented 4 years ago

As well as I like existence of blazorstyled.io, I believe it's not as easy to understand for people coming from Angular/React (with addons to write css right into components). It's kinda... overcomplicating things. What we basically need (IMHO at least):

// Razor/Blazor component
// Header.razor

<div class="starter"></div>

@style {
  .starter {
    background-color: green;
  }
}

@code {
  // Here goes blazor code
}

In end html this will become something like

<div class="abcde__starter"></div>

<style>
  .abcde__starter {
    background-color: green;
  }
</style>

So class styles wont be conflicting with other (global) styles.

We already have Blazor components, and it's a good thing we would like to reuse them. But I suspect writing prefixes for our styles in components by hand is kinda redundant.

I may be wrong.

Comment https://github.com/aspnet/AspNetCore/issues/10170#issuecomment-524506010 is using same approach.

P.S. Is it possible to even write Blazor files compile middleware? So we can attach something and release it as community made package?

buehler commented 4 years ago

@idchlife Very nice description :-)

this would be such a nice addition. this would also improve the usage for production / development. During development the styles of a component can be added to <style> tags and when compiling for production usage, there could be a combined css file which can be included into the resulting application or bundle. (opt in / out ofc)

inspgadget commented 4 years ago

Have written a component for adding css, javascript and other elements dynamically: https://github.com/inspgadget/BlazorSections It's in an early stage , but works for my purposes.

Maybe we will get a feature which helps us to isolate CSS in Feb. 2020 :
https://github.com/aspnet/AspNetCore/issues/17067 (https://github.com/aspnet/AspNetCore/milestone/61)

mythrz commented 4 years ago
// Razor/Blazor component
// Header.razor

<div class="starter"></div>

@style {
  .starter {
    background-color: green;
  }
}

@code {
  // Here goes blazor code
}

Couldn't agree more with idchlife. Simple and efficient. +1

Was hoping this would be already implemented:\ but no. 7 months+ already

SteveSandersonMS commented 4 years ago

Was hoping this would be already implemented:\ but no.

We know a lot of people are interested in this, and we really would like to do something in this area. However it's a very significant work item, and the team is already fully occupied with shipping Blazor WebAssembly in May. The earliest we might attempt something in this area is for the .NET 5.0 release at the end of this year.

troyman1289 commented 4 years ago

Good to hear that the feature will ship with .NET 5.0!

For a temporarily solution I use the SASS nesting feature: For every razor page I want an own style I create a SASS-File named by the name of the existing component in the wwwroot > css folder. All the styles for this component are wrapped inside a css class which has the name of the component.

For the Blazor (weather forecast) example the SCSS file of the FetchData page could look like:

.fetch-data {
    h1 {
        color: green
    }

    .header {
        background: red;
    }
}

The style file has to be defined inside the head tag of the index.html

<link href="css/FetchData.min.css" rel="stylesheet" />

The FetchData.razor must have a parent div where all html code of this page is put inside:

@page "/fetchdata"
@inject HttpClient Http

<div class="fetch-data">
    <h1 class="header">Weather forecast</h1>

    <p>This component demonstrates fetching data from the server.</p>
    ...
</div>

now all styles defined within the fetch-data class affect the html code only in the FetchData.razor page. For me it is the best solution to encapsulate style by now. I don't need to bind styles and I can use simple class names without prefixes for every class

SteveSandersonMS commented 4 years ago

Sorry if I gave the wrong impression, but this statement:

The earliest we might attempt something in this area is for the .NET 5.0 release at the end of this year.

... only means that we will not attempt anything prior to 5.0. The statement does not mean that we will ship this in 5.0.

We have a lot of high priority items for 5.0, not all of which will fit into the allowed time. If anything I would consider it unlikely that CSS isolation as a built-in concept will make it, however we are really interested in what shorter-term alternatives might exist such as 3rd-party implementations.

JustinCouto commented 4 years ago

@SteveSandersonMS I am sure you have a ton of things on the priority list. I totally get that. This feature request may seem small in comparison. However, I feel it is one of those things where people don't really understand the importance of it until you use it. Then once you use it, there is no going back to not using it. So, I suspect this is why there are not more people clamoring for it. For us, we'd love to use Blazer. There are so many great things about it. Although, without this feature, we will be sticking with Angular which does an excellent job with this as it is a must-have for us. Hopefully, you will keep this post updated as this evolves. Thanks for your update.

craigajohnson commented 4 years ago

Is no one else using {pagename}.razor.scss with nested selectors and a unique root to avoid collisions? The .scss file tucks nicely under the .razor file and we get full Intellisense in the .scss file as well as hints in the .razor file itself (it recognizes and suggests css info in class attributes).

The above pattern was based on our usage of Angular css isolation and it works without any issues. You are of course responsible for uniqueifying the root and it doesn't auto-generate some goofy hash so there's that but unless I'm missing a key requirement, you might want to look into that.

aherrick commented 4 years ago

@craigajohnson Like the idea of this approach too. How are you then linking the CSS file into your component?

aherrick commented 4 years ago

@craigajohnson never mind we figured this out. Just used SCSS and VS extension to automatically render SCSS to CSS. Then just link out to it in Host.scss. Not ideal, but it keeps us moving in the right direction. Thanks for the suggestion! https://chrissainty.com/get-some-sass-into-your-blazor-app/

craigajohnson commented 4 years ago

Excellent. That's exactly what we did as well (referenced the same article too). Ideally we could just reference the .scss from the component itself but not too bad as it is.

ikcore commented 4 years ago

I'll throw in here now that Client Side PWA is available and Server Side PWA is simple enough to setup I was expecting that having isolated CSS would be available out the box. I was wanting to port a couple of client PWA's from LitElement web components to Blazor because we were already serving some content via signalR and we could then just completely drop out API layer. It's a little disappointing that we can't take full advantage of the shadow DOM.

I do like the @css { } suggested implimentation and @style { } and actually the @js { } for adding some javascript but a know there are far too many caveats for that at this point in time.

RyoukoKonpaku commented 4 years ago

I think the new C# feature Source Generators and some MSBuild tasks can really help here. With that one could possible generate a C# class from css / scss / less in Blazor components to generate strongly typed and isolated styles. This gives also will possibly give the advantage of having having complete intellisense for the styles.

vertonghenb commented 4 years ago

@RyoukoKonpaku Wow, that looks promising!

defcon8 commented 3 years ago

First of all we love Blazor. BUT.. having no CSS isolation on component level is a showstopper for us and keeps us on React for now. +1 for the (S)CSS block inside razor components. Must have!

@scss{

}

KKacer commented 3 years ago

Waiting for such features a while, I implemented my own structure, with some hardship. Though it works now, I afraid after the release of this feature which could be a new standard for achieving the same result I will be forced to change every code and the infrastructure I built. As a sum up including my earlier mentioned/opened topics.

Here are the related features requested (based on my ideas):

A. I prefer SCSS.

@Scss{
}

B. SCSS imports via libraries (without compilation)

Better than that, the Scss be able to import other Scss files, even from other assemblies. Which they could be libraries dedicated to bring their own styles, base styles.

@Scss{
// Something not definable yet:
@import External-Assembly1; base/base.scss;
// We can define a new format, or a new routing mechanism to target external assemblies.
@import lib1.scss;
// the styles
// other styles
}

Cause of lack of such a feature I wrote MSBuild tools to copy/move/compile my scss files from my base project to every other projects, so in a full solution I may have tens of duplicated scss files in every project, cause the system can't route/find them in other assemblies.


C. Styling separation:

To avoid messing up a component code, it is much better to separate the code and the style in a code-behind way. So, it will be:

Component1.razor
Component1.scss

D. Styling configuration:

If we be able to have a type of .config file specifically for the styling section it could be nice, even in my personal opinion file-specific when needed. For example:

Component1.scss.config

minification: true;
obfuscation: true;
lazyload: true;
addbrowserspecificcodes: true;
renderindividually: false;

E. A new custom format like: MCSS

Not 100% sure, less priority than the previous mentioned parts but having a new file format like MSCSS (Microsoft SCSS), or BSCSS for (Blazor SCSS) may help in some scenarios like the extra routing, more customizability, more flexibility, ... This way you can get the custom parts, the configuration, routing data, ... and finally you give the duty for the last compilation to the SCSS compiler.

If we have such a format like (MCSS) we will be able to define something like this: @import External-Assembly1; base/base.scss; when base/base.scss be in another assembly named External-Assembly1.


I believe number 1,2,3 are a must, 4 and 5 can be great options to have.

JvanderStad commented 3 years ago

+1 on the scss.

Maybe it is possible to have a callback mechanism to create support for multiple (future) technologies

@isolation scss {
   .class { .otherclass {...} }
}

@isolation typescript {
.....
}

@isolation theNextBestThing {
....
}
KKacer commented 3 years ago

+1 on the scss.

Maybe it is possible to have a callback mechanism to create support for multiple (future) technologies

@isolation scss {
   .class { .otherclass {...} }
}

@isolation typescript {
.....
}

@isolation theNextBestThing {
....
}

CSS is a standard thing. And Scss is a fine wrapper and a pre-processor over it. There will be no big-thing on top of it. (just we may have CSS 4,5 some years later) TypeScript, JS are going to be replaced gradually by Blazor IMHO at least for C# developers.

So, in my opinion we should never put anything else in the same level as css/scss, we should be able to target them as fast as possible and manipulate them with the highest power and flexibility. About any extra isolation features etc I think yes, it could be an extra feature which can possibly be added in the next versions of blazor. But in my opinion still all those should be treated differently from CSS/SCSS. And we shouldn't think of a generic solution on this case.

patoncrispy commented 3 years ago

I like the idea of everything being in the one file so the aforementioned @scss {}-style markup gets my vote. I'm not a fan of how many files Angular uses for each component, but love how concise React and Vue can be. If you can't fit your code, markup and styles in a single file, your component is probably getting too big and needs to be re-thought.

KKacer commented 3 years ago

I like the idea of everything being in the one file so the aforementioned @scss {}-style markup gets my vote. I'm not a fan of how many files Angular uses for each component, but love how concise React and Vue can be. If you can't fit your code, markup and styles in a single file, your component is probably getting too big and needs to be re-thought.

In .razor files, you can place your code in @code section or you can use code-behind to make things look tidier. It is optional for each of us as developers, I hope the CSS/SCSS declaration also be as flexible and customizable. So someone like you who likes to have all the component stuff in a file be able to do that, and who like me which prefers to have the below structure also be happy about it:

Component1.razor
Component1.cs         // I prefer the simpler form  Component1.cs to Component1.razor.cs
Component1.scss
Component1.config     // not a priority of myself ATM, but can be helpful soon, for component specific configuration.
Component1.js /ts

(All these files could be optional, you can stick with a file for a better portability or separate each in a dedicated file for a more organized look)

And have them all nested under the parenthood of Component1.razor, even I prefer to see just a known type of Component1 (without extension) something like a solution folder wrapping all the contents with a dedicated icon for the Blazor components (yet not defined), which when you click or expand it, you be able to see the earlier mentioned structure.