Custom CSS Checkbox

Creating this post so I can remember how to do this.

Picked this up from youtube from the blazor power hour:

This basically creates a check box which has a nice border and a tick mark in the top left which I have made look like:

checkbox.PNG

This is done in a blazor project I am working on.

CSS:

body {
    background: #585c68;
}

.wrapper {
    width: 780px;
    margin: 100px auto 0;
}

    .wrapper .title {
        font-size: 24px;
        color: #fff;
        font-weight: 700;
        text-align: center;
        margin-bottom: 50px;
    }

.container {
    display: flex;
    flex-wrap: wrap;
}

    .container .option_item {
        display: block;
        position: relative;
        width: 175px;
        height: 175px;
        margin: 10px;
    }

        .container .option_item .checkbox {
            position: absolute;
            top: 0;
            left: 0;
            z-index: 1;
            opacity: 0;
        }

.option_item .option_inner {
    width: 100%;
    height: 100%;
    background: #ebebf2;
    border-radius: 5px;
    text-align: center;
    padding: 58px 40px;
    cursor: pointer;
    color: #585c68;
    display: block;
    border: 5px solid transparent;
    position: relative;
}

    .option_item .option_inner .icon {
        margin-bottom: 10px;
    }

        .option_item .option_inner .icon .fab {
            font-size: 32px;
        }

    .option_item .option_inner .name {
        user-select: none;
    }

.option_item .checkbox:checked ~ .option_inner.theme {
    border-color: #ff0000;
    color: #ff0000;
}

.option_item .option_inner .tickmark {
    position: absolute;
    top: 0;
    left: 0;
    border: 20px solid;
    border-color: #000 transparent transparent #000;
    display: none;
}

    .option_item .option_inner .tickmark:before {
        content: "";
        position: absolute;
        top: -18px;
        left: -18px;
        width: 15px;
        height: 5px;
        border: 3px solid;
        border-color: transparent transparent #fff #fff;
        transform: rotate(-45deg);
    }

.option_item .checkbox:checked ~ .option_inner .tickmark {
    display: block;
}

.option_item .option_inner.theme .tickmark {
    border-color: #ff0000 transparent transparent #ff0000;
}

Blazor Component Template:

@typeparam TItem

<div class="container">
    @foreach (var item in Items)
    {
        var Id = Guid.NewGuid();

        <label for="@Id" class="option_item" >
            <!-- Check to see if the checkbox needs to be checked or not from the user data byt checking if any of the items are already in the SelectedList -->
            @if (SelectedItems.Contains(item))
            {
                <input id="@Id" type="checkbox" class="checkbox" checked @onchange="_ => HandleChange(item)" />
                var i = 5;
            }
            else
            {
                <input id="@Id" type="checkbox" class="checkbox" @onchange="_ => HandleChange(item)" />
                var ii = 6;
            }
            <div class="option_inner theme">
                <div class="tickmark"></div>
                <div class="name">
                    @ItemTemplate(item)
                </div>
            </div>
        </label>
    }
</div>



@code {
    [Parameter]
    public IEnumerable<TItem> Items { get; set; }

    [Parameter]
    public RenderFragment<TItem> ItemTemplate { get; set; }

    [Parameter]
    public List<TItem> SelectedItems { get; set; } = new();

    [Parameter]
    public EventCallback<List<TItem>> SelectedItemsChanged { get; set; }

    void HandleChange(TItem item)
    {
        if (SelectedItems.Contains(item))
        {
            SelectedItems.Remove(item);
        }
        else
        {
            SelectedItems.Add(item);
        }

        SelectedItemsChanged.InvokeAsync(SelectedItems);
    }
}

The checking if an item already exists in the selected items list is done so that if it is then the box will be checked etc.

The implementation into a blazor page for my use is:

<SquareCheckBox Items="maintReqInitation.Isolations" Context="Isolation" @bind-SelectedItems="maintReqInitation.IsolationsSelected">
                                    <ItemTemplate>
                                        <div class="row">
                                            <div class="col-lg-12">
                                                <img src="@Isolation.ImageLocation" alt="@Isolation.Name" width="60" height="60" />
                                            </div>
                                        </div>
                                        <div class="row">
                                            <div class="col-lg-12">
                                                @Isolation.Name
                                            </div>
                                        </div>
                                    </ItemTemplate>
                                </SquareCheckBox>

The ItemTemplate allows the content of the check box to be set how it is needed with a image, icon, text etc.