Problem: Three-State Checkbox with Indeterminate Animation

hard
40 min
Try to create a three-state checkbox that visually handles unchecked, checked, and indeterminate states with tick and dash animations using only CSS.

Problem description

Given an HTML page containing the following:

  • A <label> with class tri-checkbox that wraps:

    • A native <input type="checkbox" class="tri-state">

    • A <span class="checkmark"></span>

    • The text “Agree to terms”

Write CSS to:

  • Hide the native checkbox input.

  • Style .checkmark as a 20px × 20px square with a 2px solid #666 border and 4px border-radius.

  • Checked state (input:checked + .checkmark):

    • Use a blue background (#2196F3) and matching border.

    • Display a white tick mark using the ::after pseudo-element (6px × 10px), positioned inside the box.

  • Indeterminate state (input:indeterminate + .checkmark):

    • Use a gray horizontal dash (::before) centered in the box (12px × 2px).

    • Animate the dash with a pulsing scale effect using @keyframes pulse.

  • Ensure smooth transitions for background, border, and pseudo-elements.

Goal

Write CSS rules that produce a custom tri-state checkbox with these visual states:

  • Unchecked: A gray-bordered box

  • Checked: A white checkmark on a blue background

  • Indeterminate: A gray dash that pulses in place

Constraints

  • Use CSS only (no JavaScript is allowed).

  • .checkmark size should be 20px by 20px; border should be 2px solid #666; border-radius should be 4px.

  • Checked background-color should be #2196F3.

  • Checked tick should be white, drawn via ::after, with border-based tick shape.

  • Indeterminate dash should be white, 12px wide, 2px tall, centered via absolute positioning.

  • Animation should be pulse keyframes scaling dash from 0.8× to 1.2× over 1s infinite ease-in-out.

  • State selectors should be input:checked and input:indeterminate.

Sample visual output

Here’s what the output would look like:

Good luck trying the problem! If you’re unsure how to proceed, check the Solution.

Problem: Three-State Checkbox with Indeterminate Animation

hard
40 min
Try to create a three-state checkbox that visually handles unchecked, checked, and indeterminate states with tick and dash animations using only CSS.

Problem description

Given an HTML page containing the following:

  • A <label> with class tri-checkbox that wraps:

    • A native <input type="checkbox" class="tri-state">

    • A <span class="checkmark"></span>

    • The text “Agree to terms”

Write CSS to:

  • Hide the native checkbox input.

  • Style .checkmark as a 20px × 20px square with a 2px solid #666 border and 4px border-radius.

  • Checked state (input:checked + .checkmark):

    • Use a blue background (#2196F3) and matching border.

    • Display a white tick mark using the ::after pseudo-element (6px × 10px), positioned inside the box.

  • Indeterminate state (input:indeterminate + .checkmark):

    • Use a gray horizontal dash (::before) centered in the box (12px × 2px).

    • Animate the dash with a pulsing scale effect using @keyframes pulse.

  • Ensure smooth transitions for background, border, and pseudo-elements.

Goal

Write CSS rules that produce a custom tri-state checkbox with these visual states:

  • Unchecked: A gray-bordered box

  • Checked: A white checkmark on a blue background

  • Indeterminate: A gray dash that pulses in place

Constraints

  • Use CSS only (no JavaScript is allowed).

  • .checkmark size should be 20px by 20px; border should be 2px solid #666; border-radius should be 4px.

  • Checked background-color should be #2196F3.

  • Checked tick should be white, drawn via ::after, with border-based tick shape.

  • Indeterminate dash should be white, 12px wide, 2px tall, centered via absolute positioning.

  • Animation should be pulse keyframes scaling dash from 0.8× to 1.2× over 1s infinite ease-in-out.

  • State selectors should be input:checked and input:indeterminate.

Sample visual output

Here’s what the output would look like:

Good luck trying the problem! If you’re unsure how to proceed, check the Solution.