From dcfb172704f3afb68a30425029ec834be2883274 Mon Sep 17 00:00:00 2001 From: bt Date: Sat, 8 Jun 2024 13:22:19 -0400 Subject: More content porting, on-going markdown changes for lowdown support --- build/dynamic-checkboxes/index.html | 310 ++++++++++++++++++++---------------- 1 file changed, 175 insertions(+), 135 deletions(-) (limited to 'build/dynamic-checkboxes') diff --git a/build/dynamic-checkboxes/index.html b/build/dynamic-checkboxes/index.html index 9adb9f2..e23448b 100644 --- a/build/dynamic-checkboxes/index.html +++ b/build/dynamic-checkboxes/index.html @@ -1,131 +1,155 @@ - + Dynamic Checkboxes - - + + +
-

Dynamic Checkboxes

+

Dynamic Checkboxes

+

2019-07-30

-

Checkboxes are used quite frequently on forms across the web. Whether you're selecting a pricing plan during a site's sign-up process or just simply selecting to opt-out from a newsletter, you have most likely interacted with some form of checkbox element.

-

What if we could make everyday checkboxes more beautiful and more intuitive? It's easier than you think. We only need a small amount of CSS and JavaScript to make considerable improvements to your average checkbox UX.

-

Let's get into it.

-

What we are building

+ +

Checkboxes are used quite frequently on forms across the web. Whether you’re selecting a pricing plan during a site’s sign-up process or just simply selecting to opt-out from a newsletter, you have most likely interacted with some form of checkbox element.

+ +

What if we could make everyday checkboxes more beautiful and more intuitive? It’s easier than you think. We only need a small amount of CSS and JavaScript to make considerable improvements to your average checkbox UX.

+ +

Let’s get into it.

+ +

What we are building

+

Take a look and play around with the CodePen below to get an idea of what we are going to build. The premise is a simple add-on pricing form which calculates the additional monthly total to the user in real-time.

+

Live CodePen Example

-

The Structure (HTML)

-

As always, we will start by breaking down the "bones" of the HTML structure for this checkbox form. Let's take a look at the HTML in it's entirety (don't worry, it is a lot more simple than it seems at first glance):

-
<h2>Add-ons</h2>
 
-<input class="checkbox-btn" name="checkbox-collection" id="checkbox-1" type="checkbox" value="49">
-<label class="checkbox-label" for="checkbox-1">
-    <span>
+

The Structure (HTML)

+ +

As always, we will start by breaking down the “bones” of the HTML structure for this checkbox form. Let’s take a look at the HTML in it’s entirety (don’t worry, it is a lot more simple than it seems at first glance):

+ +
<h2>Add-ons</h2>
+
+<input class="checkbox-btn" name="checkbox-collection" id="checkbox-1" type="checkbox" value="49">
+<label class="checkbox-label" for="checkbox-1">
+    <span>
         White-labeled Domain
-        <em>Use your own custom domain with SSL security included.</em>
-    </span>
-    <span>$49/mo</span>
-</label>
-
-<input class="checkbox-btn" name="checkbox-collection" id="checkbox-2" type="checkbox" value="49">
-<label class="checkbox-label" for="checkbox-2">
-    <span>
+        <em>Use your own custom domain with SSL security included.</em>
+    </span>
+    <span>$49/mo</span>
+</label>
+
+<input class="checkbox-btn" name="checkbox-collection" id="checkbox-2" type="checkbox" value="49">
+<label class="checkbox-label" for="checkbox-2">
+    <span>
         API Access
-        <em>Make API calls to perform custom serving and account actions.</em>
-    </span>
-    <span>$49/mo</span>
-</label>
-
-<input class="checkbox-btn" name="checkbox-collection" id="checkbox-3" type="checkbox" value="349">
-<label class="checkbox-label" for="checkbox-3">
-    <span>
+        <em>Make API calls to perform custom serving and account actions.</em>
+    </span>
+    <span>$49/mo</span>
+</label>
+
+<input class="checkbox-btn" name="checkbox-collection" id="checkbox-3" type="checkbox" value="349">
+<label class="checkbox-label" for="checkbox-3">
+    <span>
         Priority Support
-        <em>A dedicated account manager to assist your team with ongoing deployments.</em>
-    </span>
-    <span>$349/mo</span>
-</label>
-
-<div class="total-cost">
-    <h2>Your Plan</h2>
-    <div>
-        <span>$</span>
-        <span id="total-cost-inner">0</span>
-        <input id="output" type="text" value="0" disabled/>
-        <span>/mo</span>
-    </div>
-</div>
+        <em>A dedicated account manager to assist your team with ongoing deployments.</em>
+    </span>
+    <span>$349/mo</span>
+</label>
+
+<div class="total-cost">
+    <h2>Your Plan</h2>
+    <div>
+        <span>$</span>
+        <span id="total-cost-inner">0</span>
+        <input id="output" type="text" value="0" disabled/>
+        <span>/mo</span>
+    </div>
+</div>
 
-

The checkbox inputs & labels

-
<!-- #1 -->
-<input class="checkbox-btn" name="checkbox-collection" id="checkbox-1" type="checkbox" value="49">
 
-<!-- #2 -->
-<label class="checkbox-label" for="checkbox-1">
+

The checkbox inputs & labels

- <!-- #2i --> - <span> +
<!-- #1 -->
+<input class="checkbox-btn" name="checkbox-collection" id="checkbox-1" type="checkbox" value="49">
+
+<!-- #2 -->
+<label class="checkbox-label" for="checkbox-1">
+
+    <!-- #2i -->
+    <span>
         White-labeled Domain
-        <em>Use your own custom domain with SSL security included.</em>
-    </span>
-    
-    <!-- #2ii -->
-    <span>$49/mo</span>
+        <em>Use your own custom domain with SSL security included.</em>
+    </span>
+
+    <!-- #2ii -->
+    <span>$49/mo</span>
 
-</label>
+</label>
 
+
    -
  1. This input will be hidden via position:absolute by default. All checkbox inputs need to share the same name value and all checkboxes require their our custom id that will link with the corresponding for value on the label.

    -
  2. -
  3. This label needs it's for value to correspond with it's partnered checkbox.
  4. +
  5. This input will be hidden via position:absolute by default. All checkbox inputs need to share the same name value and all checkboxes require their our custom id that will link with the corresponding for value on the label.

  6. +
  7. This label needs it’s for value to correspond with it’s partnered checkbox.

    + +
      +
    • i) The first span holds the title and description information of the add-on
    • +
    • ii) The last span holds the cost associated with the current add-on
    • +
-

- i) The first span holds the title and description information of the add-on - - ii) The last span holds the cost associated with the current add-on

-

The total cost container output

-
<!-- #1 -->
-<div class="total-cost">
 
-    <h2>Your Plan</h2>
+

The total cost container output

- <!-- #2 --> - <div> +
<!-- #1 -->
+<div class="total-cost">
 
-        <!-- #2i -->
-        <span>$</span>
+    <h2>Your Plan</h2>
 
-        <!-- #2ii -->
-        <span id="total-cost-inner">0</span>
+    <!-- #2 -->
+    <div>
 
-        <!-- #2iii -->
-        <input id="output" type="text" value="0" disabled/>
+        <!-- #2i -->
+        <span>$</span>
 
-        <!-- #2iv -->
-        <span>/mo</span>
+        <!-- #2ii -->
+        <span id="total-cost-inner">0</span>
 
-    </div>
+        <!-- #2iii -->
+        <input id="output" type="text" value="0" disabled/>
 
-</div>
+        <!-- #2iv -->
+        <span>/mo</span>
+
+    </div>
+
+</div>
 
