CSSは終焉を迎える運命にあります。

2026/03/29 5:39

CSSは終焉を迎える運命にあります。

RSS: https://news.ycombinator.com/rss

要約

Japanese Translation:

この記事は、CSSのみでレンダリングを行い、ロジックには最小限のJavaScriptしか使用しない完全にプレイ可能なDOOM風ゲームをウェブブラウザ上で動かす方法を紹介しています。壁・床・天井・スプライト・弾道などを表現するために数千もの

<div>
要素が生成され、各要素はカスタムプロパティとして生のDoom座標を保持し、CSS が
hypot()
(距離)や
atan2()
(角度)といった関数で幾何学を計算します。ワールドはプレイヤーの動きに逆行するように
translate3d
rotateY
で移動されますが、CSS にはカメラオブジェクトがないためです。

床は

rotateX(90deg)
で回転し、
clip-path
(または新しい
shape()
関数)を使って任意の多角形や穴に切り取られます。テクスチャタイルはセクター全体にわたって背景位置をワールド座標に合わせて (
background-position: calc(var(--min-x)*-1px) …
) 配置されます。ドア、リフト、その他の動的要素はカスタムプロパティ上で CSS トランジションによってアニメーションし、JavaScript が状態属性を更新します。スプライトは
rotateY
でカメラに向き、
scaleX
で鏡像化したビルボードです。スプライトのアニメーションは CSS の
steps()
キーフレームで行い、攻撃・死亡フレーム用のデータ状態は JavaScript が供給します。弾道は CSS アニメーションで移動し、衝突検出はまだ JavaScript で処理されます。

照明はセクターごとに

filter: brightness(var(--light))
を使って全体的に適用され、ちらつくライトは
@property --light
を通じてアニメーションします。プロジェクトではアンカー位置決め、
@property
、および「ハッキー」な CSS‑のみのカリング手法(オフスクリーン要素を隠すために負の遅延でアニメーションを一時停止)といった実験的機能が採用されています。

数千もの 3D 転送された要素によるパフォーマンスは課題となり、著者は JavaScript で手動フラスタムカリングを実装し、条件付き

if()
のサポートが登場すれば将来的に純粋 CSS ソリューションへ移行する計画です。記事では Safari のビュー遷移による 3D フラット化、background‑image 再ラスター化の問題、コンポジタ不安定性などブラウザバグも文書化し、インラインスタイルやバグ報告といった回避策を紹介しています。

著者はより多くのロジックを純粋 CSS に移すことで JavaScript を完全に排除できる可能性があり、パフォーマンスをさらに向上させることを想定しています。成功すれば、このアプローチは軽量なブラウザベースゲームを刺激し、高度な CSS グラフィックス機能のサポートを促進し、重いエンジンを必要としない効率的なレンダリングが求められる開発者に利益をもたらすでしょう。

本文

CSS DOOM – ケーススタディ


1️⃣ なぜ純粋な CSS で DOOM を作るのか?

  • 概念実証 – ブラウザが CSS のみで描画できる限界を押し広げる。
  • パフォーマンス – 描画はブラウザの CSS エンジンだけで行い、JavaScript はゲームループのみ担当。
  • 学習体験 – 近代 CSS(三角関数・
    @property
    ・クリップ‑パス・SVG フィルタ等)がどこまで機能するかを探る。

2️⃣ コア構成

レイヤー責務
データ元の WAD から抽出した頂点、ライン定義、サイド定義、セクター。
ゲームループ(JS)物理・衝突判定・AI を計算し、カスタムプロパティ を更新。
レンダラー(CSS)三角関数(
hypot
atan2
)、変形、アニメーション、クリッピング、ライティングを実装。

JavaScript → カスタムプロパティ → CSS。


3️⃣ 幾何学とレンダリング

.wall {
    --delta-x: calc(var(--end‑x) - var(--start‑x));
    --delta-y: calc(var(--end‑y) - var(--start‑y));

    width:  calc(hypot(var(--delta‑x), var(--delta‑y)) * 1px);
    height: calc((var(--ceiling‑z) - var(--floor‑z)) * 1px);

    transform:
        translate3d(
            calc(var(--start‑x)*1px),
            calc(var(--ceiling‑z)*-1px),
            calc(var(--start‑y)*-1px)
        )
        rotateY(atan2(var(--delta‑y), var(--delta‑x)));
}
  • hypot
    /
    atan2
    で長さと角度を算出。
  • rotateX(90deg)
    で水平に配置。
  • セクター
    clip-path: polygon()
    または
    path()
    を使い、複雑な形状や穴を表現。

4️⃣ カメラ/ワールドの移動

