Instantly share code, notes, and snippets.
Last active
February 13, 2022 16:11
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
-
Save nfreear/e3bbf762ebd5f6f1d69139326e7d50a5 to your computer and use it in GitHub Desktop.
A language-switch menu based on radio buttons.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!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'; /* */ | |
| 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