+
    -
  1. A simple div with a class we can easily target later

    -
  2. -
  3. A div parent container is needed to house all the total spans together (more on this when we get into the CSS) - - i) The first span holds the static currency symbol - - ii) The second span is where our updated cost will be injected - - iii) This input field is required for us to take-in the value of the associated :checked inputs and add them together. This current value is then used for the injection into the second span - - iv) The final span simply holds the static monthly duration content

    -
  4. +
  5. A simple div with a class we can easily target later

  6. +
  7. A div parent container is needed to house all the total spans together (more on this when we get into the CSS)

    + +
      +
    • i) The first span holds the static currency symbol
    • +
    • ii) The second span is where our updated cost will be injected
    • +
    • iii) This input field is required for us to take-in the value of the associated :checked inputs and add them together. This current value is then used for the injection into the second span
    • +
    • iv) The final span simply holds the static monthly duration content
    • +
-

All that's all we need for the HTML!

-

The Visuals (CSS)

+ +

All that’s all we need for the HTML!

+ +

The Visuals (CSS)

+

Again, lets take a look at the entire file before we break it down step-by-step:

+
.checkbox-label {
     align-items: center;
     background-color: none;
@@ -153,7 +177,7 @@
     background-size: 15px;
     border: 1px solid lightgrey;
     border-radius: 50%;
-    content:'';
+    content:'';
     height: 30px;
     left: 20px;
     position: absolute;
@@ -163,7 +187,7 @@
 }
 .checkbox-label:hover:before {
     background-image:
-        url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="23.571429" height="23.571429" viewBox="0.000000 -47.142857 23.571429 23.571429"><path fill="lightgrey" d="M23.571429 -36.964286L23.571429 -33.750000C23.571429 -33.303571 23.415179 -32.924107 23.102679 -32.611607C22.790179 -32.299107 22.410714 -32.142857 21.964286 -32.142857L15.000000 -32.142857L15.000000 -25.178571C15.000000 -24.732143 14.843750 -24.352679 14.531250 -24.040179C14.218750 -23.727679 13.839286 -23.571429 13.392857 -23.571429L10.178571 -23.571429C9.732143 -23.571429 9.352679 -23.727679 9.040179 -24.040179C8.727679 -24.352679 8.571429 -24.732143 8.571429 -25.178571L8.571429 -32.142857L1.607143 -32.142857C1.160714 -32.142857 0.781250 -32.299107 0.468750 -32.611607C0.156250 -32.924107 0.000000 -33.303571 0.000000 -33.750000L0.000000 -36.964286C0.000000 -37.410714 0.156250 -37.790179 0.468750 -38.102679C0.781250 -38.415179 1.160714 -38.571429 1.607143 -38.571429L8.571429 -38.571429L8.571429 -45.535714C8.571429 -45.982143 8.727679 -46.361607 9.040179 -46.674107C9.352679 -46.986607 9.732143 -47.142857 10.178571 -47.142857L13.392857 -47.142857C13.839286 -47.142857 14.218750 -46.986607 14.531250 -46.674107C14.843750 -46.361607 15.000000 -45.982143 15.000000 -45.535714L15.000000 -38.571429L21.964286 -38.571429C22.410714 -38.571429 22.790179 -38.415179 23.102679 -38.102679C23.415179 -37.790179 23.571429 -37.410714 23.571429 -36.964286ZM23.571429 -36.964286"></path></svg>');
+        url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="23.571429" height="23.571429" viewBox="0.000000 -47.142857 23.571429 23.571429"><path fill="lightgrey" d="M23.571429 -36.964286L23.571429 -33.750000C23.571429 -33.303571 23.415179 -32.924107 23.102679 -32.611607C22.790179 -32.299107 22.410714 -32.142857 21.964286 -32.142857L15.000000 -32.142857L15.000000 -25.178571C15.000000 -24.732143 14.843750 -24.352679 14.531250 -24.040179C14.218750 -23.727679 13.839286 -23.571429 13.392857 -23.571429L10.178571 -23.571429C9.732143 -23.571429 9.352679 -23.727679 9.040179 -24.040179C8.727679 -24.352679 8.571429 -24.732143 8.571429 -25.178571L8.571429 -32.142857L1.607143 -32.142857C1.160714 -32.142857 0.781250 -32.299107 0.468750 -32.611607C0.156250 -32.924107 0.000000 -33.303571 0.000000 -33.750000L0.000000 -36.964286C0.000000 -37.410714 0.156250 -37.790179 0.468750 -38.102679C0.781250 -38.415179 1.160714 -38.571429 1.607143 -38.571429L8.571429 -38.571429L8.571429 -45.535714C8.571429 -45.982143 8.727679 -46.361607 9.040179 -46.674107C9.352679 -46.986607 9.732143 -47.142857 10.178571 -47.142857L13.392857 -47.142857C13.839286 -47.142857 14.218750 -46.986607 14.531250 -46.674107C14.843750 -46.361607 15.000000 -45.982143 15.000000 -45.535714L15.000000 -38.571429L21.964286 -38.571429C22.410714 -38.571429 22.790179 -38.415179 23.102679 -38.102679C23.415179 -37.790179 23.571429 -37.410714 23.571429 -36.964286ZM23.571429 -36.964286"></path></svg>');
 }
 .checkbox-label span {
     -webkit-user-select: none;
@@ -189,7 +213,7 @@
 .checkbox-btn:checked + .checkbox-label:before {
     background-color: mediumpurple;
     background-image:
-        url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="25.948661" height="19.888393" viewBox="2.025670 -40.011161 25.948661 19.888393"><path fill="white" d="M27.974330 -36.127232C27.974330 -35.680804 27.818080 -35.301339 27.505580 -34.988839L15.385045 -22.868304L13.108259 -20.591518C12.795759 -20.279018 12.416295 -20.122768 11.969866 -20.122768C11.523438 -20.122768 11.143973 -20.279018 10.831473 -20.591518L8.554688 -22.868304L2.494420 -28.928571C2.181920 -29.241071 2.025670 -29.620536 2.025670 -30.066964C2.025670 -30.513393 2.181920 -30.892857 2.494420 -31.205357L4.771205 -33.482143C5.083705 -33.794643 5.463170 -33.950893 5.909598 -33.950893C6.356027 -33.950893 6.735491 -33.794643 7.047991 -33.482143L11.969866 -28.543527L22.952009 -39.542411C23.264509 -39.854911 23.643973 -40.011161 24.090402 -40.011161C24.536830 -40.011161 24.916295 -39.854911 25.228795 -39.542411L27.505580 -37.265625C27.818080 -36.953125 27.974330 -36.573661 27.974330 -36.127232ZM27.974330 -36.127232"></path></svg>');
+        url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="25.948661" height="19.888393" viewBox="2.025670 -40.011161 25.948661 19.888393"><path fill="white" d="M27.974330 -36.127232C27.974330 -35.680804 27.818080 -35.301339 27.505580 -34.988839L15.385045 -22.868304L13.108259 -20.591518C12.795759 -20.279018 12.416295 -20.122768 11.969866 -20.122768C11.523438 -20.122768 11.143973 -20.279018 10.831473 -20.591518L8.554688 -22.868304L2.494420 -28.928571C2.181920 -29.241071 2.025670 -29.620536 2.025670 -30.066964C2.025670 -30.513393 2.181920 -30.892857 2.494420 -31.205357L4.771205 -33.482143C5.083705 -33.794643 5.463170 -33.950893 5.909598 -33.950893C6.356027 -33.950893 6.735491 -33.794643 7.047991 -33.482143L11.969866 -28.543527L22.952009 -39.542411C23.264509 -39.854911 23.643973 -40.011161 24.090402 -40.011161C24.536830 -40.011161 24.916295 -39.854911 25.228795 -39.542411L27.505580 -37.265625C27.818080 -36.953125 27.974330 -36.573661 27.974330 -36.127232ZM27.974330 -36.127232"></path></svg>');
     border-color: mediumpurple;
 }
 
@@ -228,11 +252,13 @@
     }
 }
 
