A Clever Shopping Cart Trick Using Radio Buttons

Editor’s note: This is a clever idea shared by Preethi, but it has accessibility drawbacks due to duplicated interactive elements. Other approaches exist, and we’ll explore one in a future article.

Whether it’s two large pizzas for yourself or twelve small ones for a kids’ party, everyone has added items to an online cart. Groceries, clothing, deli orders — it’s best when this process is simple, efficient, and perhaps a bit quirky.

This post introduces a design called infinite selection. Metaphorically infinite.

Here’s how it works:

Click an item, and it smoothly transitions into the shopping cart. You can add as many items as you want!

It’s all done in CSS, except for counting selected items, using radio form inputs in the markup.

I’ll guide you through the code, starting with the layout. Note that this is just one approach, with its own considerations and limitations.

The Layout

Each item is a wrapper containing two radio form inputs with the same name value — a radio group.

Checking one input automatically unchecks the other, creating a toggle effect.

Each item and its inputs are absolutely positioned:

.items {   
  position: absolute;

  input { 
    position: absolute; 
    inset: 0; 
  }
}

The inset property ensures the inputs are clickable without dead areas.

Arrange everything in a layout using translate to move items from the cart to a higher, spread-out position. Customize the layout as needed, ensuring radio buttons can move to the cart when selected.

.items {
  --y: 100px; /* Vertical distance from the cart */

  &:not(.cart) {
    transform: translate(var(--x), calc(-1 * var(--y)));
  }
  &.espresso { 
    --x: 0px;  /* Horizontal dist. from the cart */
  }
  &.cappuccino { 
    --x: -100%; 
  }
  &.flat-white { 
    --x: 100%; 
  }
}

Configuration is needed to fit your specific use case, involving some magic numbering.

Selecting Items

When an item () is selected (:checked), it shrinks and moves (translate) to the cart:

input:checked {
  transform: translate(calc(-1 * var(--x)), var(--y)) scale(0);
}

The second radio input in the group is checked, unchecking the first, using their shared name attribute. This boolean logic triggers the transition.

A transition animates the item moving to the cart:

input:checked{
  transform: translate(calc(-1 * var(--x)), var(--y)) scale(0);
  transition: transform .6s linear;
}

Keeping Count

This post focuses on getting a selected item to the cart. A label shows the count of added


Discover more from WIREDGORILLA

Subscribe to get the latest posts sent to your email.

Similar Posts