Dynamic Price Calculations in CSS: No JavaScript Required

By — min read

Introduction

CSS has evolved far beyond simple styling. With modern math functions and attribute selectors, you can perform numeric calculations directly in the browser, eliminating the need for JavaScript in many common scenarios. For example, you can calculate and display a discounted product price using only CSS — a task traditionally handled by scripts. This approach reduces page weight, improves performance, and simplifies the frontend stack.

Dynamic Price Calculations in CSS: No JavaScript Required
Source: css-tricks.com

Demo Overview: Streaming Subscription Discounts

Consider an interface showing several streaming services (Netflix, Disney+, HBO, etc.), each with a base price and an optional student discount of 20%. The user can toggle the discount for each service, and the price updates instantly — all without a single line of JavaScript. The demo relies on data-* attributes to store the original price and discount percentage, and CSS calc() with attr() to compute the final price.

Markup Structure

Each service is a list item containing a label for the service name and price, a checkbox to select the service, and another label for the discount toggle. The price element holds the base price and discount as data-price and data-discount attributes. Here’s a simplified example:

<li class="service">
  <label>
    <span>Netflix</span>
    <div class="price" data-price="7.99" data-discount="0.2">$7.99</div>
    <input type="checkbox" class="select-service">
  </label>
  <label>
    <span>Apply Student Discount (20%)</span>
    <input type="checkbox" class="apply-discount">
  </label>
</li>

The discount toggle (.apply-discount) triggers the CSS that recalculates and displays the new price.

Performing the Calculation in CSS

When the discount checkbox is checked, we first strike through the original price using text-decoration: line-through. Then we compute the discounted price with the attr() function. As of now, attr() works only with content property, but future CSS will expand it to other properties. The formula is:

Discounted Price = data-price × (1 - data-discount)

Because attr() returns a string, we use calc() with attr() inside a --custom-property. The actual implementation requires a workaround until browsers fully support attr() in calc(). The demo uses a @property custom property to perform the math:

/* When discount is active */
.service:has(.apply-discount:checked) .price {
  text-decoration: line-through;
  --discounted-value: calc(attr(data-price number) * (1 - attr(data-discount number)));
  content: "$" var(--discounted-value);
}

Note: The number type hint in attr() is part of the newer spec and not yet universally supported, so the demo uses a polyfill or alternative approach with @property and CSS custom properties.

Dynamic Price Calculations in CSS: No JavaScript Required
Source: css-tricks.com

Styling the Discounted Price

Once the discount is applied, we can style the new price separately using ::after or content. The original price remains visible but crossed out. Additional CSS can add a “Save X%” label by subtracting the discounted price from the original and formatting the difference. The demo uses a pseudo-element to insert “You save” messaging.

Considerations for Real-World Use

This technique showcases the power of modern CSS, but it relies on features that are still experimental or have limited browser support. As of 2025, attr() in calc() is not widely supported, and @property may not be present in all browsers. For production, you’d likely still use JavaScript for such calculations, but the CSS-only approach is an excellent benchmark for how the platform is evolving.

  • Performance benefits: No script execution, no reflow beyond what CSS already manages.
  • Accessibility: Ensure screen readers can interpret dynamic content changes (use role and aria-live regions if needed).
  • Fallback: Provide a static price with JavaScript enhancement layered on top.

Conclusion

CSS math is no longer limited to layout — it can compute real-world values like discounted prices. While full browser support is still maturing, experimenting with these techniques today prepares developers for a future where style and logic merge seamlessly. The streaming-service demo is just one example; similar approaches can handle progress bars, score counters, or any numeric display driven by data attributes.

To explore the full code and see it in action, check out the CodePen embed in the original article.

Tags:

Recommended

Discover More

How to Build and Run a Self-Improving AI Agent with Hermes on NVIDIA HardwareYour Ultimate Step-by-Step Guide to Easing Knee Arthritis Pain with Aerobic ExerciseReact Native 0.80 Overhauls JavaScript API: Deep Imports Deprecated, Strict TypeScript ArrivesMastering View Transitions: A Q&A GuideHow Massachusetts Locked in Cheaper Offshore Wind Power and Saved $1.4 Billion