ASP.NET Core 2.2 - Free Themes For Bootstrap 4

Ken Haggerty
Created 01/18/2019 - Updated 03/27/2019 09:43
Update 03/27/2019

I found and corrected a misspelling for the sandstone theme parameter in the dropdown menu.

Update 02/28/2019

I updated KenHaggerty.Com to Bootstrap 4.3.1, therefore I updated the article with the correct cdn paths and integrity hashes for version 4.3.1. The files at the asp-fallback-href paths also have to be updated or the integrity checks will fail if the cdn is not available.

The ASP.NET Core 2.2 template creates a basic functional web application. The new template includes Bootstrap 4 rather than Bootstrap 3 as in earlier versions. There are plenty of articles about the main differences between 3 and 4 like Bootstrap 3 or Bootstrap 4? Which one to choose? so I won't cover it here. I'll just say there are a few changes we all should take advantage of.

You can definitely see a difference even with the default theme installed by the template. It is lighter. brighter and has a simplistic appeal over the previous default theme. If you want to use Bootstrap 3 with the new Identity UI, it appears you will have to replace the Bootstrap files and change the setting in Startup.cs > ConfigureServices > services.AddDefaultIdentity<IdentityUser>() from (UIFramework.Bootstrap4) to (UIFramework.Bootstrap3). I haven't tried this because I am learning Bootstrap 4.

I have used Free themes for Bootstrap from Bootswatch with v3 and decided to add a theme picker to this site using v4. You may select a theme from the navigation bar which sets a 1 day theme cookie. This article is about how I did this.

Let us start in Pages > Shared > _Layout.cshtml from the top down:

Add the cookie get just above <!DOCTYPE html> replacing YOURGOMAIN.COM with your own identifier:

@{
    Context.Request.Cookies.TryGetValue("<YOURDOMAIN.COM>.Theme", out string theme);
}

Remove the Bootstrap css references. I will use the new themes in development because some of themes have varying effects on layout.

    <environment include="Development">
        <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
    </environment>
    <environment exclude="Development">
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css"
              asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
              asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute"
              crossorigin="anonymous"
              integrity="sha256-eSi1q2PG6J7g7ib17yAaWMcrr5GrtohYChqibrV7PBE="/>
    </environment>

