Taalkeuze NL / EN zonder vlaggen New
Language switch for a bilingual site, without flags: a flag stands for a country, not a language. In the header a button with the language code opens a list where each language is written in itself (Nederlands, English) with lang and hreflang attributes, and the same choice sits at the bottom as plain text links. Choosing swaps the content with a short transition, sets lang on the page and is remembered. Arrows and Esc work in the list. In production you link to the actual translated page instead of swapping text.
Elke ochtend vers brood in Haarlem
Open vanaf 7:00 aan de Botermarkt. Bestel voor 20:00, dan ligt het morgen klaar.
Taal: Nederlands English
How to use it
- Paste the HTML where the navigation & menus should appear.
- Add the CSS to your stylesheet. All classes are prefixed, so nothing clashes with your own styles.
- Add the JavaScript and call init() with the element that contains the HTML.
<!-- Taalkeuze NL / EN zonder vlaggen · NedDev · eigen werk. -->
<div class="jouw-container">
<div class="tkn" lang="nl">
<header class="tkn__head">
<a class="tkn__logo" href="#tkn">Bakkerij Verbeek</a>
<nav class="tkn__nav" aria-label="Hoofdmenu"><a href="#tkn-1" data-nl="Assortiment" data-en="Our bread">Assortiment</a><a href="#tkn-2" data-nl="Bestellen" data-en="Order">Bestellen</a><a href="#tkn-3" data-nl="Contact" data-en="Contact">Contact</a></nav>
<div class="tkn__lang">
<button class="tkn__btn" type="button" aria-expanded="false" aria-controls="tkn-list" aria-label="Taal: Nederlands. Kies een andere taal"><svg viewBox="0 0 16 16" aria-hidden="true"><circle cx="8" cy="8" r="6"/><path d="M2 8h12M8 2c1.8 1.8 2.6 3.8 2.6 6S9.8 12.2 8 14M8 2C6.2 3.8 5.4 5.8 5.4 8s.8 4.2 2.6 6"/></svg><span class="tkn__code">NL</span><svg class="tkn__chev" viewBox="0 0 16 16" aria-hidden="true"><path d="M4 6l4 4 4-4"/></svg></button>
<ul class="tkn__list" id="tkn-list" hidden>
<li><a class="tkn__opt" href="?taal=nl" hreflang="nl" lang="nl" data-l="nl" aria-current="true"><span>Nederlands</span><span class="tkn__c">NL</span></a></li>
<li><a class="tkn__opt" href="?taal=en" hreflang="en" lang="en" data-l="en"><span>English</span><span class="tkn__c">EN</span></a></li>
</ul>
</div>
</header>
<div class="tkn__body">
<h3 class="tkn__h" data-nl="Elke ochtend vers brood in Haarlem" data-en="Fresh bread in Haarlem every morning">Elke ochtend vers brood in Haarlem</h3>
<p class="tkn__p" data-nl="Open vanaf 7:00 aan de Botermarkt. Bestel voor 20:00, dan ligt het morgen klaar." data-en="Open from 7:00 at the Botermarkt. Order before 20:00 and it is ready tomorrow.">Open vanaf 7:00 aan de Botermarkt. Bestel voor 20:00, dan ligt het morgen klaar.</p>
</div>
<p class="tkn__foot"><span data-nl="Taal:" data-en="Language:">Taal:</span> <a class="tkn__fl" href="?taal=nl" hreflang="nl" lang="nl" data-l="nl" aria-current="true">Nederlands</a> <a class="tkn__fl" href="?taal=en" hreflang="en" lang="en" data-l="en">English</a></p>
<p class="tkn__sr" aria-live="polite"></p>
</div>
</div>/* Taalkeuze NL / EN zonder vlaggen · NedDev · eigen werk. */
.tkn{position:absolute;inset:0;display:flex;flex-direction:column;background:#fff;color:#0a0a0a;font-family:'Switzer',sans-serif;text-align:left;container-type:inline-size}
.tkn *,.tkn *::before,.tkn *::after{box-sizing:border-box}
.tkn__head{position:relative;z-index:2;display:flex;align-items:center;gap:14px;height:52px;padding:0 12px 0 16px;border-bottom:1px solid rgba(10,10,10,.1)}
.tkn__logo{font:700 15px/1 'Switzer',sans-serif;color:#0a0a0a;text-decoration:none;white-space:nowrap;padding:5px 0}
.tkn__nav{display:flex;gap:2px;margin-left:auto}
.tkn__nav a{padding:6px 7px;border-radius:4px;color:#3a3733;text-decoration:none;font:500 13px/1.1 'Switzer',sans-serif;white-space:nowrap}
.tkn__nav a:hover{color:#0a0a0a;background:#f4f3f1}
.tkn a:focus-visible,.tkn__btn:focus-visible{outline:2px solid #F5480F;outline-offset:2px}
.tkn__lang{position:relative}
.tkn__btn{display:flex;align-items:center;gap:5px;height:32px;margin:0;padding:0 8px;border:1px solid #0a0a0a;border-radius:4px;background:#fff;color:#0a0a0a;font:600 13px/1 'Switzer',sans-serif;cursor:pointer}
.tkn__btn svg{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:1.4;stroke-linecap:round;stroke-linejoin:round}
.tkn__btn .tkn__chev{width:12px;height:12px;stroke-width:2;transition:transform .2s}
.tkn__btn[aria-expanded="true"]{background:#0a0a0a;color:#fff}
.tkn__btn[aria-expanded="true"] .tkn__chev{transform:rotate(180deg)}
.tkn__list{position:absolute;right:0;top:calc(100% + 6px);min-width:170px;margin:0;padding:4px;list-style:none;background:#fff;border:1px solid rgba(10,10,10,.14);border-radius:8px;box-shadow:0 14px 30px -12px rgba(10,10,10,.35);animation:tknIn .14s ease-out}
.tkn__list[hidden]{display:none}
@keyframes tknIn{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}
.tkn__opt{display:flex;align-items:center;justify-content:space-between;gap:12px;min-height:32px;padding:6px 10px;border-radius:4px;color:#0a0a0a;text-decoration:none;font:400 14px/1 'Switzer',sans-serif}
.tkn__opt:hover,.tkn__opt:focus{background:#f4f3f1;outline:none}
.tkn__opt:focus-visible{box-shadow:inset 0 0 0 2px #F5480F}
.tkn__opt[aria-current="true"]{font-weight:600}
.tkn__opt[aria-current="true"] .tkn__c{background:#F5480F;color:#0a0a0a}
.tkn__c{padding:3px 5px;border-radius:4px;background:#f4f3f1;color:#57534e;font:600 12px/1 'Switzer',sans-serif}
.tkn__body{flex:1;padding:16px 16px 0;transition:opacity .18s,transform .18s}
.tkn.is-swap .tkn__body,.tkn.is-swap .tkn__nav{opacity:0;transform:translateY(4px)}
.tkn__nav{transition:opacity .18s,transform .18s}
.tkn__h{margin:0 0 6px;font:600 21px/1.15 'Switzer',sans-serif;letter-spacing:-.02em;max-width:18em;text-wrap:balance}
.tkn__p{margin:0;font:400 14px/1.45 'Switzer',sans-serif;color:#3a3733;max-width:34em}
.tkn__foot{display:flex;align-items:center;gap:6px;margin:0;padding:6px 16px 10px;font:400 13px/1 'Switzer',sans-serif;color:#57534e}
.tkn__fl{display:inline-flex;align-items:center;min-height:26px;padding:0 4px;color:#0a0a0a;text-decoration:underline;text-decoration-color:rgba(10,10,10,.3);text-underline-offset:3px}
.tkn__fl[aria-current="true"]{text-decoration-color:#F5480F;text-decoration-thickness:2px;font-weight:600}
.tkn__sr{position:absolute;width:1px;height:1px;margin:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
@container (max-width:400px){.tkn__nav{display:none}.tkn__lang{margin-left:auto}.tkn__h{font-size:19px}}
@media (prefers-reduced-motion:reduce){.tkn__body,.tkn__nav,.tkn__btn .tkn__chev{transition:none}.tkn__list{animation:none}}// Taalkeuze NL / EN zonder vlaggen · NedDev · eigen werk.
// root = het element waarin de HTML staat
function init(root){
var w=root.querySelector('.tkn');if(!w)return;
var btn=w.querySelector('.tkn__btn'),list=w.querySelector('.tkn__list'),opts=[].slice.call(list.querySelectorAll('.tkn__opt')),sr=w.querySelector('.tkn__sr'),code=w.querySelector('.tkn__code'),KEY='tkn-taal';
var NAME={nl:'Nederlands',en:'English'},rm=matchMedia('(prefers-reduced-motion: reduce)').matches;
function close(back){if(list.hidden)return;list.hidden=true;btn.setAttribute('aria-expanded','false');if(back)btn.focus();}
function openL(){list.hidden=false;btn.setAttribute('aria-expanded','true');(list.querySelector('[aria-current="true"]')||opts[0]).focus();}
function apply(l,announce){var swap=function(){w.setAttribute('lang',l);[].forEach.call(w.querySelectorAll('[data-nl]'),function(el){el.textContent=el.getAttribute('data-'+l);});
[].forEach.call(w.querySelectorAll('[data-l]'),function(a){if(a.getAttribute('data-l')===l)a.setAttribute('aria-current','true');else a.removeAttribute('aria-current');});
code.textContent=l.toUpperCase();btn.setAttribute('aria-label',l==='nl'?'Taal: Nederlands. Kies een andere taal':'Language: English. Choose another language');
if(announce)sr.textContent=l==='nl'?'Taal gewijzigd naar Nederlands':'Language changed to English';};
if(rm||!announce){swap();return;}w.classList.add('is-swap');setTimeout(function(){swap();w.classList.remove('is-swap');},180);}
function choose(l){try{localStorage.setItem(KEY,l);}catch(e){}apply(l,true);}
btn.addEventListener('click',function(){if(list.hidden)openL();else close(true);});
w.addEventListener('click',function(e){var a=e.target.closest('[data-l]');if(!a)return;e.preventDefault();var l=a.getAttribute('data-l');var fromList=list.contains(a);close(fromList);if(w.getAttribute('lang')!==l)choose(l);});
list.addEventListener('keydown',function(e){var i=opts.indexOf(document.activeElement);if(e.key==='ArrowDown'){e.preventDefault();opts[(i+1)%opts.length].focus();}else if(e.key==='ArrowUp'){e.preventDefault();opts[(i-1+opts.length)%opts.length].focus();}else if(e.key==='Escape'){e.preventDefault();close(true);}else if(e.key==='Tab'){close(false);}});
btn.addEventListener('keydown',function(e){if(e.key==='ArrowDown'&&list.hidden){e.preventDefault();openL();}});
document.addEventListener('pointerdown',function(e){if(!list.hidden&&!w.querySelector('.tkn__lang').contains(e.target))close(false);});
var saved=null;try{saved=localStorage.getItem(KEY);}catch(e){}if(saved==='en')apply('en',false);
}
init(document.querySelector('.jouw-container'));
More navigation & menus
Seen something you like?
Add it to your selection and send it over. We build your site around it, in your brand.
Get in touch →