GifproGifpro

CSSだけで割引価格を計算するcalc()×カスタムプロパティ実装作例

CSSだけで割引価格を計算するcalc()×カスタムプロパティ実装作例

CSSだけで割引価格を計算できるのか?

ECサイトや価格表示コンポーネントで、割引率に応じた価格を表示する処理は、これまでJavaScriptの役割だった。CSS-Tricksが2026年4月に公開した記事「Computing and Displaying Discounted Prices in CSS」は、この前提を覆す。CSSの calc() 関数とカスタムプロパティ(CSS変数)を組み合わせれば、割引率と元値から税込価格までをスタイルシート上で完全に計算可能になる。

この手法の核心は「CSSはpresentation層の言語」という固定観念の打破にある。実際には、counter()attr() の進化により、CSSは単なる装飾を超えた計算能力を獲得している。2026年のBaselineにも組み込まれた最新のCSS関数群を使えば、JavaScriptのDOM操作を介さずに動的な数値表示が実現できる。

実装の基本構造:calc()とカスタムプロパティの連携

元の値(original price)と割引率(discount rate)をカスタムプロパティとして宣言し、calc() 内で演算する。

.price-card {
  --original-price: 5000;
  --discount-rate: 20;
  --discounted-price: calc(var(--original-price) - (var(--original-price) * var(--discount-rate) / 100));
  --tax-rate: 10;
  --price-with-tax: calc(var(--discounted-price) + (var(--discounted-price) * var(--tax-rate) / 100));
}

このカスタムプロパティを counter()content プロパティと組み合わせれば、HTMLに数値を埋め込むことなく表示できる。

表示ロジック:contentプロパティの高度な活用

CSSで計算した値を画面に描画するには、擬似要素の contentcounter() を使う。ただし、counter() は数値のみを扱うため、通貨記号や小数点のフォーマットは別途工夫が必要だ。

.price-card::after {
  counter-reset: price var(--price-with-tax);
  content: "¥" counter(price);
}

このコードは、税込価格を「¥5500」のように表示する。小数点以下の丸めが必要な場合は round() 関数(2026年のCSS Values Level 5で提案)を calc() 内部で使う。

実務上の落とし穴3つ

1. アクセシビリティの問題
擬似要素に表示した価格はスクリーンリーダーに正しく読まれない場合がある。補助的な aria-label や、sr-only クラスで隠したspan要素に実際の値を入れるべきだ。

2. カスタムプロパティの継承とスコープ
カスタムプロパティは親要素から子要素へ継承される。複数の価格カードが同一ページにある場合、各カードの --original-price を正しくスコープしないと、意図しない値が計算に混入する。各カードにインラインスタイルで style="--original-price: 5000" を渡すのが安全だ。

3. ブラウザ互換性
2026年4月時点で、round()mod() などの高度な数学関数はBaselineに含まれていない。Chrome 130以降、Firefox 132以降で試験的に実装されているが、Safariは未対応。calc() 内の四則演算だけに絞れば、現行の全モダンブラウザで動作する。

なぜ今、CSSでの価格計算が現実的なのか

これまでCSSで数値計算が敬遠されてきた理由は、動的なデータをCSSに渡す手段が限られていたからだ。HTML属性の値をCSSに渡す attr() 関数は、content プロパティ以外では使えなかった。しかし、CSS Houdiniの CSS.registerProperty() によって、カスタムプロパティに型(数値)を与えられるようになった。これで calc() 内で安全に演算できる基盤が整った。

さらに、2026年2月のBaseline digeestで calc() のネスト対応が全ブラウザで利用可能になった。これにより、複雑な割引計算式を1行のCSSで書ける。JavaScriptを使わない価格表示は、特に静的サイトジェネレーターやJamstack構成で威力を発揮する。SSR時に価格をHTMLに焼き込まず、CSS側で計算する設計にすれば、APIから取得した価格データをクライアントサイドで動的に調整できる。

他の手法との比較

同じ割引価格表示を実現する手段として、JavaScriptでのDOM書き換えや、サーバーサイドでのHTML生成がある。CSS方式の利点は、再計算のトリガーがスタイル変更だけになる点だ。JavaScriptのようにDOMイベントを監視する必要がなく、CSS変数の変更(例:テーマ切替えや割引率の動的変更)に連動して自動で再描画される。パフォーマンス面では、calc() の計算はコンポジットスレッドで処理されるため、メインスレッドをブロックしない。

逆に、価格データを外部APIから非同期で取得するようなケースでは、CSS方式は不向きだ。その場合は、JavaScriptでカスタムプロパティを動的に設定するハイブリッド方式が現実的になる。

展望:CSSが計算レイヤーになる未来

CSS-Tricksの記事は、価格表示という具体的なユースケースを通じて、CSSの計算能力を再評価させた。今後、attr() の全プロパティ対応や、random() 関数の導入により、CSS単体で動的UIの大部分をカバーできるようになるだろう。ただし、あくまで「表示ロジック」に特化すべきで、状態管理や複雑なビジネスロジックはJavaScriptに委ねるのが健全だ。

2026年春、CSSは「スタイルシート」から「表現レイヤーのための計算環境」へと進化している。開発者はこの流れを捉え、適材適所でCSSの計算機能を使い分ける技術を磨く必要がある。

参照

理人と理子

この記事を書いた人

理人と理子

ギフプロのブログを運営している理人(リト)と理子(リコ)です!理は知性を表す漢字でもあるので、AIを連想させる名前にしてもらいました。ブログの内容はAIで作成しているところもありますが、読者の方にとって有意義な情報になるように完全自動化ではなく、人の目も通して作成しています!

首页ヘルプ