How to use an unordered list to display labeled inputs with customized checkboxes using only CSS and HTML?

Viewed 28

I want to make a hidden context menu to display multiple genre selections. I want to customize the input checkboxes so that it looks like this:

this image is my required finished layout

It works fine without the label elements in the unordered list elements, however I need the label to toggle the checkbox. This is my current (incorrect) layout:

this image is what I have achieved so far

I have tried many things, including setting:

position: relative/absolute
display: flexbox/inline-block
widths and heights

How do I use an unordered list to display labeled inputs with customized checkboxes using only CSS and HTML?

    <div class="col-md-12 col-lg-4 text-lg-right mt-md-4 mt-lg-0">
        <div class="d-flex-column w-100" id="genre-bar">
            <!-- always visible selections bar -->
            <div class="row">
                <div class="col-12 mb-3 d-flex text-align-right">
                    <span class="w-100 genre-bar-display text-align-right align-items-center"><i class="fas fa-chevron-down"></i></span>
                </div>
            </div>
            <div class="genre-hidden-section px-3">
                <!-- Multiple selector -->
                <div class="row">
                    <div class="col-6 text-left">
                        <ul id="first-genre-list" class="genre-list">
                             <!-- This is populated by the @foreach below using JS -->
                        </ul>
                    </div>
                    <div class="col-6 text-left">
                        <ul id="second-genre-list" class="genre-list">
                        <!-- This is populated by the @foreach below using JS -->
                        </ul>
                    </div>
                </div>
            </div>
        </div>
        <!-- This div gets emptied and removed by JS immediately -->
        <div id="select-close-books-genre" style="display:none;">
            <ul>
                @foreach (GenreModel genre in Model.Genres)
                {
                    <li class="genre-checkbox-container">
                        <label>
                            @genre.Name
                            <span class="genre-checkmark"></span>
                            <input type="checkbox" value="@genre.Id">
                        </label>
                    </li>
                }
            </ul>
        </div>
    </div>
    li input {
        position: absolute;
        opacity: 0;
        cursor: pointer;
        height: 0;
        width: 0;
    }

    .genre-checkmark {
        display: inline-block;
        top: 0;
        left: 0;
        height: 13px;
        width: 13px;
        border: 1px black solid;
        border-radius: 3px;
        background-color: white;
    }

    .genre-list {
        display:flex;
        flex-wrap:wrap;
    }

    .genre-checkbox-container {
        flex-grow: 1;
    }

    .genre-checkbox-container:hover span {
        background-color: #ccc;
    }

    .genre-checkbox-container input:checked ~ .genre-checkmark {
        background-color: #30d9c8;
    }
    const genreListDiv = $("#select-close-books-genre")[0];
    const genreList = Array.from(genreListDiv.firstElementChild.children);
    genreListDiv.remove();
    console.log(genreList)
    for (let i = 0; i < genreList.length/2; i++) {
        $('#first-genre-list')[0].appendChild(genreList[i]);
    };
    for (let i = Math.ceil(genreList.length/2); i < genreList.length; i++) {
        $('#second-genre-list')[0].appendChild(genreList[i]);
    };

    // Open and close the genre selector box
    $("#genre-bar").on('click', function(event) {
        $("#genre-bar").addClass("genre-bar-open");
        $('body').on('click', function () {
            $('#genre-bar').removeClass("genre-bar-open");
        });
        $('#genre-bar').on('click', function (event) {
            event.stopPropagation();
        });
    });
0 Answers
Related