Add a css reference dependent on the theme, setting your favorite if none is set:

    @{
        if (string.IsNullOrEmpty(theme))
        {
            theme = "cosmo";
        }
        switch (theme)
        {
            case "default":
                <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/css/bootstrap.min.css"
                      asp-fallback-href = "~/lib/bootstrap/dist/css/default/bootstrap.min.css" asp-suppress-fallback-integrity="true"
                      asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute"
                      integrity="sha256-YLGeXaapI0/5IgZopewRJcFXomhRMlYYjugPLSyNjTY=" />
                      crossorigin="anonymous"
            case "cerulean":
                <link href = "https://stackpath.bootstrapcdn.com/bootswatch/4.3.1/cerulean/bootstrap.min.css" rel="stylesheet"
                      asp-fallback-href="~/lib/bootstrap/dist/css/cerulean/bootstrap.min.css" asp-suppress-fallback-integrity="true"
                      asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute"
                      integrity="sha384-C++cugH8+Uf86JbNOnQoBweHHAe/wVKN/mb0lTybu/NZ9sEYbd+BbbYtNpWYAsNP"
                      crossorigin="anonymous">
                break;
            case "cosmo":
                <link href = "https://stackpath.bootstrapcdn.com/bootswatch/4.3.1/cosmo/bootstrap.min.css" rel="stylesheet"
                      asp-fallback-href="~/lib/bootstrap/dist/css/cosmo/bootstrap.min.css" asp-suppress-fallback-integrity="true"
                      asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute"
                      integrity="sha384-uhut8PejFZO8994oEgm/ZfAv0mW1/b83nczZzSwElbeILxwkN491YQXsCFTE6+nx"
                      crossorigin="anonymous">
                break;
            case "cyborg":
                <link href = "https://stackpath.bootstrapcdn.com/bootswatch/4.3.1/cyborg/bootstrap.min.css" rel="stylesheet"
                      asp-fallback-href="~/lib/bootstrap/dist/css/cyborg/bootstrap.min.css" asp-suppress-fallback-integrity="true"
                      asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute"
                      integrity="sha384-mtS696VnV9qeIoC8w/PrPoRzJ5gwydRVn0oQ9b+RJOPxE1Z1jXuuJcyeNxvNZhdx"
                      crossorigin="anonymous">
                break;
            case "darkly":
                <link href = "https://stackpath.bootstrapcdn.com/bootswatch/4.3.1/darkly/bootstrap.min.css" rel="stylesheet"
                      asp-fallback-href="~/lib/bootstrap/dist/css/darkly/bootstrap.min.css" asp-suppress-fallback-integrity="true"
                      asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute"
                      integrity="sha384-w+8Gqjk9Cuo6XH9HKHG5t5I1VR4YBNdPt/29vwgfZR485eoEJZ8rJRbm3TR32P6k"
                      crossorigin="anonymous">
                break;
            case "flatly":
                <link href = "https://stackpath.bootstrapcdn.com/bootswatch/4.3.1/flatly/bootstrap.min.css" rel="stylesheet"
                      asp-fallback-href="~/lib/bootstrap/dist/css/flatly/bootstrap.min.css" asp-suppress-fallback-integrity="true"
                      asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute"
                      integrity="sha384-T5jhQKMh96HMkXwqVMSjF3CmLcL1nT9//tCqu9By5XSdj7CwR0r+F3LTzUdfkkQf"
                      crossorigin="anonymous">
                break;
            case "journal":
                <link href = "https://stackpath.bootstrapcdn.com/bootswatch/4.3.1/journal/bootstrap.min.css" rel="stylesheet"
                      asp-fallback-href="~/lib/bootstrap/dist/css/journal/bootstrap.min.css" asp-suppress-fallback-integrity="true"
                      asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute"
                      integrity="sha384-ciphE0NCAlD2/N6NUApXAN2dAs/vcSAOTzyE202jJx3oS8n4tAQezRgnlHqcJ59C"
                      crossorigin="anonymous">
                break;
            case "litera":
                <link href = "https://stackpath.bootstrapcdn.com/bootswatch/4.3.1/litera/bootstrap.min.css" rel="stylesheet"
                      asp-fallback-href="~/lib/bootstrap/dist/css/litera/bootstrap.min.css" asp-suppress-fallback-integrity="true"
                      asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute"
                      integrity="sha384-D/7uAka7uwterkSxa2LwZR7RJqH2X6jfmhkJ0vFPGUtPyBMF2WMq9S+f9Ik5jJu1"
                      crossorigin="anonymous">
                break;
            case "lumen":
                <link href = "https://stackpath.bootstrapcdn.com/bootswatch/4.3.1/lumen/bootstrap.min.css" rel="stylesheet"
                      asp-fallback-href="~/lib/bootstrap/dist/css/lumen/bootstrap.min.css" asp-suppress-fallback-integrity="true"
                      asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute"
                      integrity="sha384-iqcNtN3rj6Y1HX/R0a3zu3ngmbdwEa9qQGHdkXwSRoiE+Gj71p0UNDSm99LcXiXV"
                      crossorigin="anonymous">
                break;
            case "lux":
                <link href = "https://stackpath.bootstrapcdn.com/bootswatch/4.3.1/lux/bootstrap.min.css" rel="stylesheet"
                      asp-fallback-href="~/lib/bootstrap/dist/css/lux/bootstrap.min.css" asp-suppress-fallback-integrity="true"
                      asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute"
                      integrity="sha384-hVpXlpdRmJ+uXGwD5W6HZMnR9ENcKVRn855pPbuI/mwPIEKAuKgTKgGksVGmlAvt"
                      crossorigin="anonymous">
                break;
            case "materia":
                <link href = "https://stackpath.bootstrapcdn.com/bootswatch/4.3.1/materia/bootstrap.min.css" rel="stylesheet"
                      asp-fallback-href="~/lib/bootstrap/dist/css/materia/bootstrap.min.css" asp-suppress-fallback-integrity="true"
                      asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute"
                      integrity="sha384-SYbiks6VdZNAKT8DNoXQZwXAiuUo5/quw6nMKtFlGO/4WwxW86BSTMtgdzzB9JJl"
                      crossorigin="anonymous">
                break;
            case "minty":
                <link href = "https://stackpath.bootstrapcdn.com/bootswatch/4.3.1/minty/bootstrap.min.css" rel="stylesheet"
                      asp-fallback-href="~/lib/bootstrap/dist/css/minty/bootstrap.min.css" asp-suppress-fallback-integrity="true"
                      asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute"
                      integrity="sha384-9NlqO4dP5KfioUGS568UFwM3lbWf3Uj3Qb7FBHuIuhLoDp3ZgAqPE1/MYLEBPZYM"
                      crossorigin="anonymous">
                break;
            case "pulse":
                <link href = "https://stackpath.bootstrapcdn.com/bootswatch/4.3.1/pulse/bootstrap.min.css" rel="stylesheet"
                      asp-fallback-href="~/lib/bootstrap/dist/css/pulse/bootstrap.min.css" asp-suppress-fallback-integrity="true"
                      asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute"
                      integrity="sha384-/uQFqO50IaQu2rNJYKPpV7zwsWJtd6V4DGX4wMw1ATz4KPuZEV96qQ2heVAw2kr2"
                      crossorigin="anonymous">
                break;
            case "sandstone":
                <link href = "https://stackpath.bootstrapcdn.com/bootswatch/4.3.1/sandstone/bootstrap.min.css" rel="stylesheet"
                      asp-fallback-href="~/lib/bootstrap/dist/css/sandstone/bootstrap.min.css" asp-suppress-fallback-integrity="true"
                      asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute"
                      integrity="sha384-G3Fme2BM4boCE9tHx9zHvcxaQoAkksPQa/8oyn1Dzqv7gdcXChereUsXGx6LtbqA"
                      crossorigin="anonymous">
                break;
            case "simplex":
                <link href = "https://stackpath.bootstrapcdn.com/bootswatch/4.3.1/simplex/bootstrap.min.css" rel="stylesheet"
                      asp-fallback-href="~/lib/bootstrap/dist/css/simplex/bootstrap.min.css" asp-suppress-fallback-integrity="true"
                      asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute"
                      integrity="sha384-1OYccka9EByiS23wvPFiYHBPRAgU91xYVFb8g8sen6vRiBI5Uko6+B87q8zPGUnA"
                      crossorigin="anonymous">
                break;
            case "sketchy":
                <link href = "https://stackpath.bootstrapcdn.com/bootswatch/4.3.1/sketchy/bootstrap.min.css" rel="stylesheet"
                      asp-fallback-href="~/lib/bootstrap/dist/css/sketchy/bootstrap.min.css" asp-suppress-fallback-integrity="true"
                      asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute"
                      integrity="sha384-N8DsABZCqc1XWbg/bAlIDk7AS/yNzT5fcKzg/TwfmTuUqZhGquVmpb5VvfmLcMzp"
                      crossorigin="anonymous">
                break;
            case "slate":
                <link href = "https://stackpath.bootstrapcdn.com/bootswatch/4.3.1/slate/bootstrap.min.css" rel="stylesheet"
                      asp-fallback-href="~/lib/bootstrap/dist/css/slate/bootstrap.min.css" asp-suppress-fallback-integrity="true"
                      asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute"
                      integrity="sha384-FBPbZPVh+7ks5JJ70RJmIaqyGnvMbeJ5JQfEbW0Ac6ErfvEg9yG56JQJuMNptWsH"
                      crossorigin="anonymous">
                break;
            case "solar":
                <link href = "https://stackpath.bootstrapcdn.com/bootswatch/4.3.1/solar/bootstrap.min.css" rel="stylesheet"
                      asp-fallback-href="~/lib/bootstrap/dist/css/solar/bootstrap.min.css" asp-suppress-fallback-integrity="true"
                      asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute"
                      integrity="sha384-8nq3OiMMgrVFAHyRMMO+DTfMEciSY+c3Awhj/5ljQ1xck1Uv2BUtMjsjLD8GT5Er"
                      crossorigin="anonymous">
                break;
            case "spacelab":
                <link href = "https://stackpath.bootstrapcdn.com/bootswatch/4.3.1/spacelab/bootstrap.min.css" rel="stylesheet"
                      asp-fallback-href="~/lib/bootstrap/dist/css/spacelab/bootstrap.min.css" asp-suppress-fallback-integrity="true"
                      asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute"
                      integrity="sha384-sZG5VVk41YqhJjYXgJFoRVd3d2AdDgy4oyIytQJMGx/Mizz1N+5bgKQBSCGfKQnP"
                      crossorigin="anonymous">
                break;
            case "superhero":
                <link href = "https://stackpath.bootstrapcdn.com/bootswatch/4.3.1/superhero/bootstrap.min.css" rel="stylesheet"
                      asp-fallback-href="~/lib/bootstrap/dist/css/superhero/bootstrap.min.css" asp-suppress-fallback-integrity="true"
                      asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute"
                      integrity="sha384-LS4/wo5Z/8SLpOLHs0IbuPAGOWTx30XSoZJ8o7WKH0UJhRpjXXTpODOjfVnNjeHu"
                      crossorigin="anonymous">
                break;
            case "united":
                <link href = "https://stackpath.bootstrapcdn.com/bootswatch/4.3.1/united/bootstrap.min.css" rel="stylesheet"
                      asp-fallback-href="~/lib/bootstrap/dist/css/united/bootstrap.min.css" asp-suppress-fallback-integrity="true"
                      asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute"
                      integrity="sha384-WTtvlZJeRyCiKUtbQ88X1x9uHmKi0eHCbQ8irbzqSLkE0DpAZuixT5yFvgX0CjIu"
                      crossorigin="anonymous">
                break;
            case "yeti":
                <link href = "https://stackpath.bootstrapcdn.com/bootswatch/4.3.1/yeti/bootstrap.min.css" rel="stylesheet"
                      asp-fallback-href="~/lib/bootstrap/dist/css/yetibootstrap.min.css" asp-suppress-fallback-integrity="true"
                      asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute"
                      integrity="sha384-w6tc0TXjTUnYHwVwGgnYyV12wbRoJQo9iMlC2KdkdmVvntGgzT9jvqNEF/uKaF4m"
                      crossorigin="anonymous">
                break;
            default:
                <link href = "https://stackpath.bootstrapcdn.com/bootswatch/4.3.1/cosmo/bootstrap.min.css" rel="stylesheet"
                      asp-fallback-href="~/lib/bootstrap/dist/css/cosmo/bootstrap.min.css" asp-suppress-fallback-integrity="true"
                      asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute"
                      integrity="sha384-uhut8PejFZO8994oEgm/ZfAv0mW1/b83nczZzSwElbeILxwkN491YQXsCFTE6+nx"
                      crossorigin="anonymous">
                break;
        }
    }

