Rolf B: Höhenangaben - werde ich das jemals verstehen?

Hallo alle,

ich wollte für User123 eine kleine Demo machen.

Und ich verzweifle daran.

https://jsfiddle.net/Rolf_b/2r1whf57/1/

Wie bringe ich das Bild dazu, nicht höher zu werden als die figure? Die Höhe der figure soll von der Viewport-Höhe abhängen.

Ich habe gelernt, dass prozentuale Höhen nur greifen, wenn die Höhe des Elternelements festgelegt ist. Wieso ist das bei einem row-template mit fr darin nicht der Fall? Am auto für die Caption liegt es nicht, das kann man auf einen festen Wert legen und die Bildhöhe wird trotzdem nicht limitiert. Es liegt am 1fr für die img Zelle. 20em, und alles ist gut. Aber ich will ja gerade flexibel bleiben.

Auf Grid bin ich nicht festgelegt, ich hatte es vorher erfolglos mit Flexbox versucht. Das div um das img war auch nur ein müder Rettungsversuch (ohne Erfolg).

Wie macht man eine responsive Galerie?!?!?! Die Beispiele im Wiki haben immer feste Höhe.

Rolf

--
sumpsi - posui - obstruxi
  1. Hallo Rolf,

    figure img {
      max-width: 100%;
      height: 85vh; /* <-- z.B. */
      vertical-align: bottom;
    }
    

    Grüße, Martl

    1. Hallo Martl,

      genau das wollte ich ja vermeiden, dem Bild eine feste Höhe zu geben.

      Ich würde es gerne von außen nach innen steuern, so dass das Bild seinem Container folgt.

      Rolf

      --
      sumpsi - posui - obstruxi
      1. Hallo Rolf,

        ganz pragmatisch: Als Hintergrundbild des Containers mit :contain.

        Grüße, Martl

  2. @@Rolf B

    Wie bringe ich das Bild dazu, nicht höher zu werden als die figure? Die Höhe der figure soll von der Viewport-Höhe abhängen.

    So ungefähr?

    (Ja, ich weiß, du willst eigentlich die max. Höhe für den Container (Bild + Bildunterschrift) angeben, nicht fürs Bild.)

    😷 LLAP

    --
    “When I was 5 years old, my mother always told me that happiness was the key to life. When I went to school, they asked me what I wanted to be when I grew up. I wrote down ‘happy.’ They told me I didn’t understand the assignment, and I told them they didn’t understand life.” —John Lennon
    1. Hallo Gunnar,

      eigentlich nicht. Das ist nur eine verschwurbelte Tarnung für

      figure {
      	--image-max-height: 90vh;
      	position: relative;
      }
      
      figure img {
      	height: var(--image-max-height);
      	width: auto;
      }
      
      figcaption {
      	margin-top: 0.5em;
      }
      

      also genau das, was ich vermeiden wollte und was auch schon Martl vorschlug. Nur ohne custom property.

      Offenbar habe ich meine Motivation unvollständig erläutert.

      Ich möchte nicht auf eine einzeilige figcaption angewiesen sein. Sie könnte mehrzeilig sein, und ist dann höher. Das img soll dann automatisch kleiner werden. Deswegen dachte ich an ein Grid mit Row-Template auto 1fr. Oder an eine Flexbox mit flex:0 0 auto für die Caption und flex:1 0 1em (oder so) für das img (oder ein div wo das img drinsteckt).

      Geht das schlichtweg nicht? Will ich etwas, wofür die aktuellen Layoutmodelle nicht vorgesehen sind?

      Die Background-Idee von Martl muss ich noch ausprobieren, bin aber grundsätzlich nicht davon überzeugt, dass das semantisch korrekt ist.

      Rolf

      --
      sumpsi - posui - obstruxi
    2. Hallo Gunnar,

      ich habe es jetzt so gelöst. Ohne jQuery.

      Kann man sowas als einfache Slideshow vorstellen? Die Idee ist, dass der Nutzer das HTML anlegt und dann createGallery aufruft, parametriert mit Galeriecontainer, Bilder-Array und Umschaltzeit.

      Durch die Kapselung könnte man mehrere Slideshows gleichzeitig steuern.

      createGallery kümmert sich darum, dass eine Umschaltung auf's nächste Bild erst erfolgt wenn es auch wirklich da ist. Bei langsamem Netz wird einfach so lange gewartet, bis auf dem HTMLImageElement Objekt die complete Eigenschaft gesetzt ist. Weil fade-out / fade-in Effekte drin sind, brauche ich drei img Elemente. Eins wird ausgeblendet, eins wird eingeblendet, und in einem wird das Folgebild geholt.

      Rolf

      --
      sumpsi - posui - obstruxi
  3. Hallo Rolf,

    Wie bringe ich das Bild dazu, nicht höher zu werden als die figure? Die Höhe der figure soll von der Viewport-Höhe abhängen.

    indem du die Höhe des <li> begrenzt max-height:100%, aber das wird wahrscheinlich noch nicht reichen, weiss aber auch nicht genau was das Endziel sein soll, eine Gallery, ok klar aber ohne in etwa deine Wunschvorstellung zu kennen, schwierig.

    Gruss
    Henry

    --
    Meine Meinung zu DSGVO & Co:
    „Principiis obsta. Sero medicina parata, cum mala per longas convaluere moras.“
    1. Hallo Henry,

      indem du die Höhe des <li> begrenzt

      tu ich doch. Ein outline zeigt mir, dass die Begrenzung des li und des figure Elements funktioniert.

      Aber das img pfeift drauf. Ich habe das Fiddle nochmal aktualisiert; die figure ist jetzt ein Grid. Höhe der figcaption: auto. Höhe des Bildes: 1fr.

      Höhe ul: 570px Höhe li: 570px Höhe figure: 570px Höhe figcaption: 18px Höhe img - man sollte 552px erwarten. Real: 599px (beim Kölsch)

      Aber ich hab jetzt ein Workaround gefunden, scheint mir.

      <figure>
        <figcaption>...</figcaption>
        <div>
          <img src="..." alt="..."
        </div>
      </figure>
      
      figure {
        margin: 0; padding: 0;
        height: 100%;
        display: grid;
        grid-template: "caption" auto "bild" 1fr / 1fr;
        justify-items: center;
      }
      figure div {
        grid-area: bild;
        height: 100%;
        overflow:hidden;
      }
      figure img {
        max-width: 100%;
        max-height: 100%;
        vertical-align: bottom;
      }
      

      Ohne das div geht's nicht. Ohne overflow:hidden auch nicht. Offenbar braucht es den block formatting context, den overflow:hidden erzeugt, um die Höhe des div "definite" zu machen. Und nur eine "definite height" sorgt dafür, dass die Höhe eines Kindelements in % akzeptiert wird.

      Und jetzt wollte ich noch erreichen, dass ein breites Bild vertikal zentriert wird. Align-irgendwas? Justify-irgendwas? Von wegen. Das div ums img hat ja eine Höhe von 100%, d.h. das kann ich vertikal zentrieren wie ich will, das füllt die Grid-Zelle immer voll aus. Und max-height:100% nimmt mir wieder die definite height weg, die das img für seine Höhe braucht.

      Also muss das div jetzt auch noch eine flexbox werden, damit ich da align-items:center reinschreiben kann.

      Irgendwie ist das alles noch nicht der Weisheit letzter Schuss.

      Rolf

      --
      sumpsi - posui - obstruxi
      1. Hallo Rolf,

        habe gerde erst gesehen, dass es ein Beispiel für user123 werden soll. Da kann ich es mir leider des Endergebnis auch nicht vorstellen. Weil, ein einzelnes Bild ist ja anders als die Frage wie der Slider nachher fertig aussehen soll. Nur, glaube ich du machst es dir zu kompliziert udn user123 hat jquery sicher nicht nötig.

        Also ist das einzige was ich im Moment einbringen kann sind viell. Beispiele und eines davon, was ausnahmsweise mal keine Hintergrundgrafiken nutzut, wäre zb. das hier.

        Gruss
        Henry

        --
        Meine Meinung zu DSGVO & Co:
        „Principiis obsta. Sero medicina parata, cum mala per longas convaluere moras.“
  4. Ich habe gelernt, dass prozentuale Höhen nur greifen, wenn die Höhe des Elternelements festgelegt ist.

    Da liegt dein Denk-/Wissensfehler. So absolut ist das falsch. Prozentangaben beziehen sich auf unterschiedliche Ausgangswerte.

    Bei img-Elementen beziehen sich height-Angaben in Prozent immer auf die Bildgröße. Das Elternelement hat deshalb mit der Prozentangabe in deinem Beispiel nichts zu tun.

    Das kannst du zum Beispiel sehen, wenn du dem Bild spaßenshalber mal eine height-Angabe von 120% mit auf den Weg gibst.

    Oder bei den gleichen Angaben (also 100%) erst mal ein kleiners Bild und dann ein größeres Bild einfügst.

    1. Hallo Mr.Murphy,

      Bei img-Elementen beziehen sich height-Angaben in Prozent immer auf die Bildgröße. Das Elternelement hat deshalb mit der Prozentangabe in deinem Beispiel nichts zu tun.

      Hast Du dafür ein Beispiel, das das klar beweist? Oder einen Link auf eine (reputable) Quelle? Wenn nicht, dann glaube ich an einen Irrtum deinerseits. Das height-Attribut eines img legt die intrinsische Höhe des Bildes fest und ist seit HTML5 nur in Pixel zulässig (ohne px Suffix). In HTML 4 war auch eine Prozentangabe erlaubt, und die HTML 4 Spec sagt:

      Note that lengths expressed as percentages are based on the horizontal or vertical space currently available, not on the natural size of the image, object, or applet.

      Das lese ich als das exakte Gegenteil deiner These.

      Aber wie auch immer, ich spreche hier nicht vom height-Attribut des img Elements, sondern von der CSS Eigenschaft height, und die legt die Höhe eines Elements basierend auf der Höhe des Elternelements fest. Alles, was ich heute gelesen und gebastelt habe, bestätigt das.

      Die Einschränkung ist nur, dass die Elternhöhe festgelegt sein muss (englisch: definite - das meint: sie darf nicht erst durch den Layoutprozess bestimmt werden). Zumindest verstehe ich die Spec so. Und das scheint der Grund, warum eine Höhenermittlung von außen nach innen, basierend auf Berechnungen, nicht gelingt.

      Rolf

      --
      sumpsi - posui - obstruxi
      1. Stimmt, da habe ich mich durch mein Testen in die Irre leiten lassen.

        Mit ist aber auch noch nicht klar, was du eigentlich erreichen willst.

        Ich habe das bislang grundsätzlich so verstanden:

        Du hast einen Eltern-Container. Höhe 90vh.

        In das Eltern-Element sollen Kind-Container. Die Kind-Container sollen übereinander gestapelt sein. Bis auf eines sind mit opacity alle unsichtbar.

        Die Kind-Container enthalten eine Bildbeschreibung und darunter ein Bild.

        Die Bildbeschreibung und das Bild sollen insgesamt im Eltern-Container zentriert sein.

        Alles weitere sind Hilfskonstrukte und können wegfallen.

        Wenn das so richtig ist wäre meine Frage: Sollen die Bilder auch vergrößert werden oder bis maximal ihrer Originalgröße angezeigt werden?

        1. Hallo Mr.Murphy,

          meine Idee war, eine responsive Slideshow zu haben (oder Galerie). Die ggf. auch nur Teil einer responsiven Seite ist. D.h. die Boxgröße der Galerie sollte sich durch das Seitenlayout festlegen - ein Grid, ein Flexboxmix, was sich der Designer gerade ausgedacht hat.

          Innerhalb der Galeriebox sollen die Bilder dann so groß wie möglich angezeigt werden.

          Das bedeutet aber, dass ich den Bildelementen max-height/max-width 100% geben muss. Ein grid mit Template "galerie" 1fr "footer" auto / 1fr hat das Problem, dass "1fr" keine definite Höhe ist. Selbst dann nicht, wenn ich dem footer eine feste Höhe gebe. Und dadurch ist die Galeriezelle aus Sicht der 100% so hoch wie das ganze Element.

          Ich hatte jetzt einige Male eine Kombination, die funktioniert hat, aber ich weiß nicht, wieso. Denn wenn ich nur ein bisschen ändere, brechen die Bilder wieder aus. Einmal schien das zwischenschalten eines div mit overflow:hidden (erzeugt neuen Block Formatting Context) zu helfen, dann wieder nicht.

          Im Moment habe ich mal wieder eine Kombi, die funktioniert. Fullpage-Layout mit Grid ("header" auto "main" 1fr "footer" auto / 1fr). Die main-Area ist die Galerie, und die figures darin sind absolut positioniert mit width/height: 100%. Wenn ich sie statt dessen mit einem Grid übereinanderlege, funktioniert es nicht. Eine figure ist ein Grid mit "caption" auto "image" 1fr / 1fr;. In der image-Area ist ein div, das enthält das img-Element, und das div ist eine Flexbox. Zum Zentrieren.

          Ein gemeinsames vertikales Zentrieren der figcaption zusammen mit dem Bild gelingt mir nicht. Weil ich es nicht schaffe, eine Box zu erzeugen, die so hoch ist wie das Bild, aber nicht höher als der Platz unter der figcaption.

          Das ist tatsächlich das Layout, das ich haben möchte. Ich habe das Page Layout Grid variiert, und die Slideshow folgt korrekt. Es ist aber reiner Versuch und Irrtum, das Zentrier-DIV nervt mich, und ich kann nicht gänzlich sagen, warum es so sein muss, damit es funktioniert. Mich deucht, dass eine JS-gesteuertes Layout verständlicher wäre.

          Rolf

          --
          sumpsi - posui - obstruxi
          1. Hallo Rolf,

            Mich deucht, dass eine JS-gesteuertes Layout verständlicher wäre.

            Nö, geht aber trotzdem einfacher und sogar pure CSS.

            Gruss
            Henry

            --
            Meine Meinung zu DSGVO & Co:
            „Principiis obsta. Sero medicina parata, cum mala per longas convaluere moras.“
            1. Hallo Henry,

              vielleicht einfacher, aber auf jeden Fall nicht wie gewünscht. Die Bilder werden abgeschnitten, nicht skaliert, wenn das Fenster verkleinert wird.

              Rolf

              --
              sumpsi - posui - obstruxi
              1. Hallo Rolf,

                vielleicht einfacher, aber auf jeden Fall nicht wie gewünscht. Die Bilder werden abgeschnitten, nicht skaliert, wenn das Fenster verkleinert wird.

                ähm, nein bei mir nicht(?). Ist aber auch noch kein HTML Grundgerüst drum herum und kein <meta name="viewport" usw., aber falls das so sein sollte sicherlich leicht anpassbar.

                Gruss
                Henry

                --
                Meine Meinung zu DSGVO & Co:
                „Principiis obsta. Sero medicina parata, cum mala per longas convaluere moras.“
          2. Mein Lösungsversuch beinhaltet nicht alle, aber ich denke doch die wesentlichen, deiner Anforderungen. Es geht mir auch darum überhaupt erst mal ein funktionierendes Beispiel zu erstellen.

            Bilder mittels CSS zu vergrößern führt häufig zu Problemen. Ich halte mich deshalb an die bewährte Regel, Bilder so groß zur Verfügung zu stellen, wie sie maximal angezeigt werden sollen.

            Die Bildbeschreibung außerhalb der Grafik führt auch zu Problemen. Zumal wenn die Höhe nicht festgelegt ist, weil die Beschreibung umbrechen kann (was ich auch für sinnvoll halte). Deshalb habe ich das figcaption-Element mit einer durchsichtigen Hintergrundfarbe auf dem Bild plaziert.

            Zur Übersichtlichkeit habe ich das CSS in drei Abschnitte unterteilt, die natürlich auch zusammengefasst werden können. So lässt sich aber leichter Testen.

            Um die Bildbeschreibung unten zu plazieren habe ich die entsprechenden CSS-Anweisungen als Kommentar eingefügt. Gleiches für eine zweite Farbkombination.

            Über- und unterhalb des Bildes habe ich einen Rand gelassen, weil mir das optisch besser gefällt.

            Bei mir passt sich der Inhalt flexibel auf die Fensterhöhe und -breite an. Auch die Bildbeschreibung. Einfach mal ausprobieren. Bei schmaler Fensterbreite wird auch das hinterste Bild sichtbar.

            
            <!DOCTYPE html>
            <html lang="de">
            <head>
               <meta charset="utf-8">
               <title>Bildergröße</title>
               <meta name="description" content="Platzhalter - Ein kurze Beschreibung des Inhalts in Satzform">
               <meta name="viewport" content="width=device-width, initial-scale=1.0">
            
               <style>
            
               /*Basisangaben*/
                  * {
                     box-sizing: border-box;
                     min-width: 1px;
                  }
                  html {
                  }
                  body {
                     margin: 0rem 0rem 0rem 0rem;
                  }
               }
            
               /*Grafiken*/
               @media all {
                  figure {
                     min-width: 1px;
                     max-width: 100%;
                     min-height: 1px;
                     margin: 0rem;
                  }
                  img {
                     min-width: 1px;
                     display: block;
                     max-width: 100%;
                     border: 0px;
                  }
               }
            
               /*.gallery*/
               @media all {
                  .gallery {
                  }
                  .gallery div {
                     height: 100vh;
                     display: flex;
                     flex-wrap: wrap;
                     justify-content: center;
                     align-content: center;
                  }
                  .gallery figure {
                     display: flex;
                     flex-wrap: wrap;
                     justify-content: center;
                     align-content: center;
                  }
                  .gallery img {
                     max-height: 100vh;
                     padding: 1rem;
                  }
                  .gallery figcaption {
                  }
               }
            
               /*.gallery css-grid, um die div-Elemente zu stapeln*/
               @media all {
                  .gallery {
                     display: grid;
                     grid-template-columns: 1fr;
                     grid-template-rows: 1fr;
                  }
                  .gallery div {
                     grid-column-start: 1;
                     grid-row-start: 1;
                  }
                  .gallery figure {
                  }
                  .gallery img {
                  }
                  .gallery figcaption {
                  }
               }
            
               /*.gallery figcaption*/
               @media all {
                  .gallery {
                  }
                  .gallery div {
                  }
                  .gallery figure {
                     position: relative;
                  }
                  .gallery img {
                  }
                  .gallery figcaption {
                     background-color: hsla(0, 0%, 100%, 0.5);
                     /*background-color: hsla(0, 100%, 50%, 0.4);*/
                     color: black;
                     /*color: white;*/
                     position: absolute;
                     top: 0;
                     /*bottom: 0;*/
                     width: calc(100% - 2rem);
                     padding: 0.5rem 1rem;
                     margin-top: 1rem;
                     /*margin-bottom: 1rem;*/
                  }
               }
            
               </style>
            </head>
            <body>
               <main id="content" class="content">
                  <section class="gallery">
                     <div>
                        <figure>
                           <figcaption>Ein Glas Kölsch</figcaption>
                           <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/f/f0/Glas_malz_muehlenkoelsch.jpg/401px-Glas_malz_muehlenkoelsch.jpg" alt="Glas mit Kölsch">
                        </figure>
                     </div>
                     <div>
                        <figure>
                           <figcaption>Deutzer Brücke mit Hauptbahnhof und Dom</figcaption>
                           <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/be/Stadtbild_K%C3%B6ln_%2850MP%29.jpg/1024px-Stadtbild_K%C3%B6ln_%2850MP%29.jpg" alt="Stadtpanorama">
                        </figure>
                     </div>
                     <div>
                        <figure>
                           <figcaption>Einmol im Johr kütt d'r Rhing us em Bett und noch viel mehr Text um einen Zeilenumbruch zu provozieren, damit er kontrolliert werden kann.</figcaption>
                           <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/8/8e/Bundesarchiv_B_422_Bild-0086%2C_K%C3%B6ln%2C_Rheinufer%2C_Hochwasser.jpg/573px-Bundesarchiv_B_422_Bild-0086%2C_K%C3%B6ln%2C_Rheinufer%2C_Hochwasser.jpg">
                        </figure>
                     </div>
                  </section>
               </main>
            </body>
            </html>
            
            
            1. Hallo Mr.Murphy,

              muss ich mir in Ruhe anschauen.

              Aber wenn da denn nicht in Zeile 44 height: 100vh; stünde... Damit liegt eine definite Höhenangabe des Containers vor...

              Rolf

              --
              sumpsi - posui - obstruxi
              1. Dann machst du aus dem "height: 100vh" halt ein "max-height: 100vh".

                1. Da hab ich meine vorige Antwort zu schnell abgeschickt, ich wollte noch etwas mehr schreiben:

                  Durch das max-height wird das div-Element grundsätzlich so hoch wie sein Inhalt, maximal so hoch wie die Browserhöhe.

                  Die Höhe wird damit durch das höchste Bild bestimmt. Das gilt auch wenn Bilder mittels opacity ausgeblendet werden.

            2. Hallo Mr.Murphy,

              habe dein Beispiel mal eingestellt.

              Gruss
              Henry

              --
              Meine Meinung zu DSGVO & Co:
              „Principiis obsta. Sero medicina parata, cum mala per longas convaluere moras.“
              1. Danke, die Möglichkeit von w3schools ist mir bislang durch die Lappen gegangen.

                Das gefällt mir, weil der Quelltext dort "in einem Stück" eingefügt und rauskopiert werden kann. Ich habe mich gleich mal angemeldet.

                1. Hallo Mr.Murphy,

                  Danke, die Möglichkeit von w3schools ist mir bislang durch die Lappen gegangen.

                  Das gefällt mir, weil der Quelltext dort "in einem Stück" eingefügt und rauskopiert werden kann. Ich habe mich gleich mal angemeldet.

                  dto, genau deswegen und weil nicht unzählige Scripte im Hintergrund ablaufen mag ich es auch. Aber Anmeldung? Ist nicht notwendig.

                  Gruss
                  Henry

                  --
                  Meine Meinung zu DSGVO & Co:
                  „Principiis obsta. Sero medicina parata, cum mala per longas convaluere moras.“
                  1. Ich habe es so verstanden, dass, wenn ich Seiten speichern und online zur Verfügung stellen will, angemeldet sein muss.

                    Als reiner Nutzer muss man nicht angemeldet sein und kann trotzdem im Quelltext rumspielen. Das finde ich auch gut.

                    1. Hallo Mr.Murphy,

                      Ich habe es so verstanden, dass, wenn ich Seiten speichern und online zur Verfügung stellen will, angemeldet sein muss.

                      nein, aber interessant zu wissen, dass dies dort so vermutet wird.

                      Gruss
                      Henry

                      --
                      Meine Meinung zu DSGVO & Co:
                      „Principiis obsta. Sero medicina parata, cum mala per longas convaluere moras.“