J47h.putty PDocsWeb Development
Related
Mastering Explicit Compile Hints in V8: A Step-by-Step Guide to Faster JavaScript StartupHow to Add Structured Data to Your Web Pages for Better Machine ReadabilityCopilot Studio Boosts Performance with .NET 10 WebAssembly UpgradeWeb Developer Curates Top CSS Color Palettes After Abandoning TailwindMicrosoft Copilot Studio Gets Massive Speed Boost with .NET 10 WebAssembly UpgradeSpeed Up Web Page Loading: A Guide to Using V8's Explicit Compile Hints10 Insights into the Web's Structure Problem and How the Block Protocol Offers a SolutionChoosing Between CommonJS and ESM: A Practical Guide to JavaScript Module Architecture

Dynamic Price Calculations in CSS: No JavaScript Required

Last updated: 2026-05-15 14:15:59 · Web Development

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.