logo

Grimgrains

Unnamed repository; edit this file 'description' to name the repository.
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:

Mindex.html6+++---
Mlinks/main.css31+++++++++++++++++++------------
Mscripts/graph.js14+++++++-------
Mscripts/helpers.js9++++++++-
Mscripts/templates/home.js5+++--
Mscripts/templates/ingredient.js8+++++---
Mscripts/templates/recipe.js10++++++----
Mscripts/templates/service.js2+-
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>