{"id":28471090,"url":"https://github.com/abdisamadmoh/blazorstylesheet","last_synced_at":"2026-05-04T23:34:38.421Z","repository":{"id":228463278,"uuid":"768256426","full_name":"AbdisamadMoh/BlazorStylesheet","owner":"AbdisamadMoh","description":"BlazorStyleSheet allows blazor (Blazor server, webassembly and MAUI blazor) developers to write their CSS styles directly in C# without the need for external stylesheets.","archived":false,"fork":false,"pushed_at":"2024-03-18T23:47:27.000Z","size":1432,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-07T10:07:47.508Z","etag":null,"topics":["blazor","csharp","css","cstylesheet","maui","net","server","web","webass"],"latest_commit_sha":null,"homepage":"https://saabytes.com","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AbdisamadMoh.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2024-03-06T18:48:42.000Z","updated_at":"2024-07-22T20:11:44.000Z","dependencies_parsed_at":"2024-03-18T23:31:46.712Z","dependency_job_id":null,"html_url":"https://github.com/AbdisamadMoh/BlazorStylesheet","commit_stats":null,"previous_names":["abdisamadmoh/blazorstylesheet"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/AbdisamadMoh/BlazorStylesheet","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AbdisamadMoh%2FBlazorStylesheet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AbdisamadMoh%2FBlazorStylesheet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AbdisamadMoh%2FBlazorStylesheet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AbdisamadMoh%2FBlazorStylesheet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AbdisamadMoh","download_url":"https://codeload.github.com/AbdisamadMoh/BlazorStylesheet/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AbdisamadMoh%2FBlazorStylesheet/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261250277,"owners_count":23130542,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["blazor","csharp","css","cstylesheet","maui","net","server","web","webass"],"created_at":"2025-06-07T10:07:48.242Z","updated_at":"2026-05-04T23:34:38.413Z","avatar_url":"https://github.com/AbdisamadMoh.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# BlazorStyleSheet\n\n**BlazorStyleSheet** is a powerful CSS styling engine expertly crafted for Blazor Server, WebAssembly, and MAUI applications. It empowers you to define **scoped, maintainable styles directly within your C# code, completely eliminating the need for external CSS files.**\n\n**BlazorStyleSheet** is built on top of **Stylesheet.NET**.\n\n**Stylesheet.Net** is a cross-platform .NET library designed for C#, VB.NET, and F# developers. It enables developers to write CSS styles directly in their code, eliminating the need for external stylesheet files. **Stylesheet.Net** provides pre-written implementations for all CSS properties, at-rules, keywords, and other elements, eliminating the need for additional dependencies.\n\n\u003e **Stylesheet.Net** is not a library from outside. It is an open source (MIT) library I wrote and maintain.\n\n**Repository**: https://github.com/AbdisamadMoh/Stylesheet.NET\n\nI would recommend you to have a look and understand how to use **Stylesheet.Net** before you can continue this tutorial. Click the link above and read the documentations.\n\n![https//githubcom/AbdisamadMoh/StylesheetNET/raw/master/20240304013616imagepng](https://github.com/AbdisamadMoh/Stylesheet.NET/raw/master/2024-03-04-01-36-16-image.png)\n\n## Quick start\n\nTo start using **BlazorStylesheet**, we first need to add it in our project.\n\nWe can add it from **nuget**, or directly referencing **BlazorStylesheet.dll**\n\nOpen `nuget` package manager in **visual studio** and paste the following code.\n\n```csharp\nInstall-Package BlazorStylesheet -Version 1.0.0\n```\n\n1. After installation done, open the file **Program.cs** or **Startup.cs** or **MauiProgram.cs** in your blazor project.\n   \n   **Add the following code**\n   \n   ```csharp\n   using BlazorStylesheet;\n   builder.Services.AddStylesheet();\n   ```\n\n2. Open the file **_Imports.razor**. In **blazor server** and **webassembly** you can find it under the project root. For **MAUI** you can find it under **Components** folder.\n\n**Add the following namespaces**\n\n```csharp\n@using BlazorStylesheet\n@using StylesheetNET\n```\n\n3. Now open **_Layout.cshtml** in **blazor server** which you can find it under **Shared** folder, or **index.html** in **blazor webassembly** and **MAUI** which you can find it under **wwwroot** folder.\n   \n   **Add the following html tags in the head before any script or styles.**\n   \n   ```html\n   \u003clink href=\"_content/BlazorStylesheet/fix.min.css\" rel=\"stylesheet\" /\u003e\n   \u003cscript src=\"_content/BlazorStylesheet/BlazorStylesheet.js\"\u003e\u003c/script\u003e\n   ```\n   \n   ![](https://imgur.com/zzdmRcX.png)\n   \n   **Now scroll up, in the tag \u003chtm ...\u003e add *loading=\"loader\"*. I will explain why we need these tags and attributes in later sections (see section 'Why we need...').**\n   \n   ```csharp\n   loading=\"loader\"\n    OR\n   loading=\"\"\n   ```\n   \n   ![](https://imgur.com/3Y767Gj.png)\n\n4. And lastly, in **Blazor Server** and **Blazor Webassembly** open **App.razor** which you can find under the project **root**. And in **MAUI**, open **Routes.razor** which you can find under **Components** folder. \n   \n   **Wrap everything you see there with:** \n   \n   ```cshtml\n   \u003cRazorStylesheet\u003e \u003c/RazorStylesheet\u003e\n   ```\n   \n   ![](https://imgur.com/AW5x14N.png)\n\n\u003e You have to complete every step mentioned above. \n\n### Now we are ready to write our first css in C#.\n\nin our **MainLayout.razor**, let's inject the **main stylesheet** and call it `sheet`. Then we can use `sheet` property to write our CSS. You can do this in every component you want to access the **main stylesheet**.\n\nNow copy the following code and paste in **MainLayout.razor** C# code.\n\n```csharp\n [Inject]\n public Stylesheet sheet\n {\n     get; set;\n }\n\n protected override void OnAfterRender(bool firstRender)\n {\n    base.OnAfterRender(firstRender);\n\n    if (firstRender)\n    {\n        sheet[\"body\"].BackgroundColor = \"blue\";\n        sheet.Build();\n    }\n\n }\n```\n\nNow build your application and refresh the browser. You will see your html body became `blue` color.\n\nTo learn how to write your stylesheet in C# please refer to https://github.com/AbdisamadMoh/Stylesheet.NET#quick-start\n\nTo access `sheet `in other components, `inject` them the `stylesheet`, following **step 4** above.\n\n\u003e Whenever you change something in your `stylesheet`, you have to call `sheet.Build()` to reflect the changes in the `DOM`.\n\nThat is how you can access your `stylesheet` in your components. But writing your whole css in a component is not a good idea as that makes your component codes unreadable.\n\nInfact there is nothing wrong writing your css in your components. But it is good idea to write in a separate `classes`. We will do that in the next section. Also we will learn when we should write our css in a component.\n\n### Lets build real world application\n\nNow lets cretate the following **navbar** menu.\n\n![](https://imgur.com/vFkjofP.png)\n\n1. Create a new component and name it **NavBar.Razor**.\n\n2. Paste the following `html` code in the **NavBar.Razor** you have created.\n\n```cshtml\n\u003cnav class=\"navbar\"\u003e\n    \u003ca href=\"#\" class=\"selected\"\u003eHome\u003c/a\u003e\n    \u003ca href=\"#\"\u003eAbout\u003c/a\u003e\n    \u003ca href=\"#\"\u003eBlog\u003c/a\u003e\n    \u003ca href=\"#\"\u003ePortefolio\u003c/a\u003e\n    \u003ca href=\"#\"\u003eContact\u003c/a\u003e\n\u003c/nav\u003e\n```\n\n3. Add the **NavBar.Razor** you have created to **MainLayout.razor** or in any other component you want.\n   \n   ![NavBar](https://imgur.com/S4qjYMq.png)\n\n4. Now lets create our CSS in C#. Create a new class and call it `Style.cs` and add these two namespaces.\n\n```csharp\nusing BlazorStylesheet;\nusing StylesheetNET;\n```\n\nNow, our class may look somehing like this:\n\n```csharp\npublic class Style\n{\n}\n```\n\nBut that's just a simple class, and **BlazorStylesheet** doesn't recognize it. We need to indicate that this class is for **stylesheet**. We can do that by simply decorating it with `[StylesheetClass]` attribute like this:\n\n```csharp\n[StylesheetClass]\npublic class Style\n{ \n}\n```\n\nNow, when we run our application, **BlazorStylesheet** will recognize our class and compile it into CSS. \n\nNow let's write some CSS in our class. **But write where?**\n\nWell, lets add a method and name it `Setup` and decorate it with `[StylesheetMethod]` like this:\n\n```csharp\n[StylesheetMethod]\nprivate void Setup()\n{\n\n}\n```\n\nWhen we run our application again and **BlazorStylesheet** finds our class, it will look for our `Setup` method and executes it.\n\nInfact, our `Setup` method is executed, not because it is called `Setup` but **BlazorStylesheet** looks for any parameterless methods that are decorated with `[StylesheetMethod]` attribute and executes them. That means we can have as many methods as we want and name whatever names we want.\n\n```csharp\n[StylesheetMethod]\npublic void method1()\n{\n    // will be executed\n} \n\npublic method2()\n{\n    // will not be executed because it is missing [StylesheetMethod]\n   // BlazorStylesheet will ignore it.\n} \n\n\n[StylesheetMethod]\npublic void method3(object parameter)\n{\n    // will throw an exception error \n   // bacause a method with [StylesheetMethod]\n   // should not have any parameter. \n}\n```\n\n**But still, how we supposed to write our CSS?**\n\nWell, to write our CSS we need to have an access to our **main stylesheet**. The **main stylesheet** is the stylesheet that acts like the **stylesheet file** of our website. It is created when the browser loads our website. And its available throughout our website and it is constant, meaning, it never gets recreated again untill the browser is refreshed. \n\nIn **razor components** we can access it through injection. \n\nBut to access the **main stylesheet** in our class, we have to add a property of type `Stylesheet` and decorate it with `[StylesheetProperty]`. We can name it whatever name we want. For this example, we will name it `sheet`.\n\n```csharp\n [StylesheetClass]\n public class Style\n {\n     [StylesheetProperty]\n     private Stylesheet sheet\n     {\n         get;\n         set;\n     }\n }\n```\n\nNow, `sheet` is a reference to our **main stylesheet**. And we can use it to write our CSS.\n\n**BlazorStylesheet** will look for any property with attribute `[StylesheetProperty]` and reference them to the **main stylesheet**.\n\nNow, to check if everything is working like expected.  Let's give our website's  **body** `red background color`. \n\nYour `Style.cs` class should look like this for now.\n\n```csharp\n [StylesheetClass]\n public class Style\n {\n     [StylesheetProperty]\n     public Stylesheet sheet\n     {\n         get;\n         set;\n     }\n\n     [StylesheetMethod]\n     private void MakeBodyRed()\n     {\n         sheet[\"body\"] = new Element()\n         {\n             BackgroundColor = \"red !important\"\n         };\n       //You can also write like this: \n       // sheet[\"body\"].BackgroundColor = \"red !important\";\n      // But the way i wrote is recommended and cleaner if you are not updating.\n     }\n }\n```\n\nNow build your application and refresh the browser. Your website body should be red.\n\n\u003e In **MAUI**, you may encounter this error:\n\u003e \n\u003e  `'Element' is an ambiguous reference between 'Microsoft.Maui.Controls.Element' and 'StylesheetNET.Element'` \n\u003e \n\u003e Because both `Microsoft.Maui.Controls` and `StylesheetNET` have `Element` class. \n\u003e \n\u003e **To fix, Add the following namespace:**\n\u003e \n\u003e ```csharp\n\u003e using Element = StylesheetNET.Element;\n\u003e ```\n\u003e \n\u003e ![image](https://imgur.com/ZratGZV.png)\n\n##### If everything is going right, let's write the CSS for our `Navbar.razor`\n\nAlthough you can write your CSS in anyway you like, but it is good idea to categorize them in methods. That is what we will do here.\n\nNow let's write our full CSS. Here is the full C# code.\n\n```csharp\n  [StylesheetClass]\n  public class Style\n  {\n      [StylesheetProperty]\n      private Stylesheet sheet\n      {\n          get;\n          set;\n      }\n\n      [StylesheetMethod]\n      private void NavBar()\n      {\n          sheet[\".navbar\"] = new Element()\n          {\n\n              Position = PositionOptions.Relative,\n              Width = \"590px\",\n              Height = \"60px\",\n              PaddingLeft = \"10px\",\n              PaddingRight = \"10px\",\n              BackgroundColor = \"#34495e\",\n              BorderRadius = \"8px\",\n              FontSize = \"0\"\n          };\n      }\n      [StylesheetMethod]\n      private void NavBar_a()\n      {\n          sheet[\".navbar \u003e a\"] = new Element()\n          {\n              LineHeight = \"50px\",\n              Height = \"100%\",\n              Width = \"100px\",\n              FontSize = \"15px\",\n              Display = DisplayOptions.InlineBlock,\n              Position = PositionOptions.Relative,\n              ZIndex = \"1\",\n              TextDecoration = \"none\",\n              TextTransform = TextTransformOptions.Uppercase,\n              TextAlign = TextAlignOptions.Center,\n              Color = \"white\",\n              Cursor = CursorOptions.Pointer\n          };\n      }\n      [StylesheetMethod]\n      private void NavBar_a_Selected()\n      {\n          sheet[\".navbar \u003e a.selected\"] = new Element()\n          {\n              BackgroundColor = \"#17B1EA\",\n              BorderRadius = \"10px\"\n\n          };\n      }\n      [StylesheetMethod]\n      private void NavBar_a_Selected_Hover()\n      {\n          sheet[\".navbar \u003e a\"] = new ElementHover()\n          {\n              BackgroundColor = \"#17B1EA\",\n              BorderRadius = \"10px\",\n              Transition = \"border-radius\",\n              TransitionDuration = \".3s\",\n              TransitionTimingFunction = TransitionTimingFunctionOptions.EaseIn\n\n          };\n      }\n      [StylesheetMethod]\n      void Animation()\n      {\n          sheet[\"h1\"] = new Element()\n          {\n              AnimationName = \"pulse\",\n              AnimationDuration = \"2s\",\n              AnimationIterationCount = AnimationIterationCountOptions.Infinite\n          };\n\n          sheet[AtRuleType.Keyframes] = new Keyframes(\"pulse\")\n          {\n              [\"from\"] = new Keyframe()\n              {\n                  Opacity = \"1.0\"\n              },\n              [\"to\"] = new Keyframe()\n              {\n                  Opacity = \"0\"\n              }\n          };\n      }\n      //Media Query for Mobile Devices\n      // @media (max-width: 480px) \n      [StylesheetMethod]\n      void ForMobile() //Make body red for mobile phones\n      {\n          sheet[AtRuleType.MediaQuery] = new MediaQuery(new AtRule().MaxWidth(\"480px\"))\n          {\n              [\"body\"] = new Element()\n              {\n                  BackgroundColor = \"red\"\n              }\n          };\n      }\n      // Media Query for low resolution  Tablets, Ipads\n      // @media (min-width: 481px) and (max-width: 767px)\n      [StylesheetMethod]\n      void ForTablet() //Make body yellow for Tablets, Ipads\n      {\n          sheet[AtRuleType.MediaQuery] = new MediaQuery(new AtRule().MinWidth(\"481px\").And.MaxWidth(\"767px\"))\n          {\n              [\"body\"] = new Element()\n              {\n                  BackgroundColor = \"yellow\"\n              }\n          };\n      }\n\n      // Media Query for Laptops and Desktops\n      // @media (min-width: 1025px) and (max-width: 1280px)\n      [StylesheetMethod]\n      void ForDesktop() //Make body gren for Laptops and Desktops\n      {\n          sheet[AtRuleType.MediaQuery] = new MediaQuery(new AtRule().MinWidth(\"1025px\").And.MaxWidth(\"1280px\"))\n          {\n              [\"body\"] = new Element()\n              {\n                  BackgroundColor = \"green\"\n              }\n          };\n      }\n  }\n```\n\nApart from the style for the **NavBar.Razor**, we also added Media queries for **mobile**, **Tablet** and **Desktop** where we change the background color of the `body` for each. We also added animation called `flash` for` h1` elements.\n\nThat is how you can write you CSS in classes in C# using **BlazorStylesheet**. Following this way, you can have as many classes as you want. At the end of the day, all of them will be compiled into a single stylesheet file. \n\n\u003e If you write same CSS in different places i.e classes, always the later ones will override the older ones. Depending the order of execution and compilation.\n\nHere, I haven't covered a full tutorial on how to write CSS in C# using **BlazorStylesheet**. Because this library uses the **Stylesheet.NET** library, which has a comprehensive tutorial, you can refer to the link below for detailed guidance on writing CSS in C#.\n\n**Repository**: https://github.com/AbdisamadMoh/Stylesheet.NET\n\n### When and how to write CSS in components?\n\nWith **BlazorStylesheet**, we have the freedom to write our CSS anywhere in our Blazor project. This is handy for keeping styles specific to a particular component and updating our CSS in realtime. But remember, for bigger styles or styles used across your whole application, it's generally better to organize them in separate C# classes. This makes your code easier to manage.\n\nUnlike classes, which we can access the **main stylesheet** through attribute decoration which the injection is managed by the **BlazorStylesheet** itself. In **components**, we can access the **main stylesheet** through injection provided by the **Dependency Injection (DI)** container provided by .NET.\n\nIn your components use `@Inject`. Put it top of your **razor** file.\n\n```cshtml\n@inject Stylesheet sheet\n```\n\n![image](https://imgur.com/Oy9LL3V.png)\n\nThen you can use `sheet `in your component.\n\n```csharp\n protected override void OnAfterRender(bool firstRender)\n {\n     base.OnAfterRender(firstRender);\n     if (firstRender)\n     {\n         sheet[\"body\"].BackgroundColor = \"blue\";\n         sheet.Build();\n     }\n }\n```\n\nIn **components** or other places where **BlazorStylesheet** doesn't manage, you have to call `sheet.Build()` when you change something in the stylesheet to reflect the changes.\n\n\u003e You don't need to call  `StateHasChanged()` as that has no effect on **BlazorStylesheet**.\n\n### Why we need...\n\n#### `loading=\"loader\"` attribute in our `\u003chtml loading=\"loader\"\u003e` and `fix.css`?\n\n**BlazorStylesheet** depends on **JavaScript runtime (JSRuntime)** provided by Blazor. **JSRuntime** is not ready untill the whole page is loaded. This means **BlazorStylesheet** has to wait untill **JSRuntime** is ready to send the compiled CSS to the clientside.\n\nThis will create a problem where your website is not styled untill everything is loaded. You can fix this problem by either showing a loader or not displaying the website untill the css is ready and the website is styled.\n\nBoth solutions lies in `fix.css` file you added.\n\n**To show loader while the website is getting ready add the following html attribute in your html tag.**\n\n\u003chtml lang=\"en\" loading=\"loader\"\u003e\n\n```html\n\u003chtml loading=\"loader\"\u003e\n```\n\n**To not show the content of the website while it is getting ready add the following html attribute in your html tag.**\n\n```html\n\u003chtml loading=\"\"\u003e\n```\n\n\u003chtml lang=\"en\" loading=\"loader\"\u003e\n\n\u003chtml lang=\"en\" loading=\"loader\"\u003e\n\n\u003e **BlazorStylesheet** does not add any element to the DOM to create the loader. So you should not worry about your DOM being modified.\n\n## More...\n\nThis library uses **Stylesheet.NET** which you can find the repository below\n\n**Repository**: https://github.com/AbdisamadMoh/Stylesheet.NET\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fabdisamadmoh%2Fblazorstylesheet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fabdisamadmoh%2Fblazorstylesheet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fabdisamadmoh%2Fblazorstylesheet/lists"}