Container-Het Aanpassen Van De Tabbladen Met De Knop “Meer”

0
23

Of de prioriteit navigatie patroon, of geleidelijk instort navigatie menu. We kunnen de naam van het in minstens drie manieren.

Er zijn meerdere UX oplossingen voor tabbladen en-menu ‘ s en elk van hen hebben hun eigen voordelen ten opzichte van een ander, je hoeft alleen maar te kiezen van de beste voor het geval dat u probeert op te lossen. Bij het ontwerp en de ontwikkeling van agency Kollegorna waren we debatteren over de meest geschikte UX techniek voor tabbladen voor de website van onze klant…

We hebben afgesproken om het een one-liner, omdat het bedrag van het tabblad artikelen is onbekend en vernauwde onze opties omlaag te brengen tot twee: de horizontale schuifbalk en de adaptieve met “meer” knop. Ten eerste, het probleem met de vorige is dat de horizontale schuifbalk als een functie niet altijd visueel duidelijk voor de gebruikers (vooral voor smalle elementen (tabs) overwegende dat, wat kan anders meer voor de hand dan een knop (“more”), toch? Ten tweede, horizontaal scrollen met behulp van een muis-gecontroleerde apparaat is niet een erg comfortabele ding om te doen, dus we nodig om onze UI meer complex met extra pijl knoppen. Al met al kwamen we kiezen voor de laatste optie:

Planning

De belangrijkste intrige hier is of het ook mogelijk is om dat te bereiken zonder JavaScript? Deels ja, maar de beperkingen die het gaat met waarschijnlijk alleen goed voor een concept museum eerder dan in real-life scenario ‘ s (in ieder geval, Kenan hebt echt een leuke baan). Nog steeds, de afhankelijkheid van JS betekent niet dat we niet bruikbaar indien u om enige reden de technologie is nog niet beschikbaar. Progressive enhancement en graceful degradation voor de win!

Aangezien het bedrag van het tabblad artikelen is onzeker of vluchtig, zullen we gebruik maken van Flexbox die ervoor zorgt dat de items liggen mooi verspreid in het container element zonder het instellen van de breedte.

Eerste Prototype

Er zijn twee lijsten zowel visueel als technisch: één is voor de items die passen in de container, en een voor items die niet. Aangezien we afhankelijk zijn van JavaScript, het is helemaal fijn om onze eerste markup met een enkele lijst alleen (we zullen dupliceren met JS):

<nav class=”tabs”>
<ul class=”primaire”>
<li><a href=”…”>Falkenberg</a></li>
<li><a href=”…”>Braga</a></li>
<!– … –>
</ul>
</nav>

Met een kleine touch van de flex-basis CSS dingen beginnen te serieus hier. Ik sla de decoratieve CSS-eigenschappen in mijn voorbeelden hier en hier plaatsen wat echt belangrijk is:

.tabbladen .-primaire {
display: flex;
}
.tabbladen .-primaire > li {
flex-groeien: 1;
}

Hier is wat we al hebben:

Graceful Degradation

Nu voordat het te verbeteren geleidelijk met JavaScript, laten we ervoor zorgen dat het overlast veroorzaakt als er geen JS beschikbaar. Er zijn meerdere redenen voor JS afwezigheid: het is nog aan het laden, het heeft fatale fouten, het niet over het netwerk verstuurd worden.

.tabbladen: (.–jsfied) {
overflow-x: auto;
-webkit-overloop-scrolling: touch;
}

En wanneer JavaScript is hier, de –jsfied naam van de klasse is toegevoegd aan de container element dat neutraliseert de CSS hierboven:

container.classList.add(‘–jsfied’)

Blijkt de horizontale schuifbalk de strategie die ik al eerder vermeld kan een boete hier gebruik van! Wanneer er niet genoeg ruimte voor menu-items de overvloeiende inhoud wordt afgekapt in de container en schuifbalken worden weergegeven. Dat is veel beter dan een lege ruimte of iets dat kapot is, is het niet?

Ontbrekende Onderdelen

Ten eerste, laten we het invoegen van de ontbrekende DOM onderdelen:

  • Secundaire (dropdown) lijst die een kopie is van de belangrijkste lijst;
  • “Meer” knop.

const container = document.querySelector(‘.tabs’)
const primaire = container.querySelector(‘.-primaire’)
const primaryItems = container.querySelectorAll(‘.-primaire > li:not(.-meer)’)
container.classList.add(‘–jsfied’)

// plaats “meer” knop en dupliceren de lijst

het jeugdwerk.insertAdjacentHTML(‘beforeend’, `
<li class=”meer”>
<button type=”button” aria-haspopup=”true” aria-expanded=”false”>
Meer &darr;
</button>
<ul class=”secundair”>
${primaire.innerHTML}
</ul>
</li>
`)
const secundair = container.querySelector(‘.-secundair’)
const secondaryItems = secundair.querySelectorAll(‘li’)
const allItems = container.querySelectorAll(‘li’)
const moreLi = primaire.querySelector(‘.-meer’)
const moreBtn = moreLi.querySelector(‘button’)
moreBtn.addEventListener(‘klik’, (e) => {
e.preventDefault()
container.classList.toggle(‘–show-secundair’)
moreBtn.setAttribute(‘aria-uitgebreid’, de container.classList.bevat(‘–show-secundair’))
})

Hier zijn we nestelen secundaire lijst in primaire en met behulp van enkele aria-* eigenschappen. We willen dat onze navigatie-menu toegankelijk, toch?

Er is ook een gebeurtenis-handler wordt aangesloten op de “more” knop, die schakelt tussen de –show-tweede klasse naam op het container element. We zullen gebruiken voor het weergeven en verbergen van de secundaire lijst. Nu laten we de stijl van de nieuwe onderdelen. U wilt visueel accent “meer” knop.

.tabbladen {
position: relative;
}
.tabbladen .-secundaire {
display: none;
position: absolute;
top: 100%;
rechts: 0;
}
.tabbladen.–show-secundair .-secundaire {
display: block;
}

Hier is waar dat ons gebracht tot:

Natuurlijk, we hebben een code die verbergt en toont de tabbladen…

Het Weergeven of verbergen van Tabbladen in de lijst

Omdat van Flexbox, worden op het tabblad items zal nooit breken in meerdere lijnen en krimpen aan hun minimale breedtes. Dit betekent dat we kunnen lopen door de elk item één voor één toe te voegen tot hun breedtes, te vergelijken met de breedte van .tabbladen element en de zichtbaarheid van bepaalde tabbladen dienovereenkomstig. Voor dat maken we een functie genaamd doAdapt en wikkel in de onderstaande code in deze sectie.

Om te beginnen breedte, we moeten visueel onthullen alle items:

allItems.forEach((item) => {
item.classList.verwijderen(‘–verborgen’)
})

Op een zijde nota, .–verborgen werkt op de manier zoals u waarschijnlijk al verwacht:

.tabbladen .–verborgen {
display: none;
}

Math tijd! Ik moet u teleurstellen, als u verwacht een aantal geavanceerde wiskunde. Dus, zoals eerder beschreven, lopen we door het elke primaire tabblad door het toevoegen van hun breedtes onder stopWidth variabele. Wij voeren ook controleren of het item past in de container, het verbergen van het item als niet van en het opslaan van de index voor later gebruik.

laat stopWidth = moreBtn.offsetWidth
laat hiddenItems = []
const primaryWidth = primaire.offsetWidth
primaryItems.forEach((item, i) => {
als(primaryWidth >= stopWidth + item.offsetWidth) {
stopWidth += item.offsetWidth
} else {
item.classList.add(‘–verborgen’)
hiddenItems.push(i)
}
})

Hierna moeten we verbergen de gelijkwaardige items uit de tweede lijst die zichtbaar is gebleven in de eerste. Evenals verbergen “meer” knop indien geen tabs zijn verborgen.

if(!hiddenItems.de lengte) {
moreLi.classList.add(‘–verborgen’)
container.classList.verwijderen(‘–show-secundair’)
moreBtn.setAttribute(‘aria-uitgebreid’, false)
}
anders {
secondaryItems.forEach((item, i) => {
if(!hiddenItems.omvat(i)) {
item.classList.add(‘–verborgen’)
}
})
}

Zorg er ten slotte voor doAdapt functie wordt uitgevoerd op de juiste momenten:

doAdapt() // aan te passen meteen op laden
venster.addEventListener(‘resize’, doAdapt) // aan te passen op het formaat van venster

Ideaal is om de resize-gebeurtenis-handler moet worden debounced om te voorkomen dat onnodige berekeningen.

Dames en heren, dit is het resultaat (spelen met de grootte van het demo-venster):

Zie de Pen Container-het Aanpassen van de Tabbladen Met de Knop “Meer” door Osvaldas (@osvaldas) op CodePen.

Ik zou waarschijnlijk een einde aan mijn artikel hier, maar er is een extra mijl kunnen we lopen om het beter te maken en een aantal dingen op te merken…

Verbeteringen

Het is geïmplementeerd in de demo hierboven, maar we hebben het niet overviewed een klein detail dat verbetert de UX van onze tabs widget. Het is het verbergen van de dropdown lijst automatisch als gebruiker op een willekeurige plek buiten de lijst. Voor dat we het kunnen binden van een wereldwijde klik op de luisteraar en controleer of het aangeklikte element of een van zijn ouders is de secondarylist of “meer” knop. Indien niet, wordt de vervolgkeuzelijst wordt ontslagen.

document.addEventListener(‘klik’, (e) => {
laat el = e.doel
terwijl(el) {
als(el === secundaire || el === moreBtn) {
return;
}
el = el.parentNode
}
container.classList.verwijderen(‘–show-secundair’)
moreBtn.setAttribute(‘aria-uitgebreid’, false)
})

Edge Gevallen

Lange Tabblad Titels

Je hebt je misschien afgevraagd hoe de widget zich gedraagt met de lange tabblad titels. Goed, je hebt minstens twee opties hier…

  1. Laat titels doorloopt naar de volgende regel is hoe ze zich gedragen standaard (u kunt ook de terugloop in word-wrap: break-word):
  1. Of u kunt uitschakelen van alle soorten verpakt in de primaire lijst met white-space: nowrap. Het script is flexibel genoeg is om de te-lange-items om de dropdown (waar de titels zijn gratis te wikkelen) door opzij de kortere broers en zussen:

Veel Tabs

Hoewel de secundaire lijst is position: absolute maakt het niet uit hoe lang uw document op de hoogte is. Zolang de container element of de ouders niet position: fixed, zal het document aan te passen en de onderkant items worden bereikbaar door naar beneden te scrollen op de pagina.

Een Ding Bewust te worden Van

Dingen worden kan lastig zijn als u de tabbladen met de knoppen in plaats ankers semantisch, wat betekent dat hun reactie te klikken, worden beslecht door JavaScript, bijvoorbeeld: dynamische tabbladen. Het probleem hier is dat de knop tabblad gebeurtenis-handlers niet worden gedupliceerd, samen met de markup. Ik zie minstens twee benaderingen om dit op te lossen:

  • Plaats dynamische gebeurtenis-handler bijlagen direct na de adaptieve tabblad code;
  • Gebruik een evenement delegatie methode in plaats daarvan (denk van jQuery ‘ s live()).

Helaas, gebeurtenissen, hoeveelheid: meest waarschijnlijk uw tabbladen hebben een geselecteerde staat dat visueel geeft de huidige tabblad, dus het is ook belangrijk voor het beheren van de lidstaten tegelijk. Anders draait de tablet en je bent verloren.

Browser Compatibiliteit

Hoewel ik gebruikt ES6 syntaxis in de voorbeelden en demo, het moet worden omgezet naar ES5 door een compiler zoals Babel aanzienlijk te verbreden met de steun van de browser (naar IE9 inclusief).

U kunt ook het uitbreiden van de Flexbox uitvoering met een oudere versie en syntaxis (alle de weg naar beneden, naar IE10). Als u ook ondersteuning van niet-Flexbox browsers kunt u altijd voorzien van detectie met CSS @ondersteunt, de techniek toepassen, geleidelijk, en vertrouwen op de horizontale schuifbalk voor oudere browsers.

Gelukkig tab-toets!