How can I change css directly(without variable) in Blazor?

Viewed 20474

I am using the server-side of Blazor.

I want to change the CSS of the body.

In Jquery I can write the code like this easily:

$("body").css("overflow-y","hidden");

However, with this tutorial(Blazor Change Validation default css class names) said, it seems I can only change the CSS by changing the class name.

It is so complex while crossing the component, especially the body is at the top of all the components.

I wonder whether there is a way can changes CSS directly in Blazor. Thank you.

5 Answers

There are several ways of getting out of the "blazor way" of doing things and accomplishing css modification of an element.

Simplest: Just like you can use the class attribute, use the style attribute

<element style=@myStyle></element>

@code {
  string myStyle;

  void MyMethod() {
     myStyle="overflow-y: hidden;"
  }
}

Advanced: Use JS interop

a. In the main view (index.html or Pages/_Host.cshtml depending on project type), create a js endpoint for your component

<script>
   window.applyStyleForElement = function(styleOp) {
       document.getElementById(styleOp.id).style[styleOp.attrib] = styleOp.value;
   }
</script>

b. In razor file:

@Inject IJRRuntime JSRuntime
<element id=@myId></element>

@code {
  string myId = Guid.NewGuid().ToString("n");

  async Task MyMethod() {
     await JSRuntime.InvokeAsync("applyStyleForElement", 
      new { id = myId,  attrib = "overflowY", value = "hidden" });
  }
}

Finally, applying to your special case with body element ("advanced" method above).

a. In the main view (index.html or Pages/_Host.cshtml depending on project type), create a js endpoint

<script>
   window.applyStyleForBody = function(style) {
       document.body.style[style.attrib] = style.value;
   }
</script>

b. In razor file:

@Inject IJRRuntime JSRuntime
(...)

@code {

  async Task MyMethod() {
     await JSRuntime.InvokeAsync("applyStyleForBody", 
       new { attrib = "overflowY", value = "hidden" });
  }
}

Well, Blazor does not support direct css modification yet, since Web Assembly doesn't. Anyway heads up, it is on the road-map for Web Assembly/Blazor.

Therefor your best bet is, changing the class name with variables. At least for now.

Well, actually there is a way to do that and it works really good (it might suffer a little delay though). I know this answer is a little bit late but it might help other people who face the same challenge.

  1. We need to create some JS code that includes the wanted files:

    function includeLeftStyle() {
        appendStyle("left.css");
    }
    
    function includeRightStyle() {
        appendStyle("right.css");
    }
    
    function appendStyle(path) {
        var element = document.createElement("link");
        element.setAttribute("rel", "stylesheet");
        element.setAttribute("type", "text/css");
       element.setAttribute("href", path);
       document.getElementsByTagName("head")[0].appendChild(element);
    }
    
  2. The wished CSS can be called according to the language (any other coditions) in the MainLayout:

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
         if (firstRender)
         {
             if (// is left)
             {
                 await JSRuntime.InvokeAsync<object>("includeLeftStyle");
             }
             else
             {
                 await JSRuntime.InvokeAsync<object>("includeRightStyle");
             }
         }
     }
    

Happy coding! :)

I'M NOT SURE IT'S THE RECOMMENDED WAY BUT it works!

For one of my project, I include a in the page html itself, using params :

<style>

    html 
    {
        background-color:@_ColorCss;
    }

</style>
//html stuff here
@code
{
    public string Color{ get; set; } = "white";
    string _ColorCss => $"{Color}";     //use this in case of formatting (ex : add 'px' or that kind of things)

    //code stuff here  
}

not the very sexiest way but it works

have fun !

Beginnig from the @Tewr answer, we can also change the whole class:

a) In the main view (index.html or Pages/_Host.cshtml depending on project type), create a js endpoint

<script> 
    window.applyStyleForElement = function (styleOp) { 
        if (styleOp != null) { 
            document.getElementById(styleOp.id).className = styleOp.value; 
        } 
} 
</script>

b) Then in the razor file

async Task MyMethod(string sortColumn) 
{
    await JsRuntime.InvokeVoidAsync("applyStyleForElement", 
         new { id = sortColumn, value = "newClassName" });
} 
Related