SASS Toggles: Homework Notebook

Lesson: SASS Toggles (ocs__toggle) Contents: Popcorn Hacks (fill in the blanks, find the bug, customize the color), Homework: a working interactive toggle dashboard.

Popcorn Hack 1: Fill in the Blanks

  1. The checkbox on a toggle keeps track of whether it is on or off.
  2. The slider is the visible part of the toggle that changes color when it is turned on.
  3. The .switch class controls the toggle’s position, size, padding, and alignment.
  4. The border-radius property makes the slider have rounded edges.
  5. The &:before class dictates the white circle of the toggle.

Output: all five answers match the answer key (checkbox, slider, alignment, border-radius, white circle).

Popcorn Hack 2: Find the Bug!

The toggle was missing one SASS class: the track <span> had an empty class="". Fix: class="ocs__toggle-track" (with aria-hidden="true" because the track is decorative).

Expected result: Toggle works! πŸŽ‰

View example code
<div id="bug-output">
  <label class="ocs__toggle ocs__toggle--green">
    <input id="bug-toggle" class="ocs__toggle-input" type="checkbox">
    <span class="ocs__toggle-track" aria-hidden="true"></span>
    <span class="ocs__toggle-label">Enable Notifications</span>
  </label>
  <p id="bug-result" style="margin-top: 12px; font-weight: 600;"></p>
</div>
<script>
  // Check whether the correct class exists
  const bugResult = document.getElementById("bug-result");
  if (document.querySelector("#bug-output .ocs__toggle-track")) {
    bugResult.textContent = "Toggle works! πŸŽ‰";
  } else {
    bugResult.textContent = "Incorrect, almost there!";
  }
</script>

Popcorn Hack 3: Customize the Toggle

I changed the checked color from green #22C55E to purple #8B5CF6 (from the hex-code table).

View example code
<style>
.custom .ocs__toggle-input:checked + .ocs__toggle-track {
  background: #8B5CF6;
}
</style>

<div class="custom">
  <label class="ocs__toggle">
    <input class="ocs__toggle-input" type="checkbox">
    <span class="ocs__toggle-track" aria-hidden="true"></span>
    <span class="ocs__toggle-label">My Custom Toggle</span>
  </label>
</div>

Homework: My Interactive Toggle Dashboard

Requirements checklist

  • 4 toggles built with ocs__toggle, each with its own label and purpose (daily tip, dark panel, notifications, mascot)
  • JavaScript checks every toggle with .checked and updates the page
  • A live counter shows how many toggles are on, and updates on every flip
  • Comments explain what I learned and what I wondered (more than 2)
  • Above and beyond: each toggle controls a real feature (show/hide a tip, restyle the panel, change the notification message, show/hide a mascot)
