Linuchs: thead soll bei scroll am oberen Rand fixiert werden

Moin,

es reicht mir, wenn folgendes Problem für den Firefox gelöst wird (geschlossene Benutzergruppe):

Wenn <table> aufwärts gescrollt wird, entschwindet der <thead> und die Spalten haben keine sichtbare Überschrift mehr.

Ich fixiere den thead, dabei löst er sich von der Tabelle und verliert die vorherigen Spaltenbreiten, schrumpft sozusagen.

Vor dem Fixieren lese ich also die Breiten aus, fixiere und versuche, die Breiten wieder zu setzen. Das mislingt. Genau: Die Breiten der Spalten im fixierten <thead> sind größer oder kleiner als im unfixierten:

function fixThead() {
  if( document.getElementsByTagName('thead')[0].style.position == 'fixed' ) {
    document.getElementsByTagName('thead')[0].style.position = '';
    document.getElementsByTagName('thead')[0].style.top      = '';
  } else {
    var zeile = document.getElementsByTagName('thead')[0].getElementsByTagName('tr')[0].getElementsByTagName('td');  // <tr> fuer Breite der Spalten sichern
    var breit = new Array();
    for( i=0; i<zeile.length; i++ ) {   // Breite der Spalten sichern
      breit[i]  = zeile[i].clientWidth; // ohne border
    }
    document.getElementsByTagName('thead')[0].style.position  = 'fixed';
    document.getElementsByTagName('thead')[0].style.top       = '5px';
    for( i=0; i<zeile.length; i++ ) {
      document.getElementsByTagName('thead')[0].getElementsByTagName('tr')[0].getElementsByTagName('td')[i].style.width     = (breit[i]) +'px';
      document.getElementsByTagName('thead')[0].getElementsByTagName('tr')[0].getElementsByTagName('td')[i].style.maxWidth  = (breit[i]) +'px';
      document.getElementsByTagName('thead')[0].getElementsByTagName('tr')[0].getElementsByTagName('td')[i].style.minWidth  = (breit[i]) +'px';
    }
//  alert( "Tabelle hat ["+zeile.length+"] Spalten, Spalte 2 = ["+breit[2]+"]px" );
  }  
}

Habe ich was übersehen? Oder gibt es gar eine Fertiglösung mit CSS3?

