Container-Anpassung-Tabs, Die Mit “Mehr” – Button

0
21

Oder ist die Priorität die navigation ein Muster oder ein sich schrittweise kollabierenden Menü-navigation. Wir nennen Sie mindestens drei Möglichkeiten.

Es gibt mehrere UX-Lösungen für tabs und Menüs, und jeder von Ihnen haben Ihre eigenen Vorteile, über die andere, Sie müssen nur wählen Sie das beste für den Fall, dass Sie versuchen zu lösen. Bei design und Entwicklung-Agentur Kollegorna waren wir debattieren über die entsprechenden UX-Technik für die Registerkarten für die website unseres Kunden…

Wir vereinbarten, es soll ein one-liner, da die Menge der Registerkarte Elemente ist unbekannt, und verengten sich die Möglichkeiten auf zwei: horizontale Bildlaufleiste und adaptive mit “mehr” – button. Erstens, das problem mit ersterem ist, dass die horizontale scroll-feature ist nicht immer visuell offensichtlich für Benutzer (vor allem für schmale Elemente wie Registerkarten) in der Erwägung, dass, was anderes kann offensichtlicher sein als eine Taste (“mehr”), richtig? Zweitens, horizontales scrollen mit einer Maus-gesteuerte Gerät ist nicht sehr komfortabel, was zu tun, so könnten wir brauchen, um unsere UI komplexer mit zusätzlichen Pfeil-Tasten. Alle als, wir am Ende die Wahl der option später:

Planung

Die Haupt-Intrige ist hier, wenn es möglich ist, zu erreichen, dass ohne JavaScript? Teilweise ja, aber die Einschränkungen, dass es wohl nur gut für ein Konzept, museum eher als real-life-Szenarien (eh, Kenan hat einen wirklich netten job). Trotzdem, die Abhängigkeit von JS bedeutet nicht, wir können es nicht brauchbar, wenn aus irgendeinem Grund die Technik ist nicht verfügbar. Progressive enhancement und graceful degradation für den Sieg!

Da die Menge der Registerkarte Elemente ist unsicher oder instabil ist, werden wir Gebrauch machen von Flexbox, die gewährleistet, die Elemente sind schön verteilt in der container-element ohne Einstellung der Breite.

Erster Prototyp

Es gibt zwei Listen sowohl optisch als auch technisch: man wird für Elemente, die in den Behälter passen, und einen für Objekte, die nicht. Da wir angewiesen sind auf JavaScript, es ist völlig in Ordnung, haben unsere ursprünglichen markup mit einer einzigen Liste nur (wir duplizieren es mit JS):

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

Mit einem winzigen Hauch von flex-basierten CSS-Dinge beginnen zu ernst hier. Ich werde zum überspringen der dekorativen CSS-Eigenschaften in meinem Beispiel hier und hier, was wirklich wichtig ist:

.tabs .-primary {
display: flex;
}
.tabs .-primär > li {
flex-grow: 1;
}

Hier ist, was wir bereits haben:

Graceful Degradation

Nun, bevor es schrittweise Verbesserung mit JavaScript, stellen wir sicher, dass es degradiert anmutig, wenn es kein JS verfügbar. Es gibt mehrere Gründe für JS fehlen: es ist immer noch laden, es hat schwerwiegende Fehler, es konnte nicht über das Netzwerk übertragen werden.

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

Und sobald JavaScript ist hier, die –jsfied Klasse name Hinzugefügt wird, um das container-element, das neutralisiert die CSS oben:

container.classList.add(‘–jsfied’)

Stellt sich heraus, der horizontale scroll-Strategie, die ich bereits erwähnt könnte einen feinen Einsatz hier! Wenn es nicht genug Platz für die Menü-Elemente der überquellenden Inhalt wird abgeschnitten, in den Behälter und die Scrollbalken werden angezeigt. Das ist die Weise, die besser als der leere Raum, oder etwas, das kaputt ist, ist es nicht?

Fehlstellen

First off, lassen Sie uns legen Sie die fehlenden DOM Teile:

  • Sekundäre (dropdown -) Liste eine Kopie der Liste;
  • “Mehr” – button.

const container = document.querySelector(‘.tabs’)
const PV = container.querySelector(‘.-primär’)
const primaryItems = container.querySelectorAll(‘.-primär > li:not(.-mehr)’)
container.classList.add(‘–jsfied’)

// legen Sie die “mehr” – Taste, und duplizieren Sie die Liste

PV.insertAdjacentHTML(‘beforeend’, `
<li class=”mehr”>
<button type=”button” aria-haspopup=”true” aria-expanded=”false”>
Mehr &darr;
</button>
<ul class=”-secondary”>
${PV.innerHTML}
</ul>
</li>
`)
const Sekundär = container.querySelector(‘.-sekundäre’)
const secondaryItems = sekundäre.querySelectorAll(‘li’)
const allItems = container.querySelectorAll(‘li’)
const moreLi = PV.querySelector(‘.-mehr’)
const moreBtn = moreLi.querySelector(‘button’)
moreBtn.addEventListener(‘click’, (e) => {
e.preventDefault()
container.classList.toggle(‘–show-Sekundär’)
moreBtn.setAttribute(‘aria-expanded’, container.classList.enthält(‘–show-Sekundär’))
})

Hier sind wir nisten sekundäre Liste in die primäre und die aria -* – Eigenschaften. Wir wollen, dass unsere navigation Menü zugänglich zu sein, richtig?

Es gibt auch ein event-handler angehängt, um den “mehr” – Taste schaltet die –show-sekundäre Klasse name auf dem container-element. Wir werden es verwenden, um ein-und ausblenden der sekundären Liste. Nun lassen Sie den Stil der neuen Teile. Möchten Sie vielleicht optisch Akzent “mehr” – button.

.tabs {
position: relative;
}
.tabs .-sekundäre {
display: none;
position: absolute;
top: 100%;
right: 0;
}
.tabs.–show-Sekundär .-sekundäre {
display: block;
}

Hier ist, wo das brachte uns zu:

Offensichtlich brauchen wir etwas code, versteckt sich und zeigt die Registerkarten…

Aus-und einblenden von Registerkarten, die in den Listen

Weil von Flexbox, die Registerkarte Einzelteile werden nie brechen in mehrere Zeilen und schrumpfen, um Ihre möglichst Breite. Das heißt, wir können zu Fuß durch die jedes Element einzeln hinzufügen Ihre breiten, vergleichen Sie es mit der Breite .Registerkarten-element, und setzen Sie die Sichtbarkeit von bestimmten tabs entsprechend. Dafür erstellen wir eine Funktion, die aufgerufen wird doAdapt und Zeilenumbruch in den code weiter unten in diesem Abschnitt.

Beginnen Breite, wir sollten visuell zeigen alle Elemente:

allItems.forEach((item) => {
Element.classList.entfernen (‘–‘versteckte’)
})

On a side note, .–verborgenen arbeiten die Weise, die Sie haben wahrscheinlich erwartet:

.tabs .–versteckt {
display: none;
}

Math Zeit! Ich muss Sie enttäuschen, wenn Sie erwarten, einige fortgeschrittene Mathematik. So, wie zuvor beschrieben, laufen wir durch jede primäre Registerkarte, indem Ihre breiten unter stopWidth variable. Wir führen auch überprüft, ob der Artikel passt in die container, das Element auszublenden, wenn Sie nicht und speichern Sie den index für eine spätere Verwendung.

lassen Sie stopWidth = moreBtn.offsetWidth
lassen Sie hiddenItems = []
const primaryWidth = PV.offsetWidth
primaryItems.forEach((Element, i) => {
wenn(primaryWidth >= stopWidth + item.offsetWidth) {
stopWidth += Element.offsetWidth
} else {
Element.classList.add (‘–‘versteckte’)
hiddenItems.push(i)
}
})

Im folgenden, wir müssen uns verstecken, die äquivalente Elemente aus der sekundären Liste, blieb sichtbar in der Grundschule. Sowie ausblenden “mehr” – button, wenn keine Registerkarten, die ausgeblendet wurden.

if(!hiddenItems.Länge) {
moreLi.classList.add (‘–‘versteckte’)
container.classList.entfernen(‘–show-Sekundär’)
moreBtn.setAttribute(‘aria-expanded’, false)
}
else {
secondaryItems.forEach((Element, i) => {
if(!hiddenItems.enthält(i)) {
Element.classList.add (‘–‘versteckte’)
}
})
}