-

The checkbox label

-
/*
-This is the main element for each checkbox "container".
+
+

The checkbox label

+ +
/*
+This is the main element for each checkbox "container".
 Inside it houses the title, description and price.
-*/
+*/
 .checkbox-label {
     align-items: center;
     background-color: none;
@@ -252,29 +278,32 @@ Inside it houses the title, description and price.
     background-color: rgba(255,255,255,0.2);
 }
 
-/* Update the label styling when the input is :checked */
+/* Update the label styling when the input is :checked */
 .checkbox-btn:checked + .checkbox-label {
     background-color: white;
     border-color: mediumpurple;
     box-shadow: 0 2px 4px rgba(0,0,0,0.05);
 }
 
-

The custom checkbox input

-

We need to hide the browser's default checkbox input and replace it with our own using pseudo selectors.

-
/* Hide browser default input */
+
+

The custom checkbox input

+ +

We need to hide the browser’s default checkbox input and replace it with our own using pseudo selectors.

+ +
/* Hide browser default input */
 .checkbox-btn {
     position: absolute;
     visibility: hidden;
 }
 
-/* Our custom input checkbox */
+/* Our custom input checkbox */
 .checkbox-label:before {
     background-repeat: no-repeat;
     background-position: center;
     background-size: 15px;
     border: 1px solid lightgrey;
     border-radius: 50%;
-    content:'';
+    content:'';
     height: 30px;
     left: 20px;
     position: absolute;
@@ -283,30 +312,33 @@ Inside it houses the title, description and price.
     width: 30px;
 }
 
