blazorblazor-server-sideasp.net-core-css-isolation

Obtain CssScope value of a Blazor Component


I have a Blazor server application that contains a component which generates a list of html paragraphs.

<div class="text">
  @FormatText(Obj.Synposis)
</div>

using this simple function:

@functions 
{
  private MarkupString FormatText(string text)
  {
    var Result = string.Concat(text.Split('¶', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries).Select(e => $@"<p>{e}</p>"));

    return new MarkupString(Result);
  }
}

the corresponding component's css style contains this:

  div.text > p {
    margin-bottom: 50rem;
    background-color: red;
  }

This issue is that the generate html string lacks the component's css scope value and therefore any style applied is ignored.

To make sure we're on the same page, the rendered css will contain this:

  div.text > p[b-taj2ej35sx] {
    margin-bottom: 50rem;
    background-color: red;
  }

... and I would have to apply that css scope as <p b-taj2ej35sx="">... in FormatText() for the style to get applied. I need to obtain the string value "b-taj2ej35sx" somehow.

The question is:

  1. can I (and how) find the component's css scope value? can I re-calculate the value myself (the code following b-)? then it would be just a matter of adding that to the <p> string
  2. can I tell blazor to not apply css scoping for a single css element in the style sheet?
  3. can I trick blazor somehow to fail to scope a css element? it already looks like the compiler failed to scope both div.text and p elements in that style rule

Solution

  • You shouldn't need to do anything with the scope unique Id.

    I'm assuming all your code is in the same component.

    Here's my code that demonstrates what you've set out and works. I've simplified it a little.

    The key is to use RenderFragments. The Razor compiler treats MarkupString as just that, and doesn't apply any CSS component magic to it.

    Index.razor with the markup that should be generated.

    @page "/"
    
    <PageTitle>Index</PageTitle>
    
    <h1>Hello, world!</h1>
    
    
    <div class="text">
        @GetFormattedText
    </div>
    
    @code {
        private string countries = "France, UK, Spain, Portugal";
    
        private RenderFragment GetFormattedText => (__builder) =>
        {
            var items = countries.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
            foreach(var item in items)
            {
             <p>@item</p>   
            }
        };
    }
    

    Index.razor.css:

    div.text > p {
        margin-bottom: 5rem;
        background-color: red;
    }
    

    And the result:

    enter image description here