Antwort an „Rolf B“ verfassen

Hallo ich,

ein Flexitem erzeugt einen eigenen Blockformatierungskontext und DESHALB geht das nicht.

Ausnahme: Das Flexitem ist selbst wieder ein Flex-Container. Dann erzeugt es einen Flexformatierungskontext. Aber der bricht auch nicht um.

Test:

<div class="flex">
<div>Das ist das erste Flexitem, nur für mich</div>
<div><span>Das ist das</span><span>zweite Flexitem,</span><span>nur für dich</span></div>
</div>
.flex {
  display: inline-flex;
  flex-flow: row wrap;
}
.flex div {
  display: inline-flex;
  flex-flow: row wrap;
  gap: 0.25em;
}

bricht das zweite div trotzdem vollständig um.

Da die Anordnung mit order unzugänglich ist (ein Screenreader oder die Tab-Reihenfolge achten nicht auf order), würde ich Dir empfehlen, die Items im DOM mit JavaScript umzusortieren. Das ist etwas schwieriger, dürfte aber die wenigsten Probleme machen.

Ich zeige mal, wie man das macht.

<ol class="orderable itemlist">
<li value="2">Das ist das erste Flexitem, nur für mich. </li>
<li value="4">Das ist das zweite Flexitem, nur für dich. </li>
<li value="1">Das ist das dritte Flexitem, für ihn, sie und them. </li>
<li value="3">Das ist das vierte Flexitem, für die ganze Welt. </li>
<li value="1">Das ist das fünfte Flexitem, für Selfhtml. </li>
</ol>

Ich verwende eine Liste, weil es für li Elemente das value-Attribut gibt, das die Nummer des Items angibt. Man muss es für alle setzen, bzw. wo es nicht gesetzt ist, ist der Wert 0.

Man iteriert nun über alle Listen mit den Klassen orderable und itemlist (fühle Dich frei, die zu sortierenden Container anders zu identifizieren) und sortiert die Items der gefundenen Listen anhand des value-Attributs um.

Dieses Iterieren kann man so formulieren:

const orderables = document.querySelectorAll("ol.orderable.itemlist");
for (const orderable of orderables) {
   ...
}

oder kompakter so:

for (const orderable of document.querySelectorAll("ol.orderable.itemlist")) {
   ...
}

Felix würde jetzt sagen: dafür nimmt man die forEach-Methode. Ich nicht, das ist aus meiner Sicht veraltet, ich bevorzuge bei iterierbaren Sammlungen die for...of Schleife.

Im Inneren der Schleife muss man jetzt die Listitems einsammeln. Das geht geschickt mit einem :scope-Selektor und dem Kind-Kombinator für querySelectorAll:

const items = orderable.querySelectorAll(":scope > li")

Das Ergebnis ist eine Nodelist. Zum Sortieren braucht man aber ein Array. Die moderne Methode, aus einem iterierbaren Objekt ein Array zu machen, ist ein Arrayliteral mit spread-Operator:

const items = [ ...orderable.querySelectorAll(":scope > li") ];

Beachte: Es ist nicht nötig, die Zwischenergebnisse in Variablen zu speichern. Man kann direkt auf den Funktionsergebnissen weiterarbeiten.

DAS kann man nun mit der sort-Methode nach der order sortieren. Dafür braucht man sort mit Vergleichs-Callback. Da das value-Attribut immer numerisch ist, kann man a.value - b.value rechnen.

const items = [ ...orderable.querySelectorAll(":scope > li") ]
              .sort( (a,b) => a.value > b.value );

Sort liefert das sortierte Array zurück, d.h. wir können dieses Ergebnis nun durchlaufen. Die items-Variable brauchen wir nicht mehr…

for (const orderable of document.querySelectorAll("ol.orderable.itemlist")) {
  for (const sortedRef of 
        [...orderable.querySelectorAll(":scope > li")]
        .sort( (a,b) => a.value - b.value )
      ) {
    orderable.append(sortedRef)
  }
}

Der append-Aufruf entfernt das Element von seiner aktuellen Position und hängt es hinten an die Liste der Kindelemente an. Bei gleicher value-Nummer sollten die Elemente so hintereinander stehen, wie sie vor dem Sortieren vorgefunden wurden.

Edit: Ich habe das überarbeitet, vorher waren es divs, jetzt ul/li, das ist viel einfacher und auch semantischer. Ich hoffe, ich habe nichts übersehen.

Rolf

--
sumpsi - posui - obstruxi
freiwillig, öffentlich sichtbar
freiwillig, öffentlich sichtbar
freiwillig, öffentlich sichtbar

Ihre Identität in einem Cookie zu speichern erlaubt es Ihnen, Ihre Beiträge zu editieren. Außerdem müssen Sie dann bei neuen Beiträgen nicht mehr die Felder Name, E-Mail und Homepage ausfüllen.

abbrechen