View example code
<style>
  /* .panel changes look when the dark toggle is on (JS adds/removes the "dark" class) */
  .hw-panel { padding: 16px; border-radius: 12px; border: 1px solid #6B7280; background: #FFFFFF; color: #111111; max-width: 480px; }
  .hw-panel.dark { background: #1F2937; color: #F9FAFB; }
  .hw-panel label { display: block; margin: 10px 0; }
</style>

<div id="hw-panel" class="hw-panel">
  <h3>My Study Dashboard</h3>

  <!-- Toggle 1: shows or hides a study tip -->
  <label class="ocs__toggle ocs__toggle--green">
    <input id="hw-tip-toggle" class="ocs__toggle-input" type="checkbox">
    <span class="ocs__toggle-track" aria-hidden="true"></span>
    <span class="ocs__toggle-label">Show Study Tip</span>
  </label>

  <!-- Toggle 2: switches the whole panel between light and dark -->
  <label class="ocs__toggle ocs__toggle--green">
    <input id="hw-dark-toggle" class="ocs__toggle-input" type="checkbox">
    <span class="ocs__toggle-track" aria-hidden="true"></span>
    <span class="ocs__toggle-label">Dark Mode</span>
  </label>

  <!-- Toggle 3: changes the notification message -->
  <label class="ocs__toggle ocs__toggle--green">
    <input id="hw-notif-toggle" class="ocs__toggle-input" type="checkbox">
    <span class="ocs__toggle-track" aria-hidden="true"></span>
    <span class="ocs__toggle-label">Notifications</span>
  </label>

  <!-- Toggle 4: shows or hides a mascot -->
  <label class="ocs__toggle ocs__toggle--green">
    <input id="hw-mascot-toggle" class="ocs__toggle-input" type="checkbox">
    <span class="ocs__toggle-track" aria-hidden="true"></span>
    <span class="ocs__toggle-label">Study Buddy</span>
  </label>

  <hr>
  <p id="hw-tip" hidden>πŸ’‘ Tip: study in 25-minute blocks, then take a 5-minute break.</p>
  <p id="hw-notif-status"></p>
  <p id="hw-mascot" hidden>πŸ¦‰ Hoot hoot! I'm your study buddy.</p>

  <!-- Live counter of how many toggles are currently ON -->
  <p><strong>Toggles on:</strong> <output id="hw-count" aria-live="polite">0</output> of 4</p>
  <p id="hw-summary"></p>
</div>

<script>
  // Grab every element once, using the ids we gave them.
  const tipToggle = document.getElementById("hw-tip-toggle");
  const darkToggle = document.getElementById("hw-dark-toggle");
  const notifToggle = document.getElementById("hw-notif-toggle");
  const mascotToggle = document.getElementById("hw-mascot-toggle");

  const panel = document.getElementById("hw-panel");
  const tip = document.getElementById("hw-tip");
  const notifStatus = document.getElementById("hw-notif-status");
  const mascot = document.getElementById("hw-mascot");
  const countOutput = document.getElementById("hw-count");
  const summary = document.getElementById("hw-summary");

  const allToggles = [tipToggle, darkToggle, notifToggle, mascotToggle];

  function updateDashboard() {
    // I thought .checked was interesting because it lets JavaScript tell whether
    // the toggle is currently turned on or off (true/false) - it's just a Boolean!
    tip.hidden = !tipToggle.checked;           // hidden is also a Boolean, so ! flips it
    mascot.hidden = !mascotToggle.checked;

    // classList.toggle(name, force) adds the class when force is true and removes it when false
    panel.classList.toggle("dark", darkToggle.checked);

    // A conditional chooses which message to show - the same IF/ELSE idea from AP CSP selection
    if (notifToggle.checked) {
      notifStatus.textContent = "πŸ”” Notifications are ON: you'll get homework reminders.";
    } else {
      notifStatus.textContent = "πŸ”• Notifications are OFF.";
    }

    // Count the toggles that are on: loop over the array and add 1 for every checked box
    let on = 0;
    const names = [];
    allToggles.forEach(function (toggle) {
      if (toggle.checked) {
        on++;
        names.push(toggle.id.replace("hw-", "").replace("-toggle", ""));
      }
    });
    countOutput.textContent = on;
    summary.textContent = on === 0 ? "Everything is off." : "On: " + names.join(", ");
  }

  // Question I had: do I need a separate listener per toggle? No - the same function
  // can be attached to every toggle's "change" event, so it recalculates everything each time.
  allToggles.forEach(function (toggle) {
    toggle.addEventListener("change", updateDashboard);
  });

  updateDashboard();   // run once so the page starts in the correct state
</script>

My Study Dashboard


Toggles on: 0 of 4

What I learned

  • .checked is a Boolean that tells JavaScript whether a toggle is on, and element.hidden = !toggle.checked links the toggle straight to a feature.
  • One updateDashboard() function can be attached to every toggle’s change event, so the counter and all four features always stay in sync.
  • The SASS classes (ocs__toggle, ocs__toggle-input, ocs__toggle-track, ocs__toggle-label) handle the whole look of the switch, so my code only had to handle the logic.

Submission: publish this notebook and paste the published page link into the Link Submission form.