Skip to content

Commit

Permalink
Use actual buttons for "UI" controls
Browse files Browse the repository at this point in the history
This makes these controls accessible from keyboard navigation.

The DOM structure needed to be changed a bit to avoid the
overflow:hidden style on the .expandable component from eating up the
focus outline.
  • Loading branch information
epidemian committed Nov 7, 2023
1 parent 4b6da22 commit e9d5591
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 46 deletions.
25 changes: 11 additions & 14 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,21 @@
</head>
<noscript>⚠ Sorry, this game requires JavaScript.</noscript>
<div id=url-container class=invisible>URL: <span id=url></span></div>
<input type=checkbox id=help-checkbox class=expandable-checkbox>
<label for=help-checkbox class=expandable>
<div class=expandable-content>
<span class="help-toggle expand-toggle">?</span>
<div class=expandable>
<button class="help-toggle expand-btn" aria-label=Help>?</button>
<div class="expandable-content hidden">
<span class=no-touch-only>Use the arrow keys or WASD to control the snake on the URL.</span>
<span class=touch-only>Use the arrows to control the snake on the URL.</span>
<a id=reveal-url href=#>Click here</a> if you can't see the page URL<span id=url-escaping-note class=invisible> or if it looks messed up with <span id=replacement-char-description></span></span>.&nbsp;<span class=collapse-toggle></span>
<a id=reveal-url href=#>Click here</a> if you can't see the page URL<span id=url-escaping-note class=invisible> or if it looks messed up with <span id=replacement-char-description></span></span>.&nbsp;<button class=collapse-btn aria-label=Hide></button>
</div>
</label>
<input type=checkbox id=max-score-checkbox class=expandable-checkbox>
<label for=max-score-checkbox id=max-score-container class="expandable invisible">
<div class=expandable-content>
<span class="high-score-toggle expand-toggle">!</span>
</div>
<div id=max-score-container class="expandable invisible">
<button class="high-score-toggle expand-btn" aria-label="Max score">!</button>
<div class="expandable-content hidden">
Your highest score is <span id=max-score></span> points!
<span id=max-score-grid></span><a id=share class=invisible href=#><i class=icon-share></i>Share</a>&nbsp;<span class=collapse-toggle></span>
</div>
</head>
</label>
<span id=max-score-grid></span><a id=share class=invisible href=#><i class=icon-share></i>Share</a>&nbsp;<button class=collapse-btn aria-label=Hide></button>
</div>
</div>
<div class="controls touch-only">
<button id=up>▲&#xFE0E;</button>
<button id=left>◀&#xFE0E;</button>
Expand Down
22 changes: 21 additions & 1 deletion snake.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,25 @@ function setupEventHandlers() {
e.preventDefault();
setUrlRevealed(!urlRevealed);
};

document.querySelectorAll('.expandable').forEach(function (expandable) {
var expand = expandable.querySelector('.expand-btn');
var collapse = expandable.querySelector('.collapse-btn');
var content = expandable.querySelector('.expandable-content');
expand.onclick = collapse.onclick = function () {
expand.classList.remove('hidden');
content.classList.remove('hidden');
expandable.classList.toggle('expanded');
};
// Hide the expand button or the content when the animation ends so those
// elements are not interactive anymore.
// Surely there's a way to do this with CSS animations more directly.
expandable.ontransitionend = function () {
var expanded = expandable.classList.contains('expanded');
expand.classList.toggle('hidden', expanded);
content.classList.toggle('hidden', !expanded);
};
});
}

function initUrlRevealed() {
Expand Down Expand Up @@ -300,7 +319,8 @@ function drawMaxScore() {
// Expands the high score details if collapsed. Only done when beating the
// highest score, to grab the player's attention.
function showMaxScore() {
$('#max-score-checkbox').checked = true;
if ($('#max-score-container.expanded')) return
$('#max-score-container .expand-btn').click();
}

function shareScore(score, grid) {
Expand Down
64 changes: 33 additions & 31 deletions style.css
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ body {
min-height: 100%;
display: flex;
flex-direction: column;
padding: 5px 10px;
align-items: flex-start;
gap: 4px;
padding: 10px;
}

a {
Expand Down Expand Up @@ -89,43 +91,51 @@ footer {
display: none !important;
}

.hidden {
visibility: hidden;
}

:root.touch .no-touch-only,
:root:not(.touch) .touch-only {
display: none;
}

/* Expandable "component". Uses the checkbox hack to expand and collapse their
content without JS */
.expandable {
overflow: hidden;
position: relative;
}

.expandable-checkbox {
display: none;
.expand-btn,
.collapse-btn {
background: none;
border: none;
padding: 0;
font: inherit;
font-weight: bold;
cursor: pointer;
width: 1rem;
}

.expandable-content,
.expand-toggle,
.collapse-toggle {
transition: all .4s;
.expand-btn,
.expandable {
transition: transform, opacity;
transition-duration: .4s;
}

.expandable-content {
.expandable {
display: inline-block;
position: relative;
height: 1.5rem;
transform: translateX(-100%);
/* Clear body padding so it doesn't show on the left of the expand-btn */
padding-right: 10px;
}

.expand-toggle {
.expand-btn {
position: absolute;
right: 0;
top: 0;
transform: translateX(100%);
}

.expand-toggle,
.collapse-toggle {
font-weight: bold;
cursor: pointer;
opacity: 1;
}

.help-toggle {
Expand All @@ -136,24 +146,16 @@ footer {
color: #ff8c0b;
}

.collapse-toggle {
.collapse-btn {
color: #aaa;
opacity: 0;
}

.expandable-checkbox:not(:checked) + .expandable {
max-height: 1.5rem;
}

.expandable-checkbox:not(:checked) + .expandable .expandable-content {
transform: translateX(-100%);
}

.expandable-checkbox:checked + .expandable .collapse-toggle {
opacity: 1;
.expandable.expanded {
height: auto;
transform: none;
}

.expandable-checkbox:checked + .expandable .expand-toggle {
.expandable.expanded .expand-btn {
opacity: 0;
}

Expand Down

0 comments on commit e9d5591

Please sign in to comment.