Puttin' the eek back in geek

CSS3 C64, a Commodore 64 demo in your browser

December 15, 2013

I wanted to see how far I could get to “emulating” a Commodore 64 without using JavaScript. Turns out you can build a sweet little C64 demo with just some plain old HTML, CSS, an image and a handful of fonts — and not a single byte of JavaScript 1. The following thingy is a little something I worked on during the train ride to work: CSS3 C64.

The logo was created with Christian Heilmann’s C64 charset logo generator. The two fonts were scavaged online. One is the default C64 font, the second one is from Giana Sisters.

This is the HTML the page runs on:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<!doctype html>
<html>
<head>
    <title>CSS3 C64 by Pixelambacht</title>
    <link href="css.css" rel="stylesheet">

    <script src="prefixfree.min.js"></script>
</head>
<body>

  <textarea class="spacebar" required autofocus spellcheck="false"></textarea>

  <section class="bluescreen">
    <ul class="loading">
      <li>
      <li>
      <li>
      <li>
      <li>
    </ul>
  </section>

  <section class="introscreen">
    <div class="logo"></div>
    <ul class="presents">
      <li>
      <li>
    </ul>
    <ul class="starfield">
      <li>
      <li>
      <li>
      <li>
      <li>
      <li><br>
      <li>
      <li>
      <li>
      <li>
      <li>
      <li><br>
      <li>
      <li>
      <li>
      <li>
      <li>
      <li><br>
    </ul>
    <p class="scrolltext"></p>
  </section>

  <a href="http://pixelambacht.nl/2013/css3-c64/" class="credits">CSS3 C64 By Pixelambacht </a>

</body>
</html>

The CSS is not really earth-shattering clever and not necessarily the best way to achieve these animations, but it takes care of all the effects:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
/* http://meyerweb.com/eric/tools/css/reset/
   v2.0 | 20110126
   License: none (public domain)
*/
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
  margin: 0;
  padding: 0;
  border: 0;
  font-size: 100%;
  font: inherit;
  vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
  display: block;
}
body {
  line-height: 1;
}
ol, ul {
  list-style: none;
}
blockquote, q {
  quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
  content: '';
  content: none;
}
table {
  border-collapse: collapse;
  border-spacing: 0;
}
*, *:before, *:after {
  -moz-box-sizing: border-box; box-sizing: border-box; box-sizing: border-box;
}

html, body {
  height: 100%;
  background: #333;
}
.credits {
  text-decoration: none;
  font: normal 8px "C64 User Mono";
  color: #777;
  position: absolute;
  right: 1em;
  bottom: 1em;
}
.credits:hover {
  color: #aaa;
}

/**
 * Fonts
 */
@font-face {
   font-family: "C64 User Mono";
   src: url("C64_User_Mono_v1.0-STYLE.eot");
   src: url("C64_User_Mono_v1.0-STYLE.eot?#iefix") format("embedded-opentype"),
        url("C64_User_Mono_v1.0-STYLE.woff") format("woff"),
        url("C64_User_Mono_v1.0-STYLE.ttf") format("truetype");
  font-weight: normal;
  font-style: normal;
}
@font-face {
  font-family: "Giana";
  src: url("giana.eot");
  src: url("giana.eot?#iefix") format("embedded-opentype"),
       url("giana.woff") format("woff"),
       url("giana.ttf") format("truetype");
  font-weight: normal;
  font-style: normal;
}

/**
 * The blue C64 screen
 */
.spacebar,
section {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 640px;
  height: 400px;

  margin-top: -200px;
  margin-left: -320px;

  color: #6076c5;
  font: normal 16px "C64 User Mono";
  text-transform: uppercase;

  z-index: 1;
}
/* Border of the sceen */
section:before {
  position: absolute;
  left: -64px;
  right: -64px;
  top: -74px;
  bottom: -74px;
  content: "";
  background: #6076c5;
  z-index: -1;
}
/* Inside screen */
section:after {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  content: "";
  background: #20398d;
  z-index: -1;
}

