commit: ba7722e166ff3244624153bbb2625b6fe01ef7d0
parent 0fc6c3394376f432bed62a65ceb3c69ded5e3d86
Author: Лu Лinveгa <aliceffekt@gmail.com>
Date: Thu, 12 Dec 2019 06:55:17 -0500
Merge pull request #28 from microlith57/feature/accessibility
Better accessibility
Diffstat:
8 files changed, 52 insertions(+), 33 deletions(-)
diff --git a/index.html b/index.html
@@ -16,7 +16,7 @@
<meta property="og:type" content="article" />
<meta property="og:url" content="http://grimgrains.com/" />
<meta property="og:image" content="https://grimgrains.com/media/services/icon.jpg" />
- <meta property="og:description" content="An illustrated food blog." />
+ <meta property="og:description" content="An illustrated food blog." />
<meta property="og:site_name" content="Grimgrains" />
<script type="text/javascript" src="scripts/helpers.js"></script>
@@ -32,7 +32,7 @@
<script type="text/javascript" src="scripts/nodes/template.js"></script>
<script type="text/javascript" src="scripts/nodes/dom.js"></script>
<script type="text/javascript" src="scripts/nodes/document.js"></script>
-
+
<script type="text/javascript" src="scripts/database/ingredients.ndtl"></script>
<script type="text/javascript" src="scripts/database/recipes.ndtl"></script>
<script type="text/javascript" src="scripts/database/pages.ndtl"></script>
@@ -75,7 +75,7 @@
}
</script>
-
+
<noscript>
<h2 style="color:white">
This website requires Javascript. To view the content, please enable it in your browser settings.
diff --git a/links/main.css b/links/main.css
@@ -13,20 +13,20 @@ h1,h2,h3,h4 { font-weight: normal; font-family: 'alte_haas_grotesk_bold'; margin
#view.ready { opacity: 1; transition: opacity 250ms }
#view.ready #header #photo { opacity: 1 }
-#view #header { }
#view #header #logo a { cursor: pointer; transition: all 250ms; }
#view #header #logo a:hover { opacity: 0.7 }
+#view #header #logo a:focus { opacity: 0.7 }
#view #header #logo a img { max-width: 240px; display: block; margin:0px auto; margin-bottom:30px; }
-#view #header ul { display: block;line-height: 40px; border-bottom: 2px solid black; margin-bottom:30px; overflow: hidden;height: 40px; }
+#view #header ul { display: block;line-height: 40px; border-bottom: 2px solid black; margin-bottom:30px; overflow: hidden;min-height: 40px; }
#view #header ul li { display: inline-block;border-top-left-radius: 3px;border-top-right-radius: 3px; margin-right:10px; margin-bottom: -2px; line-height: 40px}
-#view #header ul li:hover { }
#view #header ul li a { display: inline-block; font-family: 'alte_haas_grotesk_bold'; font-size:14px; line-height: 40px; border-bottom:2px solid transparent }
-#view #header ul li a:hover { opacity: 1 !important; }
#view #header ul li.right { float: right;margin-right:0px;margin-left:10px }
#view #header #search { display: none }
-#view.home #header ul a.home { color:#ccc;}
-#view.about #header ul a.about { color:#ccc;}
-#view.tools #header ul a.tools { color:#ccc;}
+#view.home #header ul a.home,
+#view.about #header ul a.about,
+#view.tools #header ul a.tools,
+#view.gallery #header ul a.gallery,
+#view.nutrition #header ul a.nutrition { color: #333; }
#view #core { margin-bottom:30px; }
@@ -42,6 +42,7 @@ h1,h2,h3,h4 { font-weight: normal; font-family: 'alte_haas_grotesk_bold'; margin
#view #core #content p.bref { font-size:28px; margin-bottom: 45px; line-height: 34px }
#view #core #content p a { font-weight: bold; cursor: pointer; text-decoration: underline; }
#view #core #content p a:hover { text-decoration: none; }
+#view #core #content p a:focus { text-decoration: dotted underline; }
#view #core #content p a.external:after { content:"*"; color:#999; }
#view #core #content p b { font-weight: bold; }
#view #core #content img { margin-bottom: 30px; border-radius: 2px }
@@ -63,6 +64,7 @@ h1,h2,h3,h4 { font-weight: normal; font-family: 'alte_haas_grotesk_bold'; margin
#view #core #content #instructions note { max-width:700px; margin-bottom:15px; font-size:18px; padding-left:30px; display: block; font-style: italic; font-size:14px; margin-bottom:30px; }
#view #core #content #instructions a { font-weight: bold; }
#view #core #content #instructions a:hover { text-decoration: underline; cursor: pointer }
+#view #core #content #instructions a:focus { text-decoration: underline; cursor: pointer }
#view #core #content #instructions i { background: #eee;font-size: 12px;text-transform: uppercase;padding: 5px 7.5px;display: inline-block;font-weight: bold;border-radius: 3px;color: #333;line-height: 15px }
#view #core #content #instructions code { font-size: 12px;text-transform: uppercase;padding: 3px 5.5px;display: inline-block;font-weight: bold;border-radius: 3px;border: 2px solid black;line-height: 15px}
@@ -72,7 +74,8 @@ h1,h2,h3,h4 { font-weight: normal; font-family: 'alte_haas_grotesk_bold'; margin
#view #core #content ul.ingredients { display: inline-block; margin-right:15px; font-size:0; padding-left:20px; margin-bottom:30px; }
#view #core #content ul.ingredients h3 { margin-left:-20px; }
#view #core #content ul.ingredients li.ingredient { width: 100px;margin-left:-20px;min-height: 210px;display: inline-block;text-align: center;vertical-align: top;border: 2px dashed transparent;border-radius: 10px; }
-#view #core #content ul.ingredients li.ingredient:hover span.name { text-decoration: underline; }
+#view #core #content ul.ingredients li.ingredient a:hover span.name { text-decoration: underline; }
+#view #core #content ul.ingredients li.ingredient a:focus span.name { text-decoration: underline; border: 1px dotted black; }
#view #core #content ul.ingredients li.ingredient.missing span.name { font-style: italic }
#view #core #content ul.ingredients li.ingredient img { max-width: 100%; display: block }
#view #core #content ul.ingredients li.ingredient span.name { display: block; font-family: 'alte_haas_grotesk_bold'; font-size:14px; margin-bottom: 5px;padding:0px 10px }
@@ -85,18 +88,22 @@ h1,h2,h3,h4 { font-weight: normal; font-family: 'alte_haas_grotesk_bold'; margin
#view #core #related { width:100%;}
#view #core #related li { width: calc((100% / 3) - 10px); float:left; overflow: hidden;}
-#view #core #related li:nth-child(1), #view #core #related li:nth-child(2) { margin-right:15px;}
-#view #core #related li a.photo { border-radius: 2px; display: block; height:160px; background-size:cover; margin-bottom:15px; background-position: center }
-#view #core #related li span.name { display: block; font-family: 'alte_haas_grotesk_bold'; font-size:16px; margin-bottom: 5px; text-transform: capitalize; line-height: 30px }
+#view #core #related li:nth-child(1), #view #core #related li:nth-child(2) { margin-right:15px;}
+#view #core #related li a .photo { border-radius: 2px; display: block; width:100%; height:160px; background-size:cover; margin-bottom:15px; background-position: center }
+#view #core #related li a span.name { display: block; font-family: 'alte_haas_grotesk_bold'; font-size:16px; margin-bottom: 5px; text-transform: capitalize; line-height: 30px }
+#view #core #related li a:hover span.name { text-decoration: underline; cursor: pointer }
+#view #core #related li a:focus span.name { text-decoration: underline; cursor: pointer }
#view #core #related li span.details { display: block; font-family: 'alte_haas_grotesk_regular'; font-size:14px; text-transform: capitalize; line-height: 30px; line-height: 18px }
#view #core #content #recipes { columns:3; font-size:14px; font-weight: bold}
#view #core #content #recipes li { display: block }
-#view #core #content #recipes li a:hover { text-decoration: underline; cursor: pointer; }
+#view #core #content #recipes li a:hover { text-decoration: underline; cursor: pointer; opacity: 1; }
+#view #core #content #recipes li a:focus { text-decoration: underline; cursor: pointer; opacity: 1; }
#view #core #content #recipes h3 { margin-bottom:10px; }
#view #footer { display: block; padding:15px 0px;font-family: 'alte_haas_grotesk_bold'; font-size:14px; margin-top:60px; }
#view #footer a:hover { text-decoration: underline; cursor: pointer }
+#view #footer a:focus { text-decoration: underline; cursor: pointer }
@media (max-width: 850px) {
#view #core #content #recipes { columns:1; }
diff --git a/scripts/graph.js b/scripts/graph.js
@@ -25,19 +25,19 @@ function graph () {
Ø('view').create({ x: 2, y: 6 }, DomNode),
Ø('header').create({ x: 2, y: 11 }, DomNode),
Ø('logo').create({ x: 2, y: 16 }, DomNode, 'wr', `
- <a href='index.html'><img src='media/interface/logo.png'/></a>
+ <a href='index.html'><img src='media/interface/logo.png' alt='Grimgrains'/></a>
<ul>
- <li><a class="local home" onclick="Ø('query').bang('Home')">Home</a></li>
- <li><a class="local about" onclick="Ø('query').bang('About')">About</a></li>
- <li><a class="local tools" onclick="Ø('query').bang('Tools')">Tools</a></li>
- <li><a class="local gallery" onclick="Ø('query').bang('gallery')">Gallery</a></li>
- <li><a class="local nutrition" onclick="Ø('query').bang('nutrition')">Nutrition</a></li>
+ <li><a class="local home" href="#home">Home</a></li>
+ <li><a class="local about" href="#about">About</a></li>
+ <li><a class="local tools" href="#tools">Tools</a></li>
+ <li><a class="local gallery" href="#gallery">Gallery</a></li>
+ <li><a class="local nutrition" href="#nutrition">Nutrition</a></li>
<li class='right'><a href='http://twitter.com/grimgrains' target='_blank'>Twitter</a></li>
</ul>`.to_markup()),
Ø('core').create({ x: 10, y: 11 }, DomNode),
Ø('content').create({ x: 10, y: 16 }, DomNode),
Ø('related').create({ x: 14, y: 16 }, DomNode, 'ul'),
- Ø('footer').create({ x: 6, y: 11 }, DomNode, 'wr', '<a onclick="Ø(\'query\').bang(\'about\')">Grimgrains</a> © 2014—2019<br/><a href=\'http://100r.co/\' target=\'_blank\'>Hundred Rabbits</a>')
+ Ø('footer').create({ x: 6, y: 11 }, DomNode, 'wr', '<a href="#about">Grimgrains</a> © 2014—2019<br/><a href="http://100r.co/" target="_blank">Hundred Rabbits</a>')
])
// Model
diff --git a/scripts/helpers.js b/scripts/helpers.js
@@ -1,4 +1,3 @@
-
String.prototype.capitalize = function () {
return this.charAt(0).toUpperCase() + this.slice(1).toLowerCase()
}
@@ -31,3 +30,10 @@ String.prototype.to_markup = function () {
}
return html
}
+
+function Š (target) {
+ const elem = document.getElementById('jump-' + target)
+ if (!elem) { console.error('Undefined jump target', target); return }
+ elem.scrollIntoView()
+ elem.focus()
+}+
\ No newline at end of file
diff --git a/scripts/templates/home.js b/scripts/templates/home.js
@@ -13,8 +13,9 @@ function HomeTemplate (id, rect) {
const sorted_ingredients = sort_ingredients(ingredients)
const html = `
+ <h1>Ingredients <a class='jump' id='jump-ingredients' href='javascript:Š("recipes")'>recipes</a></h1>
${make_ingredients(sorted_ingredients, q.tables.ingredients)}
- <h1>Recipes</h1>
+ <h1 id='recipes_header'>Recipes <a class='jump' id='jump-recipes' href='javascript:Š("ingredients")'>ingredients</a></h1>
${make_recipes(q.tables.recipes)}
`
return {
@@ -60,7 +61,7 @@ function HomeTemplate (id, rect) {
const name = ingredients[id][0]
html += `
<li class='ingredient${!table[name] ? ' missing' : ''}'>
- <a href='#${name.to_url()}' onclick="Ø('query').bang('${name}')">
+ <a href='#${name.to_url()}'>
<img src='media/ingredients/${name.to_path()}.png'/>
<span class='name'>${name.capitalize()}</span>
</a>
diff --git a/scripts/templates/ingredient.js b/scripts/templates/ingredient.js
@@ -118,8 +118,10 @@ function IngredientTemplate (id, rect) {
const name = id
html += `
<li class='recipe'>
- <a onclick="Ø('query').bang('${name}')" class='photo' href='#${name.to_url()}' style='background-image:url(media/recipes/${name.to_path()}.jpg)'></a>
- <span class='name'>${name.capitalize()}</span>
+ <a href='#${name.to_url()}'>
+ <div class='photo' style='background-image:url(media/recipes/${name.to_path()}.jpg)'></div>
+ <span class='name'>${name.capitalize()}</span>
+ </a>
<span class='details'><b>${recipe.TIME} minutes</b><br />${count_ingredients(recipe)} ingredients<br />${recipe.INST.length} steps</span>
</li>`
if (count > 1) { break }
@@ -170,7 +172,7 @@ function IngredientTemplate (id, rect) {
function print_ingredient (name) {
return `
<li class='ingredient'>
- <a onclick="Ø('query').bang('${name}')" href='#${name.to_url()}'>
+ <a href='#${name.to_url()}'>
<img src='media/ingredients/${name.to_path()}.png'/>
<span class='name'>${name.capitalize()}</span>
</a>
diff --git a/scripts/templates/recipe.js b/scripts/templates/recipe.js
@@ -106,8 +106,10 @@ function RecipeTemplate (id, rect) {
const recipe = q.tables.recipes[name]
html += `
<li class='recipe'>
- <a class='photo' onclick="Ø('query').bang('${name}')" href='#${name.to_url()}' style='background-image:url(media/recipes/${name.to_path()}.jpg)'></a>
- <span class='name'>${name.capitalize()}</span>
+ <a href='#${name.to_url()}'>
+ <div class='photo' style='background-image:url(media/recipes/${name.to_path()}.jpg)'></div>
+ <span class='name'>${name.capitalize()}</span>
+ </a>
<span class='details'><b>${recipe.TIME} minutes</b><br />${count_ingredients(recipe)} ingredients<br />${Object.keys(recipe.INST).length} step${Object.keys(recipe.INST).length > 1 ? 's' : ''}</span>
</li>`
if (count > 1) { break }
@@ -152,10 +154,10 @@ function RecipeTemplate (id, rect) {
const element = elements[name]
html += `
<li class='ingredient'>
- <a onclick="Ø('query').bang('${name}')" href='#${name.to_url()}'>
+ <a href='#${name.to_url()}'>
<img src='media/ingredients/${name.to_path()}.png'/>
+ <span class='name'>${name.capitalize()}</span>
</a>
- <span class='name'>${name.capitalize()}</span>
<span class='quantity'>${element}</span>
</li>`
}
diff --git a/scripts/templates/service.js b/scripts/templates/service.js
@@ -97,7 +97,7 @@ function ServiceTemplate (id, rect) {
const name = ingredients[id][0]
html += `
<li class='ingredient${!table[name] ? ' missing' : ''}'>
- <a href='#${name.to_url()}' onclick="Ø('query').bang('${name}')">
+ <a href='#${name.to_url()}'>
<img src='media/ingredients/${name.to_path()}.png'/>
<span class='name'>${name.capitalize()}</span>
</a>