ASP.​NET Core in .NET 6 - CSS isolation for MVC Views and Razor Pages

This is the eighth part of the ASP.NET Core on .NET 6 series. In this post, I'd like to have a quick into the support for SS isolation for MVC Views and Razor Pages.

Blazor components already support CSS isolation. MVC Views and Razor Pages now do the same. Since the official blog post shows it on Razor Pages, I'd like to try it in an MVC application.

Trying CSS isolation for MVC Views

At first, I'm going to create a new MVC application project using the .NET CLI:

dotnet new mvc -n CssIsolation -o CssIsolation
cd CssIsolation
code .

These commands create the project, change the directory into the project folder, and opens VSCode.

After VSCode opens, create an Index.cshtml.css file in the Views/Home folder. In Visual Studio this file will be nested under the Index.cshtml. VSCode doesn't support this kind of nesting yet.

Like in Microsoft's blog post, I just add a small CSS snippet to the new CSS file to change the color of the H1 element:

h1 {
    color: red;
}

This actually doesn't have any effect yet. Unlike Blazor, we need to add a reference to a CSS resource that bundles all the isolated CSS. Open the _Layout.cshtml that is located in the Views/Shared folder and add the following line right after the reference to the site.css:

<link rel="stylesheet" href="CssIsolation.styles.css" />

Ensure the first part of the URL is the name of your application. It is CssIsolation in my case. If you named your application like FooBar, the CSS reference is FooBar.styles.css.

We'll now have a red H1 header:

Isolated CSS: red header

How is this solved?

I had a quick look at the sources to see how the CSS isolation is solved. Every element of the rendered View gets an autogenerated empty attribute that identifies the view:

<div b-zi0vwlqhpg class="text-center">
    <h1 b-zi0vwlqhpg class="display-4">Welcome</h1>
    <p b-zi0vwlqhpg>Learn about <a b-zi0vwlqhpg href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>

Calling the CSS bundle resource in the browser (https://localhost:5001/cssisolation.styles.css) we can see how the CSS is structured:

/* _content/CssIsolation/Views/Home/Index.cshtml.rz.scp.css */
h1[b-zi0vwlqhpg] {
  color: red;
}
/* _content/CssIsolation/Views/Home/Privacy.cshtml.rz.scp.css */
h1[b-tqxfxf7tqz] {
  color: blue;
}

I did the same for the Privacy.cshtml to see how the isolation is done in the CSS resource. This is why you see two different files listed here. The autogenerated attribute is used with every CSS selector that is used here. This creates unique CSS selectors per view.

I assume this works the same with Razor Pages since both MVC and Razor Pages use the same technique.

This is pretty cool and helpful.

What's next?

In the next part In going to look into the support for Infer component generic types from ancestor components in ASP.NET Core.