Skip to content

Instantly share code, notes, and snippets.

@nfreear
Last active February 13, 2022 16:11
Show Gist options
  • Select an option

  • Save nfreear/e3bbf762ebd5f6f1d69139326e7d50a5 to your computer and use it in GitHub Desktop.

Select an option

Save nfreear/e3bbf762ebd5f6f1d69139326e7d50a5 to your computer and use it in GitHub Desktop.
A language-switch menu based on radio buttons.
<!doctype html><html lang="en"><title> Language menu </title>
<meta charset="utf-8" />
<style>
body > * { margin: 1rem auto; max-width: 32rem; }
main { font: 1.1rem/1.6 sans-serif; }
button { cursor: pointer; font: inherit; }
ul { list-style: none; padding: 0; }
.X-ul,
details,
#lang-form {
background: #fcfcfc;
border: 1px solid #bbb;
border-radius: .2rem;
width: 12rem;
list-style: none;
padding: 2px;
margin: 1rem 0;
}
#lang-form label { cursor: pointer; display: block; }
#lang-form label:hover {
background: #ddd;
}
#lang-form label.checked {
background: #ddd;
outline: 2px solid teal;
outline-offset: 2px;
X-box-shadow: 0 1px 1px 0 0 4px blue;
transition: all .3s;
}
#lang-form input {
height: 1rem;
width: .1px;
X-overflow: hidden;
outline: none;
margin-right: 2rem;
}
.X-input {
opacity: .1;
X-margin-right: 1rem;
}
input:hover,
.X-input:focus {
opacity: .9;
transition: all .3s;
}
/* label:after {
content: '(' attr(lang) ')';
font-size: x-small;
} */
/* input:after {
content: attr(value);
} */
/* label.checked:after {
content: '✔️';
color: red;
float: right;
} */
.X-input:focus:after {
background: gray;
}
#lang-form input:checked:after {
content: '\2611'; /* '\2713'; /* '☑'; /* Emoji '✔️'; */
font-size: 1.7rem;
color: teal;
position: relative;
top: -.65rem;
}
#lang-buttons button {
background: #fcfcfc;
border: 1px solid #eee;
border-radius: 0;
line-height: 1;
padding: .5rem;
width: 100%;
}
#lang-buttons :hover {
background: #ddd;
border-color: #ccc;
}
#lang-buttons button:after {
content: '\A0'; /* &nbsp; */
font-size: 1.3rem;
float: right;
width: 1rem;
}
.lang-buttons [ aria-checked ]:after,
#X_lang-buttons [ aria-checked ]:after {
content: '\2611';
color: #d00;
}
#X_lang-buttons :focus {
outline-offset: 1px;
}
summary {
padding-left: .5rem;
X-list-style-type: circle;
}
summary::marker {
color: blue;
font-size: 1.4rem;
}
details {
box-shadow: 3px 3px 4px black;
}
</style>
<main>
<h1> Language menu </h1>
<p><a href="#">Link before</a></p>
<details id="lang-buttons" open >
<summary> English </summary>
<form X-action="#" >
<ul>
<li><button value="en" name=lang aria-checked="true">English</button></li>
<li><button value=zh-Hans name=lang aria-label="Simplified" >简体中文</button></li> <!-- Jiǎntǐ zhōngwén -->
<li><button value=zh-Hant name=lang aria-label="Traditional">繁體中文</button></li> <!-- Fántǐ zhōngwén -->
<li><button value="fr" name=lang >français</button></li>
<li><button value="es-ES" name=lang aria-label="Castilian" >Español</button></li>
</ul>
</form>
</details>
<!--
<form id="lang-buttons" class="lang-buttons" aria-label="Change Language">
<ul>
<li><button lang="en" >English</button></li>
<li><button lang="zh-Hans" aria-label="Simplified" >简体中文</button></li> <!-- Jiǎntǐ zhōngwén -/->
<li><button lang="zh-Hant" aria-label="Traditional">繁體中文</button></li> <!-- Fántǐ zhōngwén -/->
<li><button lang="fr" >français</button></li>
<li><button lang="es-ES" aria-label="Castilian" >Español</button></li>
</ul>
</form>
-->
<hr>
<form id="lang-form" aria-label="Language Switch">
<label lang="en" ><input type="radio" name="lc" value="en" checked >English </label>
<label lang="zh-Hans"><input type="radio" name="lc" value="zh-Hans" aria-label="Simplified" >简体中文 </label>
<label lang="zh-Hant"><input type="radio" name="lc" value="zh-Hant" aria-label="Traditional">繁體中文 </label>
<label lang="fr" ><input type="radio" name="lc" value="fr" >français</label>
<label lang="es-ES" ><input type="radio" name="lc" value="es-ES" aria-label="Castilian" >Español </label>
<!-- <button type="submit" >Switch</button> -->
</form>
<p><a href="#">Link after</a></p>
</main>
<script type="module">
const langForm = document.querySelector('#lang-form');
const labels = langForm.querySelectorAll('label');
langForm.addEventListener('change', ev => {
let lang;
[...labels].forEach(label => {
const radio = label.querySelector('input');
label.className = radio.checked ? 'checked' : '';
if (radio.checked) { lang = radio.value; }
});
console.log('Lang form change:', lang, ev);
});
// langForm.dispatchEvent(new Event('change'));
/* langForm.addEventListener('submit', ev => {
ev.preventDefault();
const radios = ev.target.querySelectorAll('input[ type = radio ]');
// const lang = checked ? checked.value : null;
const lang = [...radios].find(radio => radio.checked); // { if(radio.checked) return radio.value });
console.warn('Lang form submit:', lang.value, ev);
}); */
</script>
<script type="module">
// const langMenu = document.querySelector('#lang-buttons');
const langMenu = document.querySelector('#lang-buttons form');
const langButtons = langMenu.querySelectorAll('button');
langMenu.addEventListener('click', ev => {
ev.preventDefault();
if (ev.target.nodeName !== 'BUTTON') { return; }
const BTN = ev.target;
const lang = BTN.value; // BTN.lang;
const name = BTN.textContent;
langButtons.forEach(btn => btn.removeAttribute('aria-checked'));
BTN.setAttribute('aria-checked', 'true');
console.warn('Lang button click:', lang, name, ev);
});
</script>
<pre>
NDF, 22-Nov-2021
</pre>
<!--
https://translate.google.com/?sl=auto&tl=zh-CN&text=Simplified%20Chinese.%0ATraditional%20Chinese.&op=translate;
https://css-tricks.com/almanac/properties/b/box-shadow/
https://stackoverflow.com/questions/658044/tick-symbol-in-html-xhtml
-->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment