Google Chrome 34.0.1797.2 (Official Build 246002) dev-m
OS  Windows 
Blink 537.36 (@165430)
enable-experimental-web-platform-features フラグ オン
CSS Programming という概念が生まれてから今年で 3 年。 CSS である程度の「計算」ができることは広く知られるようになりました[要出典]が、これまでは致命的な欠点を抱えていました。 それは、計算結果を再び入力として使うことができないという点です。
- たとえば、
counter-incrementを使えばたし算・ひき算ができますが、その結果はcontent: counter(foo)として表示するだけで、新たな計算の入力としては使えません。 - たとえば、CSS Calculator
では、演算子は一度しか使えず、普通の電卓のように 
1 + 2 + 3 + ...と連続して計算することはできません。 - たとえば、HTML + CSS だけで一次元セルオートマトンを作ることができますが、計算結果をその次のステップで利用するために人間が Tab + Space を押してやる必要があります。
 
CSS Regions を利用した次のような HTML と CSS を考えます。
<input type="checkbox"><div id="input0" class="in"></div>
<input type="checkbox"><div id="input1" class="in"></div>
<div class="or"></div>
<div class="and"></div>.in {
  flow-into: flow1;
}
input:checked + .in {
  height: 100px;
}
.or, .and {
  max-height: 100px;
  flow-from: flow1;
}2 つの input があり、それらをチェックすると、その直後の .in の高さが変化して flow1 という名前の named flow に流れ込みます。
流れ込んだ .in は、後続の 2 つの div に流れ出すことになりますが、
inputがチェックされていなければ.orも.andも空。(empty)inputがどちらか 1 つだけチェックされていれば、.orには要素が流れ出している (fit) ものの、.andは空。inputが両方ともチェックされていれば、.orにも.andにも要素が流れ出す。
というわけで、AND と OR を計算するユニットができたことになります。
div を四角、named flow を丸で表すと次のような感じでしょうか。
さて本題は、この結果を再び入力として利用することですが、簡単ですね。
.and { flow-into: flow2; } などとして、同じように flow-from: flow2 な要素も用意してやればいいのです。
AND と OR だけでは不完全なので、NOT も作っておきましょう。
これには ::region() 疑似要素を使います(::region() なしで作る方法もあるかもしれませんが)。
<div class="not-plus" id="not-plus1"></div>
<div class="not-plus"></div>
<div class="not-plus"></div>
<div class="not-minus"></div>
<div class="not-minus" id="not-minus1"></div>
<div class="not"></div>/* 前の結果が flow-into: flow2 されている前提 */
.not-plus, .not-minus {
  height: 100px;
}
.not-plus {
  flow-into: flow2;
}
.not-minus, .not {
  flow-from: flow2;
}
#not-minus1::region(#not-plus1) {
  margin-top: -200px;
}- 前の結果が流れ込んでこなければ、3 つの 
.not-plusが.not-minusと.notに流れ出す。 - 流れ込んでくると、
- まずその要素が 1 つ目の 
.not-minusに流れ出す。 - 次の 
#not-plus1が#not-minus1に流れ出し、::region()のルールが適用される。200px 分の隙間ができる。 - その隙間に残り 2 つの 
.not-plusが流れこむため、.notは空のままになる。 
 - まずその要素が 1 つ目の 
 
::region() のところを赤線で表すと次のように図にかけます。
残念ながら、::region() 疑似要素を使えるブラウザはまだありません。
Chrome (とたぶん Safari も)では古い @-webkit-region ルールが使えるのですが、margin-top はサポートされていません。
そのため、以下のデモでは JavaScript Polyfill を利用しています。::region() 疑似要素については「CSS Regions と ::region() 疑似要素」も参照してください。
以上で、AND, OR, NOT 等の基本的なユニットが完成し、また各ユニットの出力を入力に使うこともできるようになりました。 これで、(将来的にはきっと CSS だけで)論理演算ができます。めでたし、めでたし……
flow の名前の処理が手書きでは煩雑なため、テンプレートエンジンなどを使って自動生成したいところです。 例えば、私は CoffeeCup で、regioncalc/regioncalc.coffee のようなテンプレートを用意していますが、まったく役に立たなくて便利かと思います。
- Demo: 加算器
- ソース (CoffeeCup)
 - 半加算器の部分の図。flow 間を単につなげるだけの要素を薄い四角で表しています(コネクタと呼んでいます)。
 
 
- 出力を自分や、より上流に再入力して循環参照させることはできません。 できたとするといつまでもスタイルの計算が終わらなくなるため、CSS Regions の仕様で防ぐようになっています。
 - polyfill が重い + 
setTimeout等を乱用していて遅いため、スタイルが適用されるまでにタイムラグがあります。- そもそもこんなことをしているのも、無茶をすることで polyfill の不具合発見や性能向上に役立てたいという意図があります。
 
 

