Rolf B: Vermeiden von column breaks

Hallo alle,

Vor zwei Jahren schrieb Rachel Andrews über CSS Fragmentierung, und sagte, dass die CSS Eigenschaften break-before:avoid und break-after:avoid von den Browsern schlecht bis gar nicht unterstützt werden.

Ich bastele im Moment an einem Konzept für Wiki-Vorlagen, wo ich das brauchen würde, und es scheitert nach wie vor jämmerlich. Ich möchte die diversen Tutorial-Einleitungen, die einen Überblick über die Inhalte geben, mit einer Vorlage steuern.

Kontrollfrage: Ist es mit der Fragmentierung tatsächlich immer noch so schlimm? Oder mache ich etwas falsch?

jsFiddle: https://jsfiddle.net/Rolf_b/t5m10awr/ - der obere Teil.

Im unteren Teil habe ich das semantische Markup in die Tonne gehauen und einfach Breaks verwendet. Eine Präsentation mit Listenpunkten könnte man noch ergänzen. Dadurch, dass ich jetzt normalen Text als Inhalt habe, kann ich die CSS-Eigenschaften orphans und widows verwenden (Hurenkinder und Schusterjungen). Damit ist zumindest in Chromia meine Absicht erreichbar, Abschnittsüberschriften und Listenpunkte beisammenzuhalten, bzw. nicht einzelne Listenpunkte am Ende überhängen zu haben, und trotzdem responsiven Spaltensatz zu ermöglichen. Dem Fuchs sind die Widows und Orphans aber leider egal.

Richtig gut ist es aber auch in Chromia nicht, weil gelegentlich ein "padding-bottom" oder "margin-bottm" auf die Folgespalte umgebrochen wird.

Ich frage mich nur: Ist der Verzicht auf die Semantik akzeptabel? Oder würde das Wiki damit ein unakzeptables Beispiel geben?

Und gibt es eine bessere Lösung? Gibt es einen "Polyfill" auf JS Basis? Nicht, dass ich das toll fände...

Rolf

