CSS isn't, insofar as I know, Turing complete. But my knowledge of CSS is very limited.
Is CSS Turing complete?
Are any of the existing draft or committees considering language features that might enable Turing completeness if it isn't right now?
You can encode Rule 110 in CSS3, so it's Turing-complete so long as you consider an appropriate accompanying HTML file and user interactions to be part of the “execution” of CSS. A pretty good implementation is available, and another implementation is included here:
body { -webkit-animation: bugfix infinite 1s; margin: 0.5em 1em; } @-webkit-keyframes bugfix { from { padding: 0; } to { padding: 0; } } /* * 111 110 101 100 011 010 001 000 * 0 1 1 0 1 1 1 0 */ body > input { -webkit-appearance: none; display: block; float: left; border-right: 1px solid #ddd; border-bottom: 1px solid #ddd; padding: 0px 3px; margin: 0; font-family: Consolas, "Courier New", monospace; font-size: 7pt; } body > input::before { content: "0"; } p { font-family: Verdana, sans-serif; font-size: 9pt; margin-bottom: 0.5em; } body > input:nth-of-type(-n+30) { border-top: 1px solid #ddd; } body > input:nth-of-type(30n+1) { border-left: 1px solid #ddd; clear: left; } body > input::before { content: "0"; } body > input:checked::before { content: "1"; } body > input:checked { background: #afa !important; } input:not(:checked) + *+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+ input::before { content: "1"; } input:not(:checked) + *+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+ input { background: #fa0; } input:checked + *+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+ input::before { content: "1"; } input:checked + *+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+ input { background: #fa0; } input:checked + *+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+ input::before { content: "1"; } input:checked + *+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+ input { background: #fa0; } input:checked + input:checked + input:checked + *+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+ input::before { content: "0"; } input:checked + input:checked + input:checked + *+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+ input { background: #fff; } input:not(:checked) + input:not(:checked) + input:not(:checked) + *+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+ input::before { content: "0"; } input:not(:checked) + input:not(:checked) + input:not(:checked) + *+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+ input { background: #fff; } body > input:nth-child(30n) { display: none !important; } body > input:nth-child(30n) + label { display: none !important; }
Rule 110 in (webkit) CSS, proving Turing-completeness.
One aspect of Turing completeness is the halting problem.
This means that, if CSS is Turing complete, then there's no general algorithm for determining whether a CSS program will finish running or loop forever.
But we can derive such an algorithm for CSS! Here it is:
If the stylesheet doesn't declare any animations, then it will halt.
If it does have animations, then: If any animation-iteration-count is infinite, and the containing selector is matched in the HTML, then it will not halt. Otherwise, it will halt.
If any animation-iteration-count is infinite, and the containing selector is matched in the HTML, then it will not halt.
Otherwise, it will halt.
That's it. Since we just solved the halting problem for CSS, it follows that CSS is not Turing complete.
(Other people have mentioned IE 6, which allows for embedding arbitrary JavaScript expressions in CSS; that will obviously add Turing completeness. But that feature is non-standard, and nobody in their right mind uses it anyway.)
Daniel Wagner brought up a point that I missed in the original answer. He notes that while I've covered animations, other parts of the style engine such as selector matching or layout can lead to Turing completeness as well. While it's difficult to make a formal argument about these, I'll try to outline why Turing completeness is still unlikely to happen.
First: Turing complete languages have some way of feeding data back into itself, whether it be through recursion or looping. But the design of the CSS language is hostile to this feedback:
@media queries can only check properties of the browser itself, such as viewport size or pixel resolution. These properties can change via user interaction or JavaScript code (e.g. resizing the browser window), but not through CSS alone.
::before and ::after pseudo-elements are not considered part of the DOM, and cannot be matched in any other way.
Selector combinators can only inspect elements above and before the current element, so they cannot be used to create dependency cycles.
It's possible to shift an element away when you hover over it, but the position only updates when you move the mouse.
That should be enough to convince you that selector matching, on its own, cannot be Turing complete. But what about layout?
The modern CSS layout algorithm is very complex, with features such as Flexbox and Grid muddying the waters. But even if it were possible to trigger an infinite loop with layout, it would be hard to leverage this to perform useful computation. That's because CSS selectors inspect only the internal structure of the DOM, not how these elements are laid out on the screen. So any Turing completeness proof using the layout system must depend on layout alone.
Finally – and this is perhaps the most important reason – browser vendors have an interest in keeping CSS not Turing complete. By restricting the language, vendors allow for clever optimizations that make the web faster for everyone. Moreover, Google dedicates a whole server farm to searching for bugs in Chrome. If there were a way to write an infinite loop using CSS, then they probably would have found it already 😉
As per this article, it's not. The article also argues that it's not a good idea to make it one.
To quote from one of the comments:
So, I do not believe that CSS is turing complete. There is no capability to define a function in CSS. In order for a system to be turing-complete it has to be possible to write an interpreter: a function that interprets expressions that denote programs to execute. CSS has no variables that are directly accessible to the user; so you cannot even model the structure that represents the program to be interpreted in CSS.
Turing-completeness is not only about "defining functions" or "have ifs/loops/etc". For example, Haskell doesn't have "loop", lambda-calculus don't have "ifs", etc...
For example, this site: http://experthuman.com/programming-with-nothing. The author uses Ruby and create a "FizzBuzz" program with only closures (no strings, numbers, or anything like that)...
There are examples when people compute some arithmetical functions on Scala using only the type system
So, yes, in my opinion, CSS3+HTML is turing-complete (even if you can't exactly do any real computation with then without becoming crazy)
The fundamental issue here is that any machine written in HTML+CSS cannot evaluate infinitely many steps (i.e there can be no "real" recursion) unless the code is infinitely long. And the question will this machine reach configuration H
in n
steps or less is always answerable if n
is finite.
H
?" is always decidable and it is thus not Turing complete. An implementation of a cellular automaton that can only do a finite number of iterations can never be turing complete.
This answer is not accurate because it mix description of UTM and UTM itself (Universal Turing Machine).
We have good answer but from different perspective and it do not show directly flaws in current top answer.
First of all we can agree that human can work as UTM. This mean if we do
CSS + Human == UTM
Then CSS
part is useless because all work can be done by Human
who will do UTM part. Act of clicking can be UTM, because you do not click at random but only in specific places.
Instead of CSS I could use this text (Rule 110):
000 -> 0
001 -> 1
010 -> 1
011 -> 1
100 -> 0
101 -> 1
110 -> 1
111 -> 0
To guide my actions and result will be same. This mean this text UTM? No this is only input (description) that other UTM (human or computer) can read and run. Clicking is enough to run any UTM.
Critical part that CSS lack is ability to change of it own state in arbitrary way, if CSS could generate clicks then it would be UTM. Argument that your clicks are "crank" for CSS is not accurate because real "crank" for CSS is Layout Engine that run it and it should be enough to prove that CSS is UTM.
R
- read state, and W
- write state, normal CA do infinite sequence RWRWRWRW...
in case of CSS we have only R
, and we do not have W
because it modify things that it can't read, only if we add B
- browser action then we could have RBRBRBR...
but then BBBBBB
is on its own UTM.
CSS is not a programming language, so the question of turing-completeness is a meaningless one. If programming extensions are added to CSS such as was the case in IE6 then that new synthesis is a whole different thing.
CSS is merely a description of styles; it does not have any logic, and its structure is flat.
Success story sharing