-/*
-Here we add a simple '+' icon on hover
+/*
+Here we add a simple '+' icon on hover
 to our custom pseudo element.
 Adding it as an inline SVG gives us the
-ability to fully customize it's styling
-*/
+ability to fully customize it's styling
+*/
 .checkbox-label:hover:before {
     background-image:
-        url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="23.571429" height="23.571429" viewBox="0.000000 -47.142857 23.571429 23.571429"><path fill="lightgrey" d="M23.571429 -36.964286L23.571429 -33.750000C23.571429 -33.303571 23.415179 -32.924107 23.102679 -32.611607C22.790179 -32.299107 22.410714 -32.142857 21.964286 -32.142857L15.000000 -32.142857L15.000000 -25.178571C15.000000 -24.732143 14.843750 -24.352679 14.531250 -24.040179C14.218750 -23.727679 13.839286 -23.571429 13.392857 -23.571429L10.178571 -23.571429C9.732143 -23.571429 9.352679 -23.727679 9.040179 -24.040179C8.727679 -24.352679 8.571429 -24.732143 8.571429 -25.178571L8.571429 -32.142857L1.607143 -32.142857C1.160714 -32.142857 0.781250 -32.299107 0.468750 -32.611607C0.156250 -32.924107 0.000000 -33.303571 0.000000 -33.750000L0.000000 -36.964286C0.000000 -37.410714 0.156250 -37.790179 0.468750 -38.102679C0.781250 -38.415179 1.160714 -38.571429 1.607143 -38.571429L8.571429 -38.571429L8.571429 -45.535714C8.571429 -45.982143 8.727679 -46.361607 9.040179 -46.674107C9.352679 -46.986607 9.732143 -47.142857 10.178571 -47.142857L13.392857 -47.142857C13.839286 -47.142857 14.218750 -46.986607 14.531250 -46.674107C14.843750 -46.361607 15.000000 -45.982143 15.000000 -45.535714L15.000000 -38.571429L21.964286 -38.571429C22.410714 -38.571429 22.790179 -38.415179 23.102679 -38.102679C23.415179 -37.790179 23.571429 -37.410714 23.571429 -36.964286ZM23.571429 -36.964286"></path></svg>');
+        url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="23.571429" height="23.571429" viewBox="0.000000 -47.142857 23.571429 23.571429"><path fill="lightgrey" d="M23.571429 -36.964286L23.571429 -33.750000C23.571429 -33.303571 23.415179 -32.924107 23.102679 -32.611607C22.790179 -32.299107 22.410714 -32.142857 21.964286 -32.142857L15.000000 -32.142857L15.000000 -25.178571C15.000000 -24.732143 14.843750 -24.352679 14.531250 -24.040179C14.218750 -23.727679 13.839286 -23.571429 13.392857 -23.571429L10.178571 -23.571429C9.732143 -23.571429 9.352679 -23.727679 9.040179 -24.040179C8.727679 -24.352679 8.571429 -24.732143 8.571429 -25.178571L8.571429 -32.142857L1.607143 -32.142857C1.160714 -32.142857 0.781250 -32.299107 0.468750 -32.611607C0.156250 -32.924107 0.000000 -33.303571 0.000000 -33.750000L0.000000 -36.964286C0.000000 -37.410714 0.156250 -37.790179 0.468750 -38.102679C0.781250 -38.415179 1.160714 -38.571429 1.607143 -38.571429L8.571429 -38.571429L8.571429 -45.535714C8.571429 -45.982143 8.727679 -46.361607 9.040179 -46.674107C9.352679 -46.986607 9.732143 -47.142857 10.178571 -47.142857L13.392857 -47.142857C13.839286 -47.142857 14.218750 -46.986607 14.531250 -46.674107C14.843750 -46.361607 15.000000 -45.982143 15.000000 -45.535714L15.000000 -38.571429L21.964286 -38.571429C22.410714 -38.571429 22.790179 -38.415179 23.102679 -38.102679C23.415179 -37.790179 23.571429 -37.410714 23.571429 -36.964286ZM23.571429 -36.964286"></path></svg>');
 }
 
-/*
+/*
 When the checkbox input is :checked we need to
 update the inline SVG to use a checkmark symbol
-*/
+*/
 .checkbox-btn:checked + .checkbox-label:before {
     background-color: mediumpurple;
     background-image:
-        url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="25.948661" height="19.888393" viewBox="2.025670 -40.011161 25.948661 19.888393"><path fill="white" d="M27.974330 -36.127232C27.974330 -35.680804 27.818080 -35.301339 27.505580 -34.988839L15.385045 -22.868304L13.108259 -20.591518C12.795759 -20.279018 12.416295 -20.122768 11.969866 -20.122768C11.523438 -20.122768 11.143973 -20.279018 10.831473 -20.591518L8.554688 -22.868304L2.494420 -28.928571C2.181920 -29.241071 2.025670 -29.620536 2.025670 -30.066964C2.025670 -30.513393 2.181920 -30.892857 2.494420 -31.205357L4.771205 -33.482143C5.083705 -33.794643 5.463170 -33.950893 5.909598 -33.950893C6.356027 -33.950893 6.735491 -33.794643 7.047991 -33.482143L11.969866 -28.543527L22.952009 -39.542411C23.264509 -39.854911 23.643973 -40.011161 24.090402 -40.011161C24.536830 -40.011161 24.916295 -39.854911 25.228795 -39.542411L27.505580 -37.265625C27.818080 -36.953125 27.974330 -36.573661 27.974330 -36.127232ZM27.974330 -36.127232"></path></svg>');
+        url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="25.948661" height="19.888393" viewBox="2.025670 -40.011161 25.948661 19.888393"><path fill="white" d="M27.974330 -36.127232C27.974330 -35.680804 27.818080 -35.301339 27.505580 -34.988839L15.385045 -22.868304L13.108259 -20.591518C12.795759 -20.279018 12.416295 -20.122768 11.969866 -20.122768C11.523438 -20.122768 11.143973 -20.279018 10.831473 -20.591518L8.554688 -22.868304L2.494420 -28.928571C2.181920 -29.241071 2.025670 -29.620536 2.025670 -30.066964C2.025670 -30.513393 2.181920 -30.892857 2.494420 -31.205357L4.771205 -33.482143C5.083705 -33.794643 5.463170 -33.950893 5.909598 -33.950893C6.356027 -33.950893 6.735491 -33.794643 7.047991 -33.482143L11.969866 -28.543527L22.952009 -39.542411C23.264509 -39.854911 23.643973 -40.011161 24.090402 -40.011161C24.536830 -40.011161 24.916295 -39.854911 25.228795 -39.542411L27.505580 -37.265625C27.818080 -36.953125 27.974330 -36.573661 27.974330 -36.127232ZM27.974330 -36.127232"></path></svg>');
     border-color: mediumpurple;
 }
 
