-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.html
194 lines (176 loc) · 12.9 KB
/
index.html
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
<!DOCTYPE html>
<html lang="en_us">
<head>
<title>(Almost) No Javascript!</title>
<meta charset="utf-8" />
<meta name="generator" content="Pelican" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="/static/css/main.css" />
<link rel="stylesheet" href="/static/css/theme.css" />
<link rel="icon" href="/images/yazani/yazani_1_extracted_bg_big_eyes_cropped.png" type="image/png" />
<link rel="apple-touch-icon" href="/images/yazani/yazani_1_extracted_bg_big_eyes_cropped.png" type="image/png" />
<script src="/static/misc.js"></script>
<script src="/blog/banner_image.js"></script>
<meta name="tags" content="css" />
<meta property="og:site_name" content="dragoncoder047’s blog" />
<meta property="og:title" content="(Almost) No Javascript!" />
<meta property="og:description" content="I did a total redesign of my Langton’s Ant simulator last week – and most of the formatting I was able to do with pure CSS - no Javascript needed for layout control. Previously I had a rather crude layout consisting of a fixed-size canvas and a textbox below it. The …" />
<meta property="og:image" content="/images/yazani/yazani_1_extracted_bg.png" />
<meta property="og:type" content="article" />
<meta property="og:url" content="https://dragoncoder047.github.io/blog/2022/almost-no-javascript" />
<meta property="og:locale" content="['']" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="dragoncoder047’s blog - (Almost) No Javascript!" />
<meta name="twitter:description" content="I did a total redesign of my Langton’s Ant simulator last week – and most of the formatting I was able to do with pure CSS - no Javascript needed for layout control. Previously I had a rather crude layout consisting of a fixed-size canvas and a textbox below it. The …" />
<meta name="twitter:image" content="/images/yazani/yazani_1_extracted_bg.png" />
<!-- PrismJS -->
<script src="/static/prism.js" data-autoloader-path="https://cdn.jsdelivr.net/npm/prismjs@v1.x/components/"></script>
<script src="/static/prism-runbutton.js"></script>
<script src="/phoo/prism-phoo.js"></script> <!-- /PrismJS -->
</head>
<body class="match-braces rainbow-braces">
<header>
<a href="https://dragoncoder047.github.io/blog" class="flex-row"><div class="flex-row"><img src="/images/yazani/yazani_1_extracted_bg.png" style="max-height:10em" id="banner-image" /><div id="sitename-text"><h1>dragoncoder047’s blog</h1><h2>random thoughts about nonrandom things</h2></div></div></a>
<nav>
<ul>
<li><a href="https://dragoncoder047.github.io/blog/">Home</a></li>
<li><a href="https://dragoncoder047.github.io/blog/archives">Archives</a>
</li>
<li><a href="https://dragoncoder047.github.io/blog/tags">By tag</a>
</li>
<li><a href="/">Site root</a>
</li>
<li><a href="#">Projects</a>
<ul>
<li><a href="https://dragoncoder047.github.io/thuepaste">Thuepaste</a>
</li>
<li><a href="https://dragoncoder047.github.io/armdroid">Armdroid</a>
</li>
<li><a href="https://dragoncoder047.github.io/langton-music">Langton's Ant Music</a>
</li>
<li><a href="https://dragoncoder047.github.io/schemascii">Schemascii</a>
</li>
<li><a href="https://dragoncoder047.github.io/parasite">Parasite</a>
</li>
</ul>
</li>
<li>
<form action="https://www.google.com/search" method="GET">
<input name="q" type="search" placeholder="Search"></input>
<input type="hidden" name="as_sitesearch" value="https://dragoncoder047.github.io/blog"></input>
<input type="submit" value="Search"></input>
</form>
</li>
</ul>
</nav>
</header>
<main>
<h1><a href="https://dragoncoder047.github.io/blog/2022/almost-no-javascript" rel="bookmark" title="Permalink to this page">(Almost) No Javascript!</a></h1>
<div class="flex-row">
<span style="flex: 1">← Previous:
<a href="https://dragoncoder047.github.io/blog/2022/two-down-a-zillion-more-to-go">
Two Down, A Zillion More To Go
</a>
</span>
<span>Next:
<a href="https://dragoncoder047.github.io/blog/2022/ulisp-thoughts">
uLisp Thoughts
</a> →
</span>
</div>
<div class="post-info">
Posted <time class="published" datetime="2022-09-07T00:00:00-04:00">Wed 07 September 2022</time>
<address>By
<a href="https://dragoncoder047.github.io/blog/">dragoncoder047</a>
</address>
<div class="tags">
Tags:
<a href="https://dragoncoder047.github.io/blog/tag/css">css</a>
</div>
</div>
<p>I did a total redesign of my Langton’s Ant simulator last week – and most of the formatting I was able to do with pure CSS - no Javascript needed for layout control.</p>
<p>Previously I had a rather crude layout consisting of a fixed-size canvas and a textbox below it. The canvas was defined to be 1280x640 no matter the screen size, and my fear was that on smartphones it would spill over off the screen, and the image would be cut off. Additionally, the touch drag action on the canvas pans around, and so it effectively prevents the user from scrolling down and reaching the text box as well.</p>
<p>I decided I would redesign everything to fix these problems. In total, I made quite a few major changes:</p>
<ol>
<li>I redesigned the parser to use XML instead of a impossible-to-maintain custom parser. It’s quite more verbose than the original format, but by nature of the “X” in XML, it is extensible.</li>
<li>I replaced the plain old <code class="language-html highlight"><textarea></code> with an <a href="https://ace.c9.io/">Ace editor</a> to allow syntax highliting and other helpful features for working with XML.</li>
<li>I made extensive use of CSS flexboxes to position buttons and controls in neat rows that wrap around when they get full.</li>
<li>I added some Javascript to the drag manager class that automatically resizes the canvas to fill its parent element and maintain the 1:1 aspect ratio and prevent blurry drawing. There’s an (intentional?) but in the HTML5 <code class="language-html highlight"><canvas></code> that causes the drawing to become distorted if the <code class="language-html highlight"><canvas></code>‘s <code>width</code> and <code>height</code> attributes aren’t the same (or proportional to) its CSS <code>width</code> and <code>height</code>. No CSS will fix this, so I had to resort to Javascript.</li>
<li>I moved the <del>textarea</del> Ace to a separate popup window so that both it and the canvas could take up the entire screen without the user having to scroll. This, surprisingly, required absolutely no Javascript.</li>
</ol>
<p>#5 I am the most proud of, and here’s how I did it:</p>
<p>First, everything tha is <em>not</em> the popup (what would normally just be the <code class="language-html highlight"><body></code>) gets put in the <code class="language-html highlight"><main></code> element.</p>
<p>The body’s scroll is disabled:</p>
<pre class="highlight"><code class="language-css">body { overflow: hidden }</code></pre>
<p>And the <code class="language-html highlight"><main></code> is expanded to fill the entire window:</p>
<pre class="highlight"><code class="language-css">main { width: 100%; height: 100%; position: absolute; top: 0; left: 0; margin: 0 }</code></pre>
<p>Then, the popover is added adjacent to (not in) the <code class="language-html highlight"><main></code> element:</p>
<pre class="highlight"><code class="language-html"><main>
<!-- main content -->
</main>
<div id="dump" class="popover">
<div>
<!-- popover content- notice the nested <div> -->
</div>
</div></code></pre>
<p>Notice the popover has two nested <code class="language-html highlight"><div></code>s – the outer is the “greyed-out” background, and the inner is the actual popover content. Here’s the CSS that does that:</p>
<pre class="highlight"><code class="language-css">.popover {
background: rgba(0, 0, 0, 50%); z-index: 999999; position: absolute; top: 150vh; left: 0; width: 100%; height: 100%;
display: flex; justify-content: center; align-items: center
}</code></pre>
<p>The first line is pretty much the same as the CSS that was applied to the <code class="language-html highlight"><main></code> element – it makes it fill the screen. Notice, however, that the <code>top</code> is <code class="language-css highlight">150vh</code> instead of <code class="language-css highlight">0</code> – this pushes it down off the screen where it can’t be viewed.</p>
<p>The second line centers the nested <code class="language-html highlight"><div></code>, which is styled with this CSS:</p>
<pre class="highlight"><code class="language-css">.popover>div { background: white; width: 80%; height: 80%; border: 2px solid black; padding: 1em }</code></pre>
<p>There’s one last thing that is missing from this:</p>
<pre class="highlight"><code class="language-css">.popover:target { top: 0 }</code></pre>
<p>The <code class="language-css highlight">:target</code> pseudoclass is relatively new, and matches only when the hash of the URL (everything after the <code>#</code>) is equal to the selected element’s <code>id</code>. This allows the popup to be shown and hid by using only simple <code class="language-html highlight"><a></code> links that change the hash!</p>
<p>I added a link to <code>#dump</code> (which shows the popup) on the main screen, and within the popup a link to <code>#</code> (clearing the hash and hiding the popup). With this, no Javascript is needed (except to make the popup close or open automatically).</p>
<p>I haven’t had any pure CSS solution as elegant as this since I got the sticky header on this site working (yes, no Javascript on that too). I don’t know who should be prouder: me, or the CSS Working Group!</p>
<script src="https://giscus.app/client.js"
data-repo="dragoncoder047/blog"
data-repo-id="R_kgDOHCL60w"
data-category="Post Comments"
data-category-id="DIC_kwDOHCL6084CRxCW"
data-mapping="og:title"
data-reactions-enabled="1"
data-input-position="top"
data-theme="dark"
data-lang="en"
crossorigin="anonymous"
async
></script>
<section id="extras">
<div class="blogroll">
<ul>
<li><a href="https://www.conwaylife.com/">Conwaylife.com Forums</a></li>
<li><a href="https://www.python.org/">Python</a></li>
<li><a href="http://www.ulisp.com/">uLisp</a></li>
</ul>
</div>
<div class="social">
<ul>
<li><a href="https://github.com/dragoncoder047">dragoncoder047 on GitHub</a></li>
<li><a href="https://youtube.com/@dragoncoder047">dragoncoder047 on YouTube</a></li>
<li><a href="https://instagram.com/dragoncoder047/">dragoncoder047 on Instagram</a></li>
</ul>
</div>
</section>
</main>
<footer>
<address>
Site built by <a href="https://getpelican.com/">Pelican</a>
</address>
<a href="#" onclick="window.scrollTo({top: 0, left: 0});">Back to top</a>
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XR0F89CCGK"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag("js", new Date());
gtag("config", "G-XR0F89CCGK");
</script>
</footer>
</body>
</html>