/**
 * Blue screen animations
 */
@keyframes cursor {
  0% {
    background: #20398d;
  }
  50% {
    background: #6076c5;
  }
}
@keyframes line_one {
  from {
    height: auto;
    text-indent: 0;
  }
  to {
    height: auto;
    width: 23em; /* Number of chars + one for cursor */
    text-indent: 0;
  }
}
@keyframes line_two {
  to {
    width: 100%;
    height: 100%;
  }
}
@keyframes line_three {
  from {
    height: 100%;
    text-indent: 0;
  }
  to {
    height: 100%;
    width: 4em; /* Number of chars + one for cursor */
    text-indent: 0;
  }
}
@keyframes decrunch {
  /* Firefox and IE10 won't animate linear-gradients, so we fall back to full border color change */
  20% {
    background: #b8b8b8;
    background-image: linear-gradient(to bottom, #ffffff 5%,#000000 5%,#000000 10%,#b8b8b8 10%,#b8b8b8 16%,#5090d0 16%,#5090d0 23%,#98ff98 23%,#98ff98 28%,#808080 28%,#808080 33%,#484848 33%,#484848 40%,#c87870 40%,#c87870 46%,#472b1b 46%,#472b1b 51%,#a04800 51%,#a04800 57%,#f0e858 57%,#f0e858 62%,#181090 62%,#181090 69%,#50b818 69%,#50b818 78%,#a838a0 78%,#a838a0 86%,#68d0a8 86%,#68d0a8 95%,#882000 95%);
  }
  40% {
    background: #484848;
    background-image: linear-gradient(to bottom, #882000 10%,#68d0a8 10%,#68d0a8 12%,#a838a0 12%,#a838a0 18%,#50b818 18%,#50b818 27%,#181090 27%,#181090 38%,#f0e858 38%,#f0e858 41%,#a04800 41%,#a04800 56%,#472b1b 56%,#472b1b 61%,#c87870 61%,#c87870 66%,#484848 66%,#484848 68%,#808080 68%,#808080 75%,#98ff98 75%,#98ff98 77%,#5090d0 77%,#5090d0 92%,#b8b8b8 92%,#b8b8b8 94%,#000000 94%,#000000 97%,#ffffff 97%);
  }
  60% {
    background: #c87870;
    background-image: linear-gradient(to bottom, #ffffff 5%,#c87870 5%,#c87870 14%,#484848 14%,#484848 22%,#808080 22%,#808080 31%,#98ff98 31%,#98ff98 38%,#5090d0 38%,#5090d0 43%,#b8b8b8 43%,#b8b8b8 49%,#000000 49%,#000000 54%,#68d0a8 54%,#68d0a8 60%,#a838a0 60%,#a838a0 67%,#50b818 67%,#50b818 72%,#181090 72%,#181090 77%,#f0e858 77%,#f0e858 84%,#a04800 84%,#a04800 90%,#472b1b 90%,#472b1b 95%,#882000 95%);
  }
  80% {
    background: #68d0a8;
    background-image: linear-gradient(to bottom, #882000 5%,#68d0a8 5%,#68d0a8 14%,#a838a0 14%,#a838a0 22%,#50b818 22%,#50b818 31%,#181090 31%,#181090 38%,#f0e858 38%,#f0e858 43%,#a04800 43%,#a04800 49%,#472b1b 49%,#472b1b 54%,#c87870 54%,#c87870 60%,#484848 60%,#484848 67%,#808080 67%,#808080 72%,#98ff98 72%,#98ff98 77%,#5090d0 77%,#5090d0 84%,#b8b8b8 84%,#b8b8b8 90%,#000000 90%,#000000 95%,#ffffff 95%);
  }
  100% {
    background: #50b818;
    background-image: linear-gradient(to bottom, #ffffff 3%,#000000 3%,#000000 6%,#b8b8b8 6%,#b8b8b8 8%,#5090d0 8%,#5090d0 23%,#98ff98 23%,#98ff98 25%,#808080 25%,#808080 32%,#484848 32%,#484848 34%,#c87870 34%,#c87870 39%,#472b1b 39%,#472b1b 44%,#a04800 44%,#a04800 59%,#f0e858 59%,#f0e858 62%,#181090 62%,#181090 73%,#50b818 73%,#50b818 82%,#a838a0 82%,#a838a0 88%,#68d0a8 88%,#68d0a8 90%,#882000 90%);
  }
}

/**
 * All the typing stuff on the blue screen
 */
.loading {
  line-height: 1;
}
.loading li {
  padding-right: 1em;
  width: 0;
  height: 0;
  overflow: hidden;
  display: inline-block;
  position: relative;
  float: left;
  clear: left;
}
.loading li:first-child {
  height: auto;
  width: auto;
}
.loading li:before {
  white-space: pre;
}
.spacebar:before,
.loading li:first-child:before {

  content: "\0a     **** commodore 64 basic v2 ****\
    \0a\0a  64k ram system  38911 basic bytes free\
    \0a\0aready.";

}
.loading li:nth-child(2):before {
  content: "load\"pixelambacht\",8,1";
}
.loading li:nth-child(3):before {
  content: "\0asearching for pixelambacht\0aloading";
}
.loading li:nth-child(4):before {
  content: "ready.";
}
.loading li:nth-child(5):before {
  content: "run";
}
.loading li:nth-child(2) {
  width: 1em;
  height: auto;
  text-indent: 1em;
  animation-name: line_one;
  animation-delay: 2s;
  animation-duration: 3s;
  animation-iteration-count: 1;
  animation-timing-function: steps(22);
  animation-fill-mode: forwards;
}
.loading li:nth-child(2):after {
  width: 1em;
  height: 1em;
  background: rgba(0,0,0,0);
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  animation-name: cursor;
  animation-duration: 1s;
  animation-iteration-count: 7; /* must be even, so we end on invisible cursor */
  animation-timing-function: steps(1);
  animation-fill-mode: forwards;
}
.loading li:nth-child(3) {
  animation-delay: 7s;
  animation-duration: 1s;
  animation-name: line_two;
  animation-iteration-count: 1;
  animation-timing-function: steps(1, start);
  animation-fill-mode: forwards;
}
.loading li:nth-child(4) {
  animation-delay: 11s;
  animation-duration: 1s;
  animation-name: line_two;
  animation-iteration-count: 1;
  animation-timing-function: steps(1, start);
  animation-fill-mode: forwards;
}
.loading li:nth-child(5) {
  width: 1em;
  height: auto;
  text-indent: 1em;
  animation-delay: 12s;
  animation-duration: 1s;
  animation-name: line_three;
  animation-iteration-count: 1;
  animation-timing-function: steps(3, start);
  animation-fill-mode: forwards;
}
.loading li:nth-child(5):after {
  width: 1em;
  height: 1em;
  background: rgba(0,0,0,0);
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  animation-name: cursor;
  animation-duration: 1s;
  animation-delay: 10.5s;
  animation-iteration-count: 3; /* must be even, so we end on invisible cursor */
  animation-timing-function: steps(1);
  animation-fill-mode: forwards;
}

/**
 * Decrunching
 */
section.bluescreen:before {
  animation-name: decrunch;
  animation-delay: 15s;
  animation-duration: 0.25s;
  animation-iteration-count: 14;
  animation-timing-function: steps(1);
}

/**
 * Intro screen animations
 */
@keyframes startintro {
  to {
    visibility: visible;
  }
}
@keyframes logoswing {
  50% {
    left: -162px;
  }
}
@keyframes rasterswing {
  50% {
    top: 168px;
  }
}
@keyframes rasterindex {
  50% {
    z-index: 10;
  }
}
@keyframes textflash {
  0% { color: #000000; }
  1% { color: #20398d; }
  2% { color: #6076c5; }
  3% { color: #86bec5; }
  4% { color: #ffffff; }
  5% { color: #86bec5; }
  6% { color: #6076c5; }
  7% { color: #20398d; }
  8% { color: #000000; }
  26% { color: #873b31; }
  27% { color: #ba7369; }
  28% { color: #dce78c; }
  29% { color: #ffffff; }
  30% { color: #dce78c; }
  31% { color: #ba7369; }
  32% { color: #873b31; }
  33% { color: #000000; }
  51% { color: #555555; }
  52% { color: #808080; }
  53% { color: #ababab; }
  54% { color: #ffffff; }
  55% { color: #ababab; }
  56% { color: #808080; }
  57% { color: #555555; }
  58% { color: #000000; }
  76% { color: #625000; }
  77% { color: #74ab54; }
  78% { color: #b7eb9b; }
  79% { color: #ffffff; }
  80% { color: #b7eb9b; }
  81% { color: #74ab54; }
  82% { color: #625000; }
  83% { color: #000000; }
}
@keyframes starscroll {
  to {
    left: -40em;
  }
}
@keyframes scroller {
  to {
    text-indent: -220em; /* Should match text length */
  }
}
@keyframes scrollerbounce {
  from, to  {
    animation-timing-function: ease-out;
  }
  50% {
    line-height: 1em;
    animation-timing-function: ease-in;
  }
}

/**
 * The intro screem
 */
section.introscreen {
  animation-name: startintro;
  animation-delay: 19s; /* Blue screen animation takes 19s */
  animation-fill-mode: forwards;
  animation-duration: 1s; /* Doesn't matter */

  visibility: hidden;
  background: #000;
  border-color: #000;

  font: normal 16px "Giana";
  text-transform: uppercase;

}
section.introscreen:before,
section.introscreen:after {
  background: #000;
}

/**
 * The swinging Pixelambacht logo
 */
div.logo {
  position: absolute;
  top: 64px;
  left: 0;
  right: 0;
  text-align: center;
  margin: 0 auto;
  height: 96px;
  color: #6076c5;
  overflow: hidden;
}
div.logo:before {
  content: url(pixelambacht-logo.png);
  position: absolute;
  left: 40px;

  animation-name: logoswing;
  animation-duration: 3s;
  animation-iteration-count: infinite;
  animation-timing-function: cubic-bezier(0.420, 0.000, 0.580, 1.000);
  animation-fill-mode: forwards;

  z-index: 9;
}

/**
 * The swinging raster bar
 */
section.introscreen:after {
  height: 100px;
  left: -64px;
  right: -64px;
  z-index: 8;
  position: absolute;

  animation-name: rasterswing, rasterindex;
  animation-duration: 4s, 4s;
  animation-iteration-count: infinite, infinite;
  animation-timing-function: cubic-bezier(0.420, 0.000, 0.580, 1.000), steps(1);
  animation-fill-mode: forwards;

  background: linear-gradient(to bottom, #873b31 0%,#000000 2%,#873b31 2%,#873b31 4%,#873b31 4%,#873b31 6%,#ba7369 6%,#ba7369 8%,#873b31 8%,#873b31 10%,#ba7369 10%,#ba7369 12%,#ba7369 12%,#ba7369 14%,#dce78c 14%,#dce78c 16%,#ba7369 16%,#ba7369 18%,#dce78c 18%,#dce78c 20%,#dce78c 20%,#dce78c 22%,#ffffff 22%,#ffffff 24%,#dce78c 24%,#dce78c 26%,#ffffff 26%,#ffffff 28%,#ffffff 28%,#ffffff 30%,#dce78c 30%,#dce78c 32%,#ffffff 32%,#ffffff 34%,#dce78c 34%,#dce78c 36%,#dce78c 36%,#dce78c 38%,#ba7369 38%,#ba7369 40%,#dce78c 40%,#dce78c 42%,#ba7369 42%,#ba7369 44%,#ba7369 44%,#ba7369 46%,#873b31 46%,#873b31 48%,#ba7369 48%,#ba7369 50%,#873b31 50%,#873b31 52%,#873b31 52%,#873b31 54%,#000000 54%,#000000 56%,#873b31 56%,#873b31 58%,rgba(0,0,0,0) 58%,rgba(0,0,0,0) 100%);
}

/**
 * Credits block
 */
ul.presents {
  z-index: 10;
  color: #000000;
  position: absolute;
  top: 228px;
  left: -64px;
  right: -64px;
  text-align: center;
  padding: 34px 0; /* Making it 100px high */

  background: linear-gradient(to bottom, #20398d 0%,#000000 2%,#20398d 2%,#20398d 4%,#20398d 4%,#20398d 6%,#6076c5 6%,#6076c5 8%,#20398d 8%,#20398d 10%,#6076c5 10%,#6076c5 12%,#6076c5 12%,#6076c5 14%,#86bec5 14%,#86bec5 16%,#6076c5 16%,#6076c5 18%,#86bec5 18%,#86bec5 20%,#86bec5 20%,#86bec5 22%,#ffffff 22%,#ffffff 24%,#86bec5 24%,#86bec5 26%,#ffffff 26%,#ffffff 74%,#86bec5 74%,#86bec5 76%,#ffffff 76%,#ffffff 78%,#86bec5 78%,#86bec5 80%,#86bec5 80%,#86bec5 82%,#6076c5 82%,#6076c5 84%,#86bec5 84%,#86bec5 86%,#6076c5 86%,#6076c5 88%,#6076c5 88%,#6076c5 90%,#20398d 90%,#20398d 92%,#6076c5 92%,#6076c5 94%,#20398d 94%,#20398d 96%,#20398d 96%,#20398d 98%,#000000 98%,#000000 100%); /* W3C */
}
ul.presents li:first-child:before {
  content: "c64 in css3";
  animation-name: textflash;
  animation-duration: 10s;
  animation-iteration-count: infinite;
  animation-timing-function: steps(1);
}
ul.presents li:last-child:before {
  content: "coded by pixelambacht";
  animation-name: textflash;
  animation-duration: 10s;
  animation-delay: 0.5s;
  animation-iteration-count: infinite;
  animation-timing-function: steps(1);
}

/**
 * Flashing startfield behind the scrolltext
 */
.starfield {
  position: relative;
  position: absolute;
  bottom: 0;
  left: 0;
  overflow: hidden;
  height: 4em;
  width: 40em;
}
.starfield li {
  position: relative;
  display: inline;
  left: 0;
}
.starfield li:before {
  content: ".";
}
/* Create an exact copy of each star */
.starfield li:after {
  content: ".";
  position: absolute;
  top: 0;
  left: 40em;
}
.starfield li {
  animation-name: starscroll;
  animation-duration: 5s;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
  animation-fill-mode: forwards;
}
.starfield li:before,
.starfield li:after {
  animation-name: textflash;
  animation-iteration-count: infinite;
  animation-timing-function: steps(1);
  animation-duration: 6.5s;
  padding-left: 3em;
}
.starfield li:nth-child(2n):before,
.starfield li:nth-child(2n):after {
  padding-left: 4em;
}
.starfield li:nth-child(3n):before,
.starfield li:nth-child(3n):after {
  padding-left: 7em;
}
.starfield li:nth-child(4n):before,
.starfield li:nth-child(4n):after {
  padding-left: 2em;}

/* Flash each star at a different time */
.starfield li:nth-child(1):before,
.starfield li:nth-child(1):after {
  animation-delay: -1s;
}
.starfield li:nth-child(2):before,
.starfield li:nth-child(2):after {
  animation-delay: -1.5s;
}
.starfield li:nth-child(3):before,
.starfield li:nth-child(3):after {
  animation-delay: -2s;
}
.starfield li:nth-child(4):before,
.starfield li:nth-child(4):after {
  animation-delay: -2.5s;
}
.starfield li:nth-child(5):before,
.starfield li:nth-child(5):after {
  animation-delay: -3s;
}
.starfield li:nth-child(6):before,
.starfield li:nth-child(6):after {
  animation-delay: -3.5s;
}
.starfield li:nth-child(7):before,
.starfield li:nth-child(7):after {
  animation-delay: -4s;
}
.starfield li:nth-child(8):before,
.starfield li:nth-child(8):after {
  animation-delay: -4.5s;
}
.starfield li:nth-child(9):before,
.starfield li:nth-child(9):after {
  animation-delay: -5s;
}
.starfield li:nth-child(10):before,
.starfield li:nth-child(10):after {
  animation-delay: -5.5s;
}
.starfield li:nth-child(11):before,
.starfield li:nth-child(11):after {
  animation-delay: -6s;
}
.starfield li:nth-child(12):before,
.starfield li:nth-child(12):after {
  animation-delay: -6.5s;
}
.starfield li:nth-child(13):before,
.starfield li:nth-child(13):after {
  animation-delay: -7s;
}
.starfield li:nth-child(14):before,
.starfield li:nth-child(14):after {
  animation-delay: -7.5s;
}
.starfield li:nth-child(15):before,
.starfield li:nth-child(15):after {
  animation-delay: -8s;
}
.starfield li:nth-child(16):before,
.starfield li:nth-child(16):after {
  animation-delay: -8.5s;
}
.starfield li:nth-child(17):before,
.starfield li:nth-child(17):after {
  animation-delay: -9s;
}
.starfield li:nth-child(18):before,
.starfield li:nth-child(18):after {
  animation-delay: -9.5s;
}
.starfield li:nth-child(19):before,
.starfield li:nth-child(19):after {
  animation-delay: -10s;
}
.starfield li:nth-child(20):before,
.starfield li:nth-child(20):after {
  animation-delay: -10.5s;
}
.starfield li:nth-child(21):before,
.starfield li:nth-child(21):after {
  animation-delay: -11s;
}

/**
 * And finally the meat of a C64 cracktro... the scrolltext
 */
p.scrolltext {
  /* Bounce-animation needs to be separate from the scroll animation, otherwise the
     change in timing-functions will be applied to both animations */
  line-height: 7em;

  animation-name: scrollerbounce;
  animation-delay: 20s; /* Blue screen animation takes 19s, wait another second */
  animation-duration: 1s;
  animation-iteration-count: infinite;
}
p.scrolltext:before {
  content: "welcome to my little c64 intro entirely done in css! no javascript was used \
    for these effects... greetz to all the elite! press space to reset, and have fun \
    typing some basic! pixelambacht signing off...";
  position: absolute;
  bottom: 0;
  left: 0;
  width: 40em;
  overflow: hidden;
  white-space: nowrap;
  text-indent: 40em;
  height: 60px;
  color: #fff;

  animation-name: scroller;
  animation-delay: 20s; /* Blue screen animation takes 19s, wait another second */
  animation-duration: 16s;
  animation-iteration-count: infinite;
  animation-timing-function: linear;
}

/**
 * Act like a real C64 once space bar has been pressed
 */
.spacebar:valid + section li + li {
  display: none;
}
.spacebar:valid + section,
.spacebar:valid + section:before,
.spacebar:valid + section + section {
  animation-name: none;
}
.spacebar:valid + section + section {
  /* This selector doesn't work in Chrome, although it's valid :( */
  visibility: hidden;
}
.spacebar {
  background: transparent;
  outline: none;
  padding: 0;
  border: none;
  resize: none;
}
.spacebar:valid {
  z-index: 20;
  margin-top: -104px;
  text-indent: -1em; /* Hide that first space */
  height: 19em;
  overflow: hidden;
}

This demo works on the latest Chrome and Firefox, works reasonably well in IE11 and not very well in Opera.

Check the code on Github or LOAD”PIXELAMBACHT”,8,1 and have some fun!

  1. I actually use Prefixfree to take care of all the browser-specific prefixes.