Section references: BootstrapCDN

Add a dropdown nav item to the navigation bar for your list of themes:

<li class="nav-item dropdown">
    <a class="nav-link dropdown-toggle" id="navbarDropdownTheme" data-target="#" href="#" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Theme</a>
    <ul class="dropdown-menu" aria-labelledby="navbarDropdownTheme">
        <li><a class="dropdown-item theme @(theme == "default" ? "active" : "")" data-theme="default" href="#">Default</a></li>
        <li><a class="dropdown-item theme @(theme == "cerulean" ? "active" : "")" data-theme="cerulean" href="#">Cerulean</a></li>
        <li><a class="dropdown-item theme @(theme == "cosmo" ? "active" : "")" data-theme="cosmo" href="#">Cosmo</a></li>
        <li><a class="dropdown-item theme @(theme == "cyborg" ? "active" : "")" data-theme="cyborg" href="#">Cyborg</a></li>
        <li><a class="dropdown-item theme @(theme == "darkly" ? "active" : "")" data-theme="darkly" href="#">Darkly</a></li>
        <li><a class="dropdown-item theme @(theme == "flatly" ? "active" : "")" data-theme="flatly" href="#">Flatly</a></li>
        <li><a class="dropdown-item theme @(theme == "journal" ? "active" : "")" data-theme="journal" href="#">Journal</a></li>
        <li><a class="dropdown-item theme @(theme == "litera" ? "active" : "")" data-theme="litera" href="#">Litera</a></li>
        <li><a class="dropdown-item theme @(theme == "lumen" ? "active" : "")" data-theme="lumen" href="#">Lumen</a></li>
        <li><a class="dropdown-item theme @(theme == "lux" ? "active" : "")" data-theme="lux" href="#">Lux</a></li>
        <li><a class="dropdown-item theme @(theme == "materia" ? "active" : "")" data-theme="materia" href="#">Materia</a></li>
        <li><a class="dropdown-item theme @(theme == "minty" ? "active" : "")" data-theme="minty" href="#">Minty</a></li>
        <li><a class="dropdown-item theme @(theme == "pulse" ? "active" : "")" data-theme="pulse" href="#">Pulse</a></li>
        <li><a class="dropdown-item theme @(theme == "sandstone" ? "active" : "")" data-theme="sandstone" href="#">Sandstone</a></li>
        <li><a class="dropdown-item theme @(theme == "simplex" ? "active" : "")" data-theme="simplex" href="#">Simplex</a></li>
        <li><a class="dropdown-item theme @(theme == "sketchy" ? "active" : "")" data-theme="sketchy" href="#">Sketchy</a></li>
        <li><a class="dropdown-item theme @(theme == "slate" ? "active" : "")" data-theme="slate" href="#">Slate</a></li>
        <li><a class="dropdown-item theme @(theme == "solar" ? "active" : "")" data-theme="solar" href="#">Solar</a></li>
        <li><a class="dropdown-item theme @(theme == "spacelab" ? "active" : "")" data-theme="spacelab" href="#">Spacelab</a></li>
        <li><a class="dropdown-item theme @(theme == "superhero" ? "active" : "")" data-theme="superhero" href="#">Superhero</a></li>
        <li><a class="dropdown-item theme @(theme == "united" ? "active" : "")" data-theme="united" href="#">United</a></li>
        <li><a class="dropdown-item theme @(theme == "yeti" ? "active" : "")" data-theme="yeti" href="#">Yeti</a></li>
    </ul>