Stellen Sie schließlich sicher doAdapt Funktion ausgeführt wird, auf die richtigen Momente:

doAdapt() // das sich sofort auf laden
Fenster.addEventListener(‘resize’, doAdapt) // anzupassen, auf Fenster Größe ändern

Ideal in der resize-Ereignisprozedur sollte entprellten um unnötige Berechnungen.

Meine Damen und Herren, dies ist das Ergebnis (spielen mit der Größenänderung das demo-Fenster):

Finden Sie die Stift-Behälters-Anpassung von Registerkarten, die Mit “Mehr” – Button von Osvaldas (@osvaldas) auf CodePen.

Ich könnte wahrscheinlich am Ende mit meinem Artikel hier, aber es gibt eine extra Meile wir können gehen, es besser zu machen und einige Dinge zu beachten…

Verbesserungen

Es wurde implementiert in der demo oben, aber wir haben nicht übersichlich ein kleines detail, das verbessert die UX unserer tabs-widget. Es versteckt sich in der dropdown-Liste automatisch, wenn ein Benutzer klickt auf eine beliebige Stelle außerhalb der Liste. Dafür können wir binden einen globalen Klick-listener und überprüfen Sie, ob das angeklickte element oder einer Ihrer Eltern ist die secondarylist oder “mehr” – button. Wenn nicht, ist die dropdown-Liste wird entlassen.

Dokument.addEventListener(‘click’, (e) => {
let el = e.Ziel
while(el) {
if(el === Sekundär – | | el === moreBtn) {
return;
}
el = el.parentNode
}
container.classList.entfernen(‘–show-Sekundär’)
moreBtn.setAttribute(‘aria-expanded’, false)
})

Grenzfälle

Lange Tab-Reiter

Sie haben sich vielleicht schon gefragt, wie sich das widget verhält sich mit langen Registerkarte Titel. Gut, Sie haben mindestens zwei Möglichkeiten hier…

  1. Lassen Sie Titel in die nächste Zeile umbrochen ist, wie Verhalten Sie sich standardmäßig (Sie können auch den Zeilenumbruch mit word-wrap: break-word):
  1. Oder Sie können deaktivieren Sie alle Arten von Geschenkpapier in der primären Liste mit white-space: nowrap. Das Skript ist flexibel genug, um die too-long-Positionen auf den dropdown (wo die Titel sind frei, zu wickeln) und durch den ausbau neben der kürzeren Geschwister:

Viele Tabs

Obwohl die sekundäre Liste position: absolute ist es egal, wie lange Ihr Dokument die Höhe. Solange das container-element oder seine Eltern sind nicht position: fixed wird das Dokument anpassen und die unteren Elemente werden erreichbar durch scrollen der Seite nach unten.

Eine Sache zu Beachten

Die Dinge werden schwierig, wenn die tabs befinden sich Schaltflächen, eher als Anker semantisch, was bedeutet, dass Ihre Reaktion auf Klicks beschlossen werden, die von JavaScript, z.B.: dynamische tabs. Das problem hier ist, dass der tab button-event-Handler nicht dupliziert zusammen mit dem markup. Ich sehe mindestens zwei Wege lösen:

  • Ort, dynamische event-handler-Anhänge direkt nach dem adaptive Registerkarte code;
  • Eine event delegation-Methode statt (man denke an die jQuery live()).

Leider, treten Ereignisse in der Quantität: die meisten wahrscheinlich, dass die tabs haben einen ausgewählten Zustand, optisch zeigt die aktuelle Registerkarte, so dass es auch wichtig zum verwalten der Zustände gleichzeitig. Andernfalls kippen Sie die Tablette und du bist verloren.

Browser-Kompatibilität

Obwohl ich früher ES6-syntax in den Beispielen und demo, sollte es umgewandelt werden ES5 von einem compiler wie Babel deutlich zu erweitern die browser-Unterstützung (bis einschließlich IE9).

Sie können auch erweitern Sie das Flexbox-Umsetzung mit einer älteren version und-syntax (den ganzen Weg hinunter zum IE10). Wenn Sie brauchen, um auch die Unterstützung nicht-Flexbox-Browser können Sie immer tun, feature-Erkennung mittels CSS @unterstützt, für die Technik nach und nach und verlassen Sie sich auf horizontales scrollen für ältere Browser.

Happy tabbing!