#scene {
    translate: 0 0 var(--perspective);
    transform:
        rotateY(calc(var(--player‑angle) * -1rad))
        translate3d(
            calc(var(--player‑x)*-1px),
            calc(var(--player‑z)*1px),
            calc(var(--player‑y)*1px)
        );
}
  • プレイヤーの動きに逆行するように ワールド を移動させる → 典型的な「カメラトリック」。
  • --perspective
    は CSS の透視変形による歪みを補正。

5️⃣ テクスチャとライティング

.floor {
    background-repeat: repeat;
    background-size: 64px 64px;
    background-position:
        calc(var(--min‑x)*-1px)
        calc(var(--max‑y)*1px);
}

.wall, .floor, .sprite {
    filter: brightness(var(--light, 1));
}
  • ワールド方向に合わせたテクスチャ座標でシームレスタイル。
  • @property --light
    filter:brightness()
    を組み合わせて、セクターごとの照明とちらつきを実装。

6️⃣ JS ループなしのアニメーション

要素CSS
ドア / リフト
transition: transform 1s ease-in-out;

transform: translateY(var(--offset));
スプライト
rotateY(calc(var(--player‑angle)*1rad))
,
scaleX(var(--mirror, 1))
;
@keyframes sprite-cycle { from{background-position-x:0;} to{background-position-x:calc(var(--w)*var(--frames)*-1px);} }
弾丸
animation: projectile‑move var(--duration) linear both;
  • JavaScript はカスタムプロパティや状態属性だけを設定。

7️⃣ 高度な CSS 機能の利用