-

The total cost container

-

We only need some very basic flexbox styling for our bottom "total" container:

+ +

The total cost container

+ +

We only need some very basic flexbox styling for our bottom “total” container:

+
.total-cost {
     align-items: baseline;
     border-top: 1px solid lightgrey;
@@ -328,21 +360,24 @@ update the inline SVG to use a checkmark symbol
     font-weight: bold;
 }
 
-/*
+/*
 This input is used in our JavaScript - look at the
 function part of this post to understand why
-*/
+*/
 .total-cost input {
     display: none;
 }
 
-

Last but not least - mobile

+ +

Last but not least - mobile

+

Now we just ensure that on smaller devices our checkbox labels render nicely:

+
@media(max-width:480px) {
-    /*
+    /*
     Avoids the inner label content from squishing together
     and becoming unreadable
-    */
+    */
     .checkbox-label {
         align-items: flex-start;
         flex-direction: column;
@@ -353,39 +388,44 @@ function part of this post to understand why
     }
 }
 
-

That's it for the styling!

-

The Function (JS)

-

As you can see below, we only need a very minor amount of JavaScript to accomplish our total cost "injection".

+ +

That’s it for the styling!

+ +

The Function (JS)

+ +

As you can see below, we only need a very minor amount of JavaScript to accomplish our total cost “injection”.

+
window.onload=function(){
 
-// Place the default browser checkbox inputs into a variable
-var inputs = document.getElementsByClassName('checkbox-btn')
+// Place the default browser checkbox inputs into a variable
+var inputs = document.getElementsByClassName('checkbox-btn')
 
-// Now we loop through the inputs and check if they are
-// greater than zero. If so, we run our function.
-for (var i=0; i < inputs.length; i++) {
+// Now we loop through the inputs and check if they are
+// greater than zero. If so, we run our function.
+for (var i=0; i < inputs.length; i++) {
 
     inputs[i].onchange = function() {
 
-        // Create `add` variable which takes the :checked input value
+        // Create `add` variable which takes the :checked input value
         var add = this.value * (this.checked ? 1 : -1);
 
-        // We grab the current total value on our hidden input field and return it
-        // as a floating point number
-        // (since in this use case it will be a price number based on currency)
-        var new_total = parseFloat(document.getElementById('output').value);
+        // We grab the current total value on our hidden input field and return it
+        // as a floating point number
+        // (since in this use case it will be a price number based on currency)
+        var new_total = parseFloat(document.getElementById('output').value);
 
-        // Now we simply add the existing total value with the newly ":checked" input value
-        var updated_total = document.getElementById('output').value=new_total + add
+        // Now we simply add the existing total value with the newly ":checked" input value
+        var updated_total = document.getElementById('output').value=new_total + add
 
-        // Place the new updated total directly inside the `total-cost-inner` span element
-        document.getElementById('total-cost-inner').innerHTML = updated_total;
+        // Place the new updated total directly inside the `total-cost-inner` span element
+        document.getElementById('total-cost-inner').innerHTML = updated_total;
     }
 
 }
 }
 
-

That's it! Feel free to play with the demo some more at the top of the post, or check out the CodePen source directly.

+ +

That’s it! Feel free to play with the demo some more at the top of the post, or check out the CodePen source directly.