--
sumpsi - posui - obstruxi
  1. Hallo,

    ich habe mal versucht, einen Rebreaker zu basteln.

    https://jsfiddle.net/Rolf_b/t5m10awr/4/

    Das ist unglaublich komplex, vor allem, weil Chrome keinen Reflow macht wenn man Breaks hinzufügt. Abfragen von offsetHeight, was angeblich unfehlbar einen Reflow macht, hat keinen Effekt. Ich schiebe im Moment das Padding des Abschnitts hin und her, und zwischendurch gebe ich dem Browser mit setTimeout Gelegenheit, sich neu zu zeichnen und die verdammten Column Breaks zu aktualisieren.

    Immerhin kann ich so den größten Teil der Break-Logik des Browsers recyclen und muss nicht alles selbst machen (was vermutlich gründlich schiefgeht oder unendlich komplex ist).

    Ich glaube, ich verzichte dann doch auf den Spaltenbalancierer und überlasse das den Browserherstellern (die das Thema aber wohl aus dem gleichen Grund zurückstellen).

    Fertiges JS scheint es dafür auch nicht zu geben.

    Meinungen? Weiß jemand was besseres? Oder ist es euch einfach nur egal - angesichts der Antwortflut hier scheint es ja wohl so zu sein 😟

    Rolf

    --
    sumpsi - posui - obstruxi
    1. Servus!

      Hallo,

      ich habe mal versucht, einen Rebreaker zu basteln.

      https://jsfiddle.net/Rolf_b/t5m10awr/4/

      Das ist unglaublich komplex, vor allem, weil Chrome keinen Reflow macht wenn man Breaks hinzufügt. Abfragen von offsetHeight, was angeblich unfehlbar einen Reflow macht, hat keinen Effekt. Ich schiebe im Moment das Padding des Abschnitts hin und her, und zwischendurch gebe ich dem Browser mit setTimeout Gelegenheit, sich neu zu zeichnen und die verdammten Column Breaks zu aktualisieren.

      Immerhin kann ich so den größten Teil der Break-Logik des Browsers recyclen und muss nicht alles selbst machen (was vermutlich gründlich schiefgeht oder unendlich komplex ist).

      Ich glaube, ich verzichte dann doch auf den Spaltenbalancierer und überlasse das den Browserherstellern (die das Thema aber wohl aus dem gleichen Grund zurückstellen).

      Fertiges JS scheint es dafür auch nicht zu geben.

      Meinungen? Weiß jemand was besseres? Oder ist es euch einfach nur egal - angesichts der Antwortflut hier scheint es ja wohl so zu sein 😟

      Das soll ja für die Inhaltsübersichten zu den Kursen verwendet werden. Die haben sich zu der jetzigen Form entwickelt - 2 oder 3 Spalten am Desktop, eine ol, damit es eine Kapitelzählung gibt und immer mehr Unterpunkte, damit man eben auch weiß, was in den Kapiteln vorkommt. Das System ist unhandlich und wird von mir dann manuell angepasst:

      • entweder mit br
      • mit 2 oder 3 Spalten
      • oder mit einem weiteren Spiegelstrich/ Unterpunkt

      Matthias Apsel hatte auch schon erfolglos rumprobiert. Wir haben iirc für einige Sachen JS (So lädt der blaue Navigations-Balken dynamisch nach, kein h1 auf Startseite, utrace für Bürokraten, einen genauen Überblick habe ich nicht) ich würde es einfach weiterhin so handhaben.

      Herzliche Grüße

      Matthias Scharwies

      --
      Einfach mal was von der ToDo-Liste auf die Was-Solls-Liste setzen.“
    2. Hallo Rolf,

      Meinungen? Weiß jemand was besseres? Oder ist es euch einfach nur egal - angesichts der Antwortflut hier scheint es ja wohl so zu sein 😟

      nicht egal, aber ich habe, ehrlich gesagt, dein Problem nicht verstanden.

      Gruß
      Jürgen

      1. Servus!

        Hallo Rolf,

        Meinungen? Weiß jemand was besseres? Oder ist es euch einfach nur egal - angesichts der Antwortflut hier scheint es ja wohl so zu sein 😟

        nicht egal, aber ich habe, ehrlich gesagt, dein Problem nicht verstanden.

        columns teilt den Text auf mehrere Spalten auf. Dabei hat der Nutzer aber nur Einfluss auf Spaltenbreite und Abstände (gap), nicht wie der Text umbricht.

        Bei den ol in den Inhaltsangaben gibt es ja entweder ol ol oder ol ul und es wäre schön, wenn ein ol li nicht unten als letztes stehen würde, der dazugehörende Erklärttext/Unterkapitel ol ol li aber in der nächsten Spalte.

        Das lässt sich mit css aber wohl nicht regeln. Evtl. sollte man doch auf ul und eine feste Spaltenanzahl mit der Vorlage:3Spalten umsteigen.

        Herzliche Grüße

        Matthias Scharwies

        --
        Einfach mal was von der ToDo-Liste auf die Was-Solls-Liste setzen.“
      2. Hallo Jürgen,

        mach mein Fiddle auf und lass die "Rebreak" Checkbox aus. Variiere die Breite des Ausgabebereichs. Je nach Länge der Abschnitte und nach Anzahl der Spalten kommt es vor, dass die Abschnittsüberschrift am Ende von Spalte 1 steht und die Inhaltspunkte dazu in der nächsten Spalte. Oder der letzte Punkt eines Abschnitts steht einsam am Beginn einer neuen Spalte.

        Schusterjungen und Hurenkinder eben

        Matthias hantiert mit <br> herum, um das zu lösen, aber das ist nicht responsiv. Solange man bei zwei Spalten bleibt, kann man das noch mit <br> bändigen, aber bei drei Spalten hängt die reale Spaltenzahl von der Viewportbreite ab (bzw. vom Verhältnis Fontsize zu Viewportbreite) und die erforderliche Auffütterung mit <br> ist nicht mehr konstant.

        Man kann ein bisschen mit break-inside:avoid erreichen, aber das ist nur für kleine Abschnitte wirklich gut. Sobald ein Abschnitt mit - sagenwirmal - 6 Punkten kommt, kann das Ergebnis dadurch sehr aus der Balance geraten.

        Das Rebreak-Script, das ich versucht habe, tut daher zwei Dinge: Abschnitte mit max. 3 Punkten (in Version 5 - in der v4 waren es noch 2) bekommen die keepTogether-Klasse, die break-inside:avoid zusteuert. Und bei größeren Abschnitten prüfe ich nach einem Resize des Fensters, ob der erste Punkt im Abschnitt einen offsetTop hat, der kleiner ist als der offsetTop der Überschrift. Desgleichen für die Punkte 2 und 1. Und dann versuche ich, mit Hinzufügen der break-Klasse den Umbruch zu verschieben, so dass die Überschrift mit den Punkten 1+2 zusammenbleibt.

        Und wie gesagt - da kämpfe ich auch gegen den Browser. Eine Layout-Phase muss auf jeden Fall passieren, weil ich nicht weiß, wie sich die Folgespalten verschieben, wenn ich in Spalte 1 einen Break einfüge. Nach jedem hinzugefügten Break ist demnach ein setTimeout nötig. Das reicht aber noch nicht, denn Chrome macht keinen Reflow, wenn ich eine break-* Eigenschaft hinzufüge. Das tut er nur, wenn sich die Box selbst ändert, z.B. durch Verändern des Paddings. Deswegen mache ich zwei setTimeout-Phasen nach jedem hinzugefügten Break. In der ersten schiebe ich ein Padding-Pixel von rechts nach links und in der zweiten wieder zurück. Klappt meistens. Nicht immer 😕

        Ich bin also bislang alles andere als glücklich mit dem Ergebnis.

        • Bei manuell hinzugefügten <br> mag ich nicht bleiben.
        • Abschnitte grundsätzlich auf break-inside:avoid setzen ist zu unflexibel
        • Die Listenstruktur zerschlagen und die Umbrüche komplett manuell auszuführen würde vermutlich einen visuellen Erfolg bringen, das Ergebnis ist aber kein zugängliches HTML mehr und die Semantik dürfte im Eimer sein. Der Algorithmus dafür ist auch nicht trivial, aber wenn das Semantikproblem nicht wäre, würde mich das nicht abschrecken. Das kriegt man sicherlich irgendwie hin; das ist eine Optimierungsaufgabe, die professionelle Spaltensatztools gelöst haben.
        • Die einzelnen Reflow-Schritte, die ich jetzt über setTimeout mache, könnte ich auch versuchen, im Script zu simulieren. Ich müsste die Höhen von Überschriften und Listitems bestimmen und dann so lange mit simulierten Breaks jonglieren, bis die Balance gelingt. Das ist allerdings auch nicht trivial.

        Rolf

        --
        sumpsi - posui - obstruxi