Feature用途
@property
数値アニメーション可能にする(例:
--player-z
)。
clip-path: path()
+
shape()
穴付きの複雑なセクタ形状。
filter:url(#fuzz)
SVG フィルタでシミリング・インビジブルスペクトル効果を実装。
anchor-name/position-anchor
武器や UI がステータスバーに固定されるように。
@keyframes cull-toggle
+
animation-delay
ヒント
純 CSS でのカリング(可視性を計算値で制御)。

8️⃣ パフォーマンスとカリング

  • ブラウザコンポジタは自動的に画面外要素をスキップしない → 手動カリングが必要。
  • JavaScript は数フレームごとにカリング、実験的な CSS カリングは
    cull-toggle
    アニメーションヒントで行う。
  • 深度ソートは主にブラウザ側で処理される;軽微な Z オフセットで共平面のちらつきを修正。

9️⃣ 制限とバグ

問題回避策
Safari のビュートランジションが
preserve-3d
をフラット化
3D シーンではビュー・トランジションを回避。
CSS 変数で
background-image
を再設定すると大規模な再レイアウトが発生
テクスチャ画像はインラインスタイルで設定。
Chrome のコンポジタが多くの 3D サーフェスで不安定マテリアルの複雑さを可能な限り削減。

🔚 結論

  • 純粋な CSS だけでも完全なファーストパーソンシューティングゲーム(ゲームループ以外)を描画できる。
  • 近代 CSS は、三角関数・アニメーション・クリッピング・フィルタといった強力な機能を提供し、かつ想像もされていないほどの表現力がある。
  • このプロジェクトは、ロジック(JavaScript)とレンダリング(CSS)の責務をきれいに分離する方法を示している。

CSS で DOOM を走らせることは可能か?
はい – 十分なカスタムプロパティ、アニメーション、3D トランスフォームの賢明な活用で実現できます。

同じ日のほかのニュース

一覧に戻る →

2026/03/29 2:39

GitLab の創業者は、会社を立ち上げることでがんと闘う

## Japanese Translation: **概要** 著者は、上部脊柱のT5椎骨に位置する腫瘍性骨肉腫との個人的な闘いを語ります。標準治療オプションを試みたものの適切な臨床試験が見つからない中で、著者は自身の状態に合わせた新しい診断手法と並行治療プロトコルを開発しました。また、「癌ジャーニーデッキ」と埋め込み型OpenAIフォーラムプレゼンテーションを作成し、この経験を記録しています。著者のアプローチはevenone.venturesに掲載されている企業によって支援され、さらにエリオット・ハーシュバーグによる著者の旅路についての包括的な記事や、ルクサンドラ氏が執筆した「The bureaucracy blocking the chance(機会を阻む官僚主義)」という患者優先医療実践を批判する作品も広い文脈に含まれます。治療データと詳細なタイムラインは、https://osteosarc.com/ で公開されており、データ概要ドキュメントや25 TBの読み取り可能なGoogle Cloudバケットが含まれています。著者は読者にメールリストへの登録を促し、更新情報を受け取れるよう案内しています。また、`cancer@sytse.com` で連絡を取ることもできます。

2026/03/27 23:39

オープンブースト・オン・モトローラ 88000プロセッサー

## Japanese Translation: (欠落している詳細を補完しつつ明瞭さを保つ)** ``` モトローラ 68000 ファミリーは、1990年代中頃のワークステーション(Apple、Amiga、Atari ST、Sun、HP、NeXT)や多くの産業用ボードで普及していました。 その RISC 後継機種である 88000(m88k)は、68k と PowerPC の間に導入されましたが、約 1994 年頃に期待された性能を提供できず廃止されました。m88k は二世代存在しました: • 88100 – 第1世代 CPU で、オプションの外部 88200 CMMU チップを搭載し、MVME180(20 MHz、2 本の CMMU)と MVME181 に使用されました。 • 88110 – 第2世代 CPU で、統合キャッシュ/MMU を備え、50 MHz を想定していましたが実際には約 40 MHz で販売されました。MVME187(25 MHz、デュアル CMMU、最大 64 MB)、MVME188(SMP、最大 4 CPU と 8 CMMU)、および MVME197 系列(セカンダリキャッシュ)に搭載されました。 VME バスは 32‑bit アドレス/データラインを備えたパッシブバックプレーンであり、複数ボードサポート、割り込みベクタ、オプションのスレーブマッピング、および終端要件があります。 OpenBSD のポートは 1995 年に MVME187 上で開始されました。Nivas Madhur、Steve Murphree、Marc Espie らの貢献は CVS マージ競合、アカウント停止(Theo de Raadt の関与)、GCC‑2.95 互換性問題、カーネルパニック(「align & align‑1」アサーション)および MVME188 上の不完全な SMP サポートに直面しました。ポートは 3.1‑beta スナップショットまで達成しましたが、ハードウェアエラー(VME バスロックアップ、DCAM2 コンフリクト、I²C フェイル)が未解決のまま残っています。 m88k アーキテクチャに関するドキュメントは、モトローラ AT&T System III/V、Data General DG/UX、Omron UniOS などのプロプライエタリ Unix バリアントと無料 CMU Mach コードから取得されました。メンテナー間の個人メール交換は協力、衝突解決、およびニッチなポートの保守課題を示しています。 MVME VME ボードおよび他の m88k システムのユーザーは、この OpenBSD ポートに安全性と安定性を依存しています。継続的なサポートがない場合、利用可能な OS を失うリスクがあり、新しいアーキテクチャへの移行が必要になるかもしれません。 ``` *改善された要約はすべての主要ポイントを反映し、不適切な推測を回避し、主旨を明確に提示し、曖昧または混乱を招く表現を排除しています。

2026/03/27 6:16

データのコピーやサーバーの立ち上げなしに、チーム横断でデータベースを統合する

## Japanese Translation: --- ## Summary Datahikeは、データベースのすべての状態を不変スナップショットとして保存します。各スナップショットは、ノードがコンテンツアドレス化され、バージョン間で共有される永続的なB‑tree派生構造です。そのため、書き込み時には新しいノードが作成され、古いノードは変更されません。接続(`@conn`)を参照すると、ブランチヘッドキーのみがロードされ、以降のクエリノードはストレージから遅延読み込みされローカルにキャッシュされるため、読み取りは高速です。 ライターは各トランザクションを直接永続ストレージへフラッシュするため、ストア自体が権威的であり、読みアクセスには別途トランザクタやAPI層は不要です。これによりDatahikeはサーバーレスで低遅延のリードエンジンとなります。 システムは**Konserve**を使用しており、S3、ローカルファイルシステム、JDBC、IndexedDBなど多くのバックエンド上に抽象化されています。ブラウザクライアントは`konserve-sync`でデータベースをローカルにレプリケートでき、クエリはローカルレプリカに対して実行されるため往復通信が不要です。WebSocketによる同期では変更されたツリー・ノードのみが送信され、構造的共有を活用した効率的な更新が可能です。 Datahikeの値ベースモデルは、異なるバックエンドにある複数のデータベースを単一のDatalogクエリで結合できるようにします。また、`d/as-of`を使用して異なる時点のスナップショットを混在させることで、追加の調整なしに履歴データを監査・デバッグできます。 Clojure REPLのサンプルでは、2つの独立したデータベースを作成し、それらにデータを投入してクロスデータベース結合を実行する方法が示されています。バックエンドキーワードを変更するだけで同じコードが異なるストレージバックエンドでも動作します。従来のETLパイプライン、メッセージキュー、およびAPI層を排除することで、このモデルは遅延・保守負担と新たな障害モードを削減し、不変スナップショットデータベースを分散アプリケーションに実用的にします。

CSSは終焉を迎える運命にあります。 | そっか~ニュース