</li>

I got the most of the Navbar Dropdown from Craig Watson's Code Pen. The data-theme I will cover next.

Section references: Craig Watson's Code Pen

Now the JavaScript part:

I use a cookie helper called js-cookie but you can set the theme cookie as you prefer.

Download and add the js-cookie script to the bottom of _Layout.cshtml but before site.js:

<script src="~/js/js.cookie.js"></script>

Section references: js-cookie

In site.js, add the jQuery on click event for each of the dropdown-items using the class theme and set the cookie value based on the data-theme attribute. Be sure to set the cookie identifier as before. I set the cookie to expire in 1 day.

$('.theme').on('click', function () {
    Cookies.set('<YOURDOMAIN.COM>.Theme', $(this).data('theme'), { expires: 1 });
    location.reload();
});

Update the bootstrap.bundle.min.js script towards the bottom of _Layout.cshtml after the jQuery script link:

<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/js/bootstrap.bundle.min.js"
        asp-fallback-src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"
        asp-fallback-test="window.jQuery && window.jQuery.fn && window.jQuery.fn.modal"
        asp-suppress-fallback-integrity="true"
        integrity="sha256-fzFFyH01cBVPYzl16KT40wqjhgPtq6FFUB6ckN2+GGw=" crossorigin="anonymous">
</script>

Here is the bonus:

Because we set the theme in C# code, we can use it to add the active class to the current theme in our dropdown list. This is the function of @(theme == "cerulean" ? "active" : "").

You can check out all of the themes on this site and pick a favorite. I kinda like Spacelab. Let me know your thoughts or issues in the new comments section. Thanks for reading.

Article Tags:

Bootstrap

Comment Count = 0

Please log in to comment.

Login Register
Logged in users receive web notifications.
Web Notifications