Gruß, Linuchs

  1. Hallo Linuchs,

    Oder gibt es gar eine Fertiglösung mit CSS3?

    Kommt drauf an ob ich es richtig verstehe. Dann suchst du vielleicht das.

    Gruss
    Henry

    1. Hallo Henry,

      nein, das suche ich nicht.

      Eher sowas wie ich es schon oft gesehen habe: Die Navigationsleiste steht unterhalb des Firmennamens und wenn der Seiteninhalt scrollt und die Navi verschwindet, wird sie an den oberen Rand des Viewports geklebt.

      Scrolle ich die Seite wieder runter, löst sich die Navi vom oberen Rand und nimmt wieder ihren vorherigen Platz ein, scrollt also auch mit runter.

      Ich verstehe nicht, warum die per JS gesetzten Breiten der Spalten nicht eingehalten werden. Bei "Element untersuchen" hat eine <td> folgenden Wert:

      <td style="width: 55px; max-width: 55px; min-width: 55px;"></td>

      Doch ist geschätzt 150px breit. Naja, eigentlich habe ich die Tabelle zerstört, kann das der Grund sein?

      <thead style="position: fixed; top: 5px;">

      Nun könnte ich eine zweite Tabelle fixieren und den <thead> hineinkopieren. Dann funktioniert wieder nicht die Spalten-Sortierung.

      Ich versuche es trotzdem mal ...

      Gruß, Linuchs

      1. Hallo Linuchs,

        nein, das suche ich nicht.

        ok.

        Eher sowas wie ich es schon oft gesehen habe: Die Navigationsleiste steht unterhalb des Firmennamens und wenn der Seiteninhalt scrollt und die Navi verschwindet, wird sie an den oberen Rand des Viewports geklebt.

        Damit meinst du wahrscheinlich so was? Was mich aber dabei verwirrt ist, wie du das dann mit der Tabelle meinst.

        Doch ist geschätzt 150px breit. Naja, eigentlich habe ich die Tabelle zerstört, kann das der Grund sein?

        Gut möglich, thead fällt ja aus dem normalen Fluss heraus. Btw. Warum eigentlich Pixel?

        Nun könnte ich eine zweite Tabelle fixieren und den <thead> hineinkopieren. Dann funktioniert wieder nicht die Spalten-Sortierung.

        Ich weiß zwar immer noch nicht, was du vorhast aber meine Intuition sagt mir, du machst es dir zu kompliziert. Keine Beispielseite zum Hochladen?

        Gruss
        Henry

        1. Hallo Henry,

          Damit meinst du wahrscheinlich so was? Was mich aber dabei verwirrt ist, wie du das dann mit der Tabelle meinst.

          Genau diesen Effekt. Den will ich auf den <thead> anwenden.

          Gut möglich, thead fällt ja aus dem normalen Fluss heraus. Btw. Warum eigentlich Pixel?

          Was denn sonst? Welche Einheit der Breite kann man denn sonst auslesen und übertragen mit clientWidth?

          meine Intuition sagt mir, du machst es dir zu kompliziert. Keine Beispielseite zum Hochladen?

          Naja, das Problem, dass die Überschrift weg·scrollt, hat doch jede größere HTML-Tabelle, auch Excel-Tabellen. Die kann man fixieren und die Breite der Spalten ist identisch zw. fixiertem und scrollbarem Bereich.

          Ist eine Adresstabelle meines Kunden mit > 600 Einträgen, kann ich doch nicht veröffentlichen …

          Gruß, Linuchs

          1. Habe das "Problem" auf diese öffentliche Seite gepackt zwecks Recherche:

            http://remso.eu/?zp=p581a

            Bitte in das linke obere Tabellenfeld "A" klicken, um die fixierte Leiste mit den falschen Spaltenbreiten sichtbar zu machen.

            Nochmal klicken zum Verdecken.

            1. @@Linuchs

              Habe das "Problem" …

              Welches Problem? Das schon längst gelöste?

              … auf diese öffentliche Seite gepackt zwecks Recherche:

              Willst du nicht mal recherchieren? In diesem Thread?

              LLAP 🖖

              --
              „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
            2. Hallo Linuchs,

              nur um noch mal sicher zu gehen, das ist auch das was du haben willst, lediglich die Breite ober soll der Tabelle entsprechen?

              Gruss
              Henry

          2. Hej Linuchs,

            meine Intuition sagt mir, du machst es dir zu kompliziert. Keine Beispielseite zum Hochladen?

            Ist eine Adresstabelle meines Kunden mit > 600 Einträgen, kann ich doch nicht veröffentlichen …

            Wenn du uns eine auf das Problem reduzierte Beispielsweise mit Fake-Daten zeigst, geht das sehr wohl… 😉

            Naja, das Problem, dass die Überschrift weg·scrollt, hat doch jede größere […] Tabelle

            Daher unterteilt man diese i.d.R. und bietet eine Blätter-Navigation an…

            Marc

      2. Hej Linuchs,

        nein, das suche ich nicht.

        Eher sowas wie ich es schon oft gesehen habe: Die Navigationsleiste steht unterhalb des Firmennamens und wenn der Seiteninhalt scrollt und die Navi verschwindet, wird sie an den oberen Rand des Viewports geklebt.

        Das klingt jetzt erst mal aber nicht nach Tabelle…

        Marc

    2. @@Henry

      Dann suchst du vielleicht das.

      table.scroll tbody, table.scroll thead tr { display: block; } ist keine so gute Idee. Da geschehen schlimme Dinge.

      LLAP 🖖

      --
      „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
  2. @@Linuchs

    Habe ich was übersehen?

    Ja: position: sticky.

    Oder gibt es gar eine Fertiglösung mit CSS3?

    Die gibt es.

    LLAP 🖖

    --
    „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
    1. Hallo Gunnar,

      Ja: position: sticky. Die gibt es.

      Das habe ich gesucht und vergeblich recherchiert … auf uralte Diskussionen gestoßen mit umständlichen Lösungen.

      Danke

      1. Habe das jetzt mit position:sticky gemacht. Beispielseite

        Nun werden aber die border zwischen den <thead> .. <td> nicht gezeigt, obwohl sie bei "Element untersuchen" angegeben werden. Vermutlich ein FF-Bug? Aber gut, damit kann ich leben.

        Habe das mal in der Opera gegengeprüft, aber die Version 47.0.2631.80 kennt sticky nicht. Ist das eine spezielle FF-Fähigkeit?

        1. Hallo Linuchs,

          Habe das mal in der Opera gegengeprüft, aber die Version 47.0.2631.80 kennt sticky nicht. Ist das eine spezielle FF-Fähigkeit?

          Einige andere auch nicht, bzw. zumindest in deinem Fall nicht verlässlich. Hast du den ganzen Thread hier gelesen?

          Gruss
          Henry

        2. Diese Seite funktioniert auch in der Opera. Muss ich mir näher ansehen.

    2. Hallo Gunnar,

      Die gibt es.

      Nicht schlecht, hätte nicht gedacht dass sticky so lokal seine Möglichkeit ausspielen kann. Ich war schon dran eine Lösung mit Clon des Thead zu fabrizieren. Gut, dass du so schnell warst. Na zumindest mit meiner Intuition lag ich richtig. 😉

      Gruss
      Henry

    3. Hallo Gunnar,

      das Feature ist laut MDN experimentell und nur im FF enthalten. Laut Caniuse ist es bis zum FF 58 buggy, auch wenn sich das im bugzilla anders liest.

      Chrome und Edge basteln noch dran :(

      Als ich vor ca 2 Jahren nach sowas suchte, gab es das in Kendo UI, aber nur so, dass man den Head in eine eigene Table auslagerte und die sticky machte. Mit all den Problemen, die diese Teilung mit sich bringt. Die FF Lösung ist schick - hoffe, die kommt bald in die Breite.

      Rolf

      --
      sumpsi - posui - clusi
      1. @@Rolf B

        das Feature ist laut MDN experimentell und nur im FF enthalten.

        Ich weiß nicht, welcher Seite du das entnehmen willst. Ich kann solch eine Aussage weder auf der englischen noch auf der (schon etwas in die Tage gekommenen) deutschen Seite finden.

        Wegen „es reicht mir, wenn folgendes Problem für den Firefox gelöst wird (geschlossene Benutzergruppe)“ hatte ich mich um andere Browser auch nicht geschert.

        Laut Caniuse ist es bis zum FF 58 buggy

        Irrelevant. Aktuell ist 59.0.2.

        Chrome und Edge basteln noch dran :(

        Wie Can I use sagt: mit position: -webkit-sticky geht’s auch in Safari; und wenn man das nicht auf thead, sondern auf thead th anwendet, geht’s auch in Chrome und vermutlich (nicht getestet) auch in Edge.

        LLAP 🖖

        --
        „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
        1. Hallo Gunnar,

          wenn ich dem englischen Link folge und bei sticky schaue, sehe ich da einen Erlenmeyerkolben.

          Anwendung auf th hatte ich in Chrome probiert, ohne Effekt. Bis ich top:0 hinzufügte. Muss man wissen, steht nicht auf MDN...

          MDN verlinkt auf drafts.csswg.org, die warnen vor dem Implementieren - aber ok, auf w3.org gibt's einen Stand von 2016 der sticky enthält - mit etlichen Issues.

          Aber so ganz 100%-ig ist es wohl noch nicht; ich habe Probleme mit einer wegscrollenden th Border bei border-collapse:collapse; (FF+Chrome) offenbar wird durch collapse der Border vom th gelöst. In Edge16 ist es noch schlimmer, da ist ungescrollt die Border gar nicht sichtbar und erscheint erst beim Hochscrollen.

          Horizontales sticky funktioniert nur bei definierter width. Ist die Brutto-Breite des Inhaltes aber "zu groß", scrollt das horizontale Sticky doch wieder irgendwann weg. Eine klare Regel habe ich nicht gefunden, und aus der Spec ableiten kann ich das auch nicht.

          Rolf

          --
          sumpsi - posui - clusi
          1. @@Rolf B

            wenn ich dem englischen Link folge und bei sticky schaue, sehe ich da einen Erlenmeyerkolben.

            Das erklärt „laut MDN experimentell“, aber nicht „nur im FF enthalten“.

            Anwendung auf th hatte ich in Chrome probiert, ohne Effekt. Bis ich top:0 hinzufügte. Muss man wissen, steht nicht auf MDN...

            Aber in der Spec: “If the stickily positioned element’s top style is not auto, and the stickily positioned element projects above the top of the sticky-constraint rectangle, the stickily positioned element is moved down until it is fully contained in the sticky-constraint rectangle.”

            Das soll dann wohl im Umkehrschluss heißen: Wenn top (bzw. bottom, left right) den (berechneten) Wert auto hat, dann tritt dieses Verhalten nicht auf, d.h. dann ist ein stickily positioniertes Element nicht sticky.

            Aber so ganz 100%-ig ist es wohl noch nicht; ich habe Probleme mit einer wegscrollenden th Border bei border-collapse:collapse; (FF+Chrome) offenbar wird durch collapse der Border vom th gelöst.

            Deshalb dieser miese Trick.

            LLAP 🖖

            --
            „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
    4. Hi,

      Die gibt es.

      warum machst Du die Trennlinie als border-bottom von thead th:after? Und nicht einfach bei thead?

      cu,
      Andreas a/k/a MudGuard

      1. @@MudGuard

        Die gibt es.

        warum machst Du die Trennlinie als border-bottom von thead th:after? Und nicht einfach bei thead?

        Weil sie dann beim Scrollen nicht mehr zu sehen wäre. (Frag mich nicht, warum nicht. Vermutlich noch ein kleiner ein Bug.)

        LLAP 🖖

        --
        „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann