grmblfx: position sticky und Text-fade out beim Scrollen

problematische Seite

Hallo,

ich hätte gerne, dass der Kopfbereich der Seite stehen bleibt und Text beim scrollen nach oben unterhalb ausfadet. Ich habe mit Hilfe div. Foren bereits eine Lösung gefunden, die dem ziemlich nahe kommt, siehe die Testseite unter yourmed.de und das angehängte Bild. Mein bisheriges CSS dazu lautet:

nav:after {
  content   : "";
  position  : absolute;
  top       : 148px;
  left      : 0;
  height    : 40px;
  width     : 100%;
  background: linear-gradient(to top, transparent, white);
}

Das Problem ist, dass ich dazu eine absolute Höhe angeben muss (top: 148px;), was natürlich je nach Gerät/Viewport/Browser/Schriftgröße etc. nicht mehr passt. Hat jemand eine Idee für eine Lösung ohne dieses Problem?

Gruß Daniel

Text fade out unter Kopfbereich

  1. problematische Seite

    Du kannst das Pseudoelement in #upper_wrapper statt nav einfügen. Wenn Du dann top: weg lässt reiht sich was Pseudoelement in die nächste Zeile und Du musst nur noch den padding-bottom von #upper_wrapper überwinden. Dies könntest Du mit einem transparenten border machen, dann aber das Hintergrundbild auf background-repeat: no-repeat; stellen.

    Alles sehr hacky 😐

    Anmerken will ich noch, dass solche Fadeouts, über Text hinweg, keine gute User Experience zulassen, da der transparente Teil ggf. interaktive Elemente, wie Links, überdeckt, die dann nicht mit der Maus ansteuerbar sind.

  2. problematische Seite

    Hallo grmblfx,

    Das Problem ist, dass ich dazu eine absolute Höhe angeben muss

    Nein. Brauchst Du nicht. Du brauchst auch kein Pseudo-Element.

    <header>
      <p>Dr. Arbeit.de</p>
      <nav><ul><li>Suchen</li><li>Anbieten</li><li>Links</li></ul></nav>
    </header>
    <h1>Wie man eine Doktorarbeit schreibt</h1>
    
    body {
      --fade-height: 1.5em;
    }
    header {
      text-align: center;
      position: sticky;
      top: 0;
      padding-bottom: var(--fade-height);
      margin-bottom: calc(0 - var(--fade-height));
      background-image: linear-gradient(to top, transparent, white var(--fade-height));
      pointer-events: none;
      border-bottom: 1px solid red;   /* Nur zur Visualisierung der Grenze */
    }
    h1 {
      margin-top: var(--fade-height);
    }
    

    Durch Verändern des Wertes des custom-property --fade-height kannst Du bestimmen, wie hoch der Ausblendebereich ist. Das Custom Property sorgt dafür, dass die Höhe des Ausblendebereichs nicht an drei Stellen als magic number auftaucht. Der IE kann das nicht, aber der kann auch kein position:sticky. So what.

    Der Fade-Bereich sollte nicht höher sein als der margin-top der Seitenüberschrift, am besten gleich hoch, sonst blendest Du die schon in "Normalstellung" weg. Das stelle ich mit der margin-top Angabe für h1 sicher.

    Ich habe <nav> in den <header> gesteckt, damit sie gemeinsam sticky sind. Die bottom-border soll nur die Grenze des Fading-Bereichs visualisieren. Ich setze unten ein Padding, um Platz für den Ausblendebereich zu schaffen, und einen gleichgroßen negativen Margin, damit die folgenden Elemente an dieser Stelle den Header überlappen können. Dadurch brauche ich kein Pseudoelement. Die --fade-height habe ich der h1 Überschrift als margin-top gegeben, damit der Textinhalt der Überschrift genau an den Fade-Bereich angrenzt.

    Schließlich noch der Einwand mit Buttons und Links von djr. Dagegen hilft pointer-events: none;.

    Rolf

    --
    sumpsi - posui - obstruxi
    1. problematische Seite

      @@Rolf B

      Der IE kann das nicht, aber der kann auch kein position:sticky. So what.

      Hehe. 👍

      Ich habe <nav> in den <header> gesteckt, damit sie gemeinsam sticky sind.

      Das sollte nicht die Begründung dafür sein.

      Du hast <nav> in den <header> gesteckt, weil die da strukturel reingehört: “The header element represents a group of introductory or navigational aids.” [Spec]

      Wenn das auch dem Stylen zugute kommt – fein.

      😷 LLAP

      --
      „Sag mir, wie Du Deine Maske trägst, und ich sage Dir, ob Du ein Idiot bist.“ —@Ann_Waeltin
      1. problematische Seite

        Hallo Gunnar,

        Du hast <nav> in den <header> gesteckt, weil die da strukturel reingehört:

        Ich schenke Dir ein l 💝😉

        Ähnliches schreibte ich um 14:09. Es darf da rein. Aber es muss nicht, oder? Wenn die Navi links an der Seite ist, wär's ja auch Blödsinn. Und es gibt viele Beispiele, auch im Self-Wiki, bei denen <nav> unter dem <header> steht. Deshalb dachte ich, dass eine andere Begründung als „es ist erlaubt, das zu tun“ sinnvoll wäre.

        Rolf

        --
        sumpsi - posui - obstruxi
  3. problematische Seite

    Hallo grmblfx,

    sorry, dass ich deine Seite nicht vorher angeschaut habe.

    • outer_wrapper ist unnötig. Schmeiß das div weg und verschiebe die CSS Eigenschaften auf den Body. _ upper_wrapper ist auch unnötig. Schiebe <nav> in den <header> hinein, wie ich es in meinem Beispiel gemacht habe. Das ist zwar nicht das, was unser Wiki vorschlägt, aber es ist durchaus zulässig. Die Inhaltskategorie von <header> ist flow content, und das ist auch der Inhaltstyp von <nav>. Das einzige, was ein Header nicht enthalten darf, ist <header>. Sogar die Spec hat ein Beispiel, wo <nav> im <header> steht.
    • -webkit-position oder -webkit-sticky ist meiner Meinung nach nicht mehr nötig, sticky gibt's lange genug.
    • Mein Beispiel oben passt für dein Farbschema nicht. Ich bau das noch um.

    Rolf

    --
    sumpsi - posui - obstruxi
    1. problematische Seite

      Hallo,

      erstmal Danke für die qualifizierte Antwort! Leider funktioniert das nicht wie gewünscht.

      • Die Navigation ist nicht mehr benutzbar, weil die links nicht mehr anklickbar sind. Das macht so keinen Sinn...
      • Dein Beispiel fadet unterhalb des Kopfbereiches die Hintergrundfarbe zu weiß. Was ich möchte, ist ja, dass der Text von main am Oberrand ausfadet, wenn ich nach oben scrolle. Vielleicht hatte ich mich unkklar ausgedrückt. Vermutlich müsste ich dann die CSS-Eigenschaft im main-Bereich setzen, wenn dadruch allerdings alle links unwirksam werden, macht es ja keinen Sinn...

      Gruß Daniel

      1. problematische Seite

        Hallo grmblfx,

        jetzt hast Du mich geärgert.

        Die Links sind nicht anklickbar. Ach was!!! Das ist deine Kritik? Natürlich sind sie es nicht. Es sind in meinem Beispiel oben ja gar keine. Meine völlig aus der Luft gegriffene Annahme war, dass Du so viel selbst erkennen kannst und es nicht stumpf übernimmst.

        Damit hab ich jetzt eigentlich gar keine Lust mehr, Dir zu helfen. Offenbar bist Du ein Copy-Schnorrer ohne jegliche eigene Ahnung. Das hast Du durch deinen Kommentar bewiesen. Aber weil ich den Umbau oben angekündigt habe und jetzt ohnehin fertig bin:

        https://jsfiddle.net/Rolf_b/ekxhob39/

        Erklärungen gibt's keine mehr. Ich habe fertig 😟

        Rolf

        --
        sumpsi - posui - obstruxi
        1. problematische Seite

          Hallo Rolf,

          falls Du es doch noch lesen solltest, was ich hoffe:

          Du scheinst mich falsch verstanden zu haben. Ich bezog mich nicht auf Dein Beispiel, sondern auf meine Seite, nachdem ich Deine Lösung reinkopiert und (natürlich!) angepasst hatte. Danach waren die links in der Navigation nicht mehr anklickbar. Das scheint mir mittlerweile auch logisch, denn mit pointer-events: none; für den gesamten Header werden ja alle links deaktiviert. Ich verstehe auch nicht, warum man das explizit angeben sollte. Wofür soll das gut sein? Wenn ich es weglasse, passiert genau das erwünschte Verhalten, lediglich in der obersten Textzeile, die gefadet wird, sind links nicht anklickbar, das finde ich verschmerzbar.

          Ich bedanke mich jedenfalls sehr für Deine Hilfe und bedaure, dass Du Dich geärgert hast. Ich versuche gerade, mir Ahnung anzueignen, "dumme" Fragen lassen sich dabei wohl nicht vermeiden.

          Gruß Daniel

          1. problematische Seite

            Hallo grmblfx,

            https://wiki.selfhtml.org/wiki/CSS/Eigenschaften/Anzeige/pointer-events

            lediglich in der obersten Textzeile, die gefadet wird, sind links nicht anklickbar, das finde ich verschmerzbar.

            Das ist keine gute Idee.

            Bis demnächst
            Matthias

            --
            Du kannst das Projekt SELFHTML unterstützen,
            indem du bei Amazon-Einkäufen Amazon smile (Was ist das?) nutzt.
          2. problematische Seite

            Hallo grmblfx,

            da habe dich dann sehr falsch verstanden 😳. Bitte entschuldige meinen Ausbruch.

            pointer-events:none hatte den Sinn, auf den Einwand von djr zu reagieren. Wenn der Fadeout-Bereich über einem Button oder Link im Haupttext ist, dann kannst Du den noch halbsichtbaren Link oder Button nicht mehr klicken.

            Dass das die Links in der Navigation ebenfalls tötet, daran habe ich nicht gedacht; meine ersten Versuche hatten noch das ::after Element.

            Ob man es jetzt noch mit einem einzigen header Element retten kann? Hmmm. Für die nav Links könnte man pointer-events:auto setzen, aber da ist noch was. pointer-events:none bewirkt auch, dass ein Link, der weit oben und unter dem Header versteckt ist, trotzdem noch geklickt werden kann. Das ist ganz schlechte UX.

            Also doch ein ::after Element, da muss pointer-events:none aber auf jeden Fall 'rein.

            Die Frage der Positionierung kann man so lösen, dass man die Position in Bezug auf die Unterkante berechnet. Mit Hilfe der Variablen --fade-height kann man das hier machen:

            header::after {
               position: absolute;
               width: 100%;
               height: var(--fade-height);
               bottom: calc(0px - var(--fade-height));
            }
            

            Wenn ich für ein absolutes Element die bottom-Eigenschaft setze, wird der Wert relativ zur Unterkante des Elternelements gerechnet.

            Guck noch mal ins Fiddle: https://jsfiddle.net/Rolf_b/ekxhob39/

            Um den Effekt von pointer-events zu zeigen, habe ich Buttons in den Text gesetzt und dafür einen Click-Handler registriert 😀.

            Möglicherweise geht es auch ohne absolute Positionierung, aber ein ::after Element (oder ein technisches div im HTML) ist nötig, und es artet meiner Vermutung nach in Gefummel mit Gradienten aus.

            Rolf

            --
            sumpsi - posui - obstruxi
            1. problematische Seite

              Wow, damit funktionieren jetzt sogar die links im gefadeten Bereich!

              Mittlerweile habe ich (Dank dieser Seite) auch verstanden, was pointer-events:none bewirkt, das war mir überhaupt nicht klar.

              Danke nochmal für die ausführliche Hilfe und Erläuterung!

              Zum Hintergrund: Ich habe während meines Studiums eine Stellenbörse (drarbeit.de) programmiert und mir damals dafür selber HTML, CSS, Javascript, PHP und MySQL beigebracht. Die Seite war zwischenzeitlich recht gut genutzt, ich hatte aber dann nie mehr die Zeit, sie zu aktualisieren. Sowohl das HTML/CSS als auch der PHP-Code sind absoluter "Anfänger-Stil". Nachdem mein Sohn jetzt unbedingt "Programmieren" lernen möchte (das schließt HTML und CSS ein, dann aber vor allem Javscript und PHP), haben wir uns einen Relaunch der Seite als Projekt vorgenommen, nachdem sie erstaunlicherweise immer noch von einigen Menschen genutzt wird. Wie ich festgestellt habe, hat sich mittlerweile v.a. durch CSS3 einfach extrem viel geändert und ich muss vieles neu lernen. Immerhin habe ich die Phase der DIV-Suppen und float-Hacks überspringen können 😀

              Bis sicherlich bald...