Friday 13 July 2018

Web Tutorial: Styling a Checkbox

The humble checkbox has been a mainstay of the web ever since HTML forms were in existence. Its purpose is to enable the user to select multiple options on a form. It's simple, effective and intuitive.

However, it has one notable flaw - it's pretty much unstylable in CSS. You can't alter the size or appearance of the checkbox. At most, you can make it appear or disappear. That said, for those determined to bend the humble checkbox to your will, being able to make it appear or disappear will be the key to this web tutorial today..

We begin with a bit of HTML incorporating two checkboxes with their respective labels. The first checkbox is labelled "Print" and the second is labelled "Email". Their ids will all also be named accordingly. As an example, we set the first checkbox to be checked by default.

<!DOCTYPE html>
<html>
    <head>
        <title>Checkboxes</title>

        <style>

        </style>

        <script>

        </script>
    </head>

    <body>
        <label for="cbPrint">Print</label>
        <input type="checkbox" name="cbPrint" id="cbPrint" value="print" checked>

        <br />

        <label for="cbEmail">Email</label>
        <input type="checkbox" name="cbEmail" id="cbEmail" value="email">
    </body>
</html>


It's just a plain-Jane checkbox. We're going to make our own soon!


We begin by enclosing each checkbox and its label in a div, and giving the div a class of checkbox_wrapper.
    <body>
        <div class="checkbox_wrapper">
            <label for="cbPrint">Print</label>
            <input type="checkbox" name="cbPrint" id="cbPrint" value="print" checked>
        </div>

        <br />

        <div class="checkbox_wrapper">
            <label for="cbEmail">Email</label>
            <input type="checkbox" name="cbEmail" id="cbEmail" value="email">
        </div>
    </body>


Then we style checkbox_wrapper.

In the main class, we set the cursor property to pointer so that when you mouse over the checkbox or label, it shows the user that this sucker is meant for clicking!

The label within the checkbox_wrapper class has font-size set to 16 pixels. This one's entirely up to you. I'm just making things pretty. I'm awesome like that.

And lastly, the checkbox, which is the input tag within the checkbox_wrapper class, has the display property set to inline. This is entirely unnecessary, because that is the default setting for the checkbox anyway. But we'll need this for later.
        <style>
            .checkbox_wrapper
            {
                cursor:pointer;
            }

            .checkbox_wrapper label
            {
                font-size:16px;
            }

            .checkbox_wrapper input
            {
                display:inline;
            }
        </style>


There shouldn't be significant change at this point, though you may notice that there's some spacing between your checkbox-label pairs, due to the divs they're enclosed in.


Now, before each label, add a div with a class of checkbox. Assign an id which is the id of the respective checkbox, followed by "_checkbox". Within each of these divs, you should have a span element containing "&checkmark;". In the HTML character table, this translates to ✓. A tick!

For a full listing of HTML special characters, here's a link. (https://dev.w3.org/html5/html-author/charref)

        <div class="checkbox_wrapper">
            <div class="checkbox" id="cbPrint_checkbox">
                <span>&checkmark;</span>
            </div>
            <label for="cbPrint">Print</label>
            <input type="checkbox" name="cbPrint" id="cbPrint" value="print" checked>
        </div>

        <br />

        <div class="checkbox_wrapper">
            <div class="checkbox"  id="cbEmail_checkbox">
                <span>&checkmark;</span>
            </div>
            <label for="cbEmail">Email</label>
            <input type="checkbox" name="cbEmail" id="cbEmail" value="email">
        </div>


This is what you should have...

Now style your checkboxes. We'll make it a 20 pixel by 20 pixel square, with slightly rounded corners and a dark grey outline. For good measure, we'll set the float property to left so it aligns with the label.
            .checkbox
            {
                width:20px;
                height:20px;
                border-radius:3px;
                border:1px solid #444444;               
                float:left;
            }


Coming along nicely!


Let's clean this up a little. Set the margin-left property of the labels to 1 em.
            .checkbox_wrapper label
            {
                font-size:16px;
                margin-left:1em;
            }


OK, looking less crowded now.


And here, we'll adjust the tick's span element so it sits nicely within its checkbox. We can accomplish this by setting the display property to inline-block, the width to 100% and aligning the text center. We'll also make the tick bold, and give it a nice lime green.
            .checkbox span
            {
                display:inline-block;
                width:100%;
                text-align: center;
                font-size:1em;
                color:#44FF44;
                font-weight:bold;
            }


Yep, looking presentable now.

Making stuff work

Now you have the checkboxes, but you need to make them respond. First, let's write some JavaScript.

Alter the HTML code as follows. You'll notice that we added an onclick event which calls the checkbox() function, passing in the id of the checkbox as an argument. Also, each div with the class checkbox has had an additional class added to it, either on or off depending on whether the checkbox is checked. This will be significant soon.
        <div class="checkbox_wrapper" onclick="checkbox('cbPrint')">
            <div class="checkbox on" id="cbPrint_checkbox">
                <span>&checkmark;</span>
            </div>
            <label for="cbPrint">Print</label>
            <input type="checkbox" name="cbPrint" id="cbPrint" value="print" checked>
        </div>

        <br />

        <div class="checkbox_wrapper" onclick="checkbox('cbEmail')">
            <div class="checkbox off"  id="cbEmail_checkbox">
                <span>&checkmark;</span>
            </div>
            <label for="cbEmail">Email</label>
            <input type="checkbox" name="cbEmail" id="cbEmail" value="email">
        </div>


And write the checkbox() function. First, grab the div that we styled, using the id and the string "_checkbox".
        <script>
            function checkbox(id)
            {
                var cb = document.getElementById(id + "_checkbox");
            }
        </script>


Next, check if it's checked by accessing its className property.
        <script>
            function checkbox(id)
            {
                var cb = document.getElementById(id + "_checkbox");

                if (cb.className=="checkbox on")
                {

                }
                else
                {

                }
            }
        </script>


If it's checked, set its class to "checkbox off" and ensure that the respective checkbox is unchecked. Do the opposite if it's not checked.
        <script>
            function checkbox(id)
            {
                var cb = document.getElementById(id + "_checkbox");

                if (cb.className=="checkbox on")
                {
                    cb.className = "checkbox off";
                    document.getElementById(id).checked = false;
                }
                else
                {
                    cb.className = "checkbox on";
                    document.getElementById(id).checked = true;
                }
            }
        </script>

Time to test!

Click on the labels or styled checkboxes. Do the original checkboxes respond? They should. We have a problem though... the styled checkboxes themselves aren't responding.

This is because we haven't added styles for On and Off states. Let's fix this. For the Off state, span disappears. For the On state, span is visible.
            .checkbox span
            {
                display:inline-block;
                width:100%;
                text-align: center;
                font-size:1em;
                color:#44FF44;
                font-weight:bold;
            }

            .checkbox.off span
            {
                display:none;
            }

            .checkbox.on span
            {   
                display:inline-block;
            }


And here you go!


One final touch. Hide the checkboxes.
            .checkbox_wrapper input
            {
                display:none;
            }


Voila.

Try it here...





Isn't that an awful lot of trouble?

Well yeah, no shit. These are the hoops HTML/CSS makes you jump through to style textboxes. Still, if you want a nicer-looking UI, this is what it takes.

It's worth noting that many CSS frameworks such as Semantic UI already do this for you, and all the styling and JavaScript has already been written in the package. But nothing like learning how to do it yourself, hey?

That's all. ✓ back for more! (snicker)
T___T

No comments:

Post a Comment