Stefan Einspender: Rahmen um automatisch skaliertes Bild

Hallo,

nachfolgend ein kurzer Quelltext. Der blaue Kasten verändert seine Größe in Abhängigkeit von der Größe des Browserfensters. Das Bild im blauen Kasten wird automatisch so skaliert, dass es den blauen Kasten bestmöglich ausfüllt, allerdings werden die Bildproportionen dabei nicht verändert.

Und die Frage ist jetzt, wie kann ich es realisieren, dass dort rote Rahmen direkt um das Bild (mit 13 Pixel Abstand) erzeugt wird. Aktuell ist der der Rand des blauen Kastens, was so nicht sein soll.

<!doctype html><html lang="de"><head><meta charset="utf-8"><title>test</title>

	<style>
		div {
			height: calc(100vh - 200px);
			width: calc(100vw - 200px);
			margin-top: 100px;
			margin-left: 100px;
			background: #009;
		}

		img {
			height: calc(100% - 30px);
			width: calc(100% - 30px);
			object-fit: contain;
			padding: 13px;
			border: 2px solid red;
		}
	</style>

</head><body>

	<div><img alt="" src="https://via.placeholder.com/700x400?text=Platzhalterbild" height="400" width="700"></div>

</body></html>

Vielleicht hat da ja jemand von Euch eine Idee, vielen Dank 😀

Viele Grüße, Stefan

  1. Hallo Stefan,

    mein bester Versuch ist bisher

    div {
      height: calc(100vh - 200px);
      width: calc(100vw - 200px);
      margin-top: 100px;
      margin-left: 100px;
      display: flex;
      justify-content: center;
      align-items: center;
      background: #009;
    }
    
    img {
      max-height: 100%;
      max-width: 100%;
      padding: 13px;
      box-sizing: border-box;
      border: 2px solid red;
    }
    

    Allerdings hat die Freude ein Ende sobald das div breiter ist als das Bild. Solange das Bild groß genug ist, funktioniert es. Ist das div zu breit, nimmt das Bild bei genügend viel Höhe nicht mehr die ganze Breite ein.

    Ob man es mit grid besser hinbekommt - keine Ahnung.

    Die Notlösung wäre JavaScript und ein resize-Handler, aber darauf würde ich verzichten solange es irgendwie anders geht.

    Rolf

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

      nahe dran, aber Bild ist dann nicht mehr proportional.
      Hab das dann mal versucht:

      div {
      height: calc(100vh - 200px);
      width: calc(100vw - 200px);
      margin-top: 100px;
      margin-left: 100px;
      background: #009;
      display: flex;
      justify-content: center;
      align-items: center;
      		}
      
      img {
       max-width:calc(100% - 10vw);height:auto;
      padding: 13px;
      border: 2px solid red;
      		}
      

      auch nicht schön, aber viell. ausbaufähig. Wenn Stefan genauer erklären würde, was er beabsichtigt, gäbs, glaube ich, bestimmt sowieso bessere Lösungen.

      Gruss
      Henry

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

        vielleicht mal zur Erklärung, also ich habe auf einer Seite oben eine Überschrift und unten eine Fußzeile. Die beiden Bereiche belegen eine feste Höhe, so dass der blaue Kasten variabel als Größe bleibt. In diesem blauen Kasten soll dann immer genau ein Bild mittig zentriert abgebildet werden. Es soll den blauen Kasten möglichst komplett ausfüllen, aber dabei müssen die Proportionen erhalten bleiben. Also wenn es Hochformat ist, bleiben links und rechts mehr freie Flächen zum Bleistift. Und umd das Bild direkt herum (mit etwas Abstand) soll ein Rahmen sein.

        Habe Deine Variante probiert, da schiebt sich das Bild aus dem Viewport raus (und überlagert dann sicher auch die Kopf- und Fußzeile). Auch das Zoomen fehlt leider komplett, soll aber vorhanden sein.

        Viele Grüße, Stefan

    2. Hallo Rolf,

      habe ich ausprobiert, funktioniert so aber nicht wie gewünscht. Das Bild soll "gezoomt" werden, wenn das div größer ist, aber dabei proportional bleiben. Und wenn man bei Deiner Variante das Fenster zusammenschiebt, dann wird das Bild gestaucht, ist ganz ungünstig.

      Viele Grüße, Stefan

      1. Hallo Stefan,

        ja, das habe ich ja geschrieben: meine Lösung funktioniert nur bis zur "natürlichen" Größe des Bildes.

        Wenn ich möchte, dass sich das Bild in der Größe an das div anpasst, dann passt sich auch der Bildrahmen an das div an.

        Die Angabe width:100% für das img macht das Element so breit wie sein Elternelement, und der Rahmen entspricht dieser Breite. Das object-fit:contain bezieht sich nur auf den dargestellten Inhalt des img Elements, nicht auf das Element selbst.

        Deshalb die Lösung mit max-height und max-width, das macht das img so groß wie im aktuellen div möglich und behält den Aspect bei, aber es zoomt nicht mehr.

        Die Lösung für das fehlene zoomen kann sein, das Bild zu vergrößern. Mach es nicht 700x400, sondern 2100x1200 und komprimiere stärker, so dass die Dateigröße in etwa gleich bleibt. Das hat zwei Vorteile:

        • auf Retina-Displays sieht das Bild besser aus
        • du musst schon sehr große Monitore haben, damit es nicht mehr mitskaliert.

        Wichtig ist die Angabe von box-sizing:border-box am Bild, weil ansonsten Padding und Border die angegebene Breite und Höhe des Bildes vergrößern und Du sie mit calc herausrechnen müsstest.

        Die Angabe von object-fit ist bei meinem Vorschlag nicht mehr nötig, die max-width/max-height Angaben sorgen automagisch dafür, dass das Seitenverhältnis des Bildes eingehalten wird.

        Um Hintergrundbild und Seiteninhalt zu trennen, sollte man das div absolut positionieren.

        Beispiel

        Rolf

        --
        sumpsi - posui - obstruxi
  2. Hallo Stefan Einspender,

    auch ich habe mit flexbox zentriert, habe allerdings mit der Farbe des div-Elements sehr getrickst.

    div {
      height: calc(100vh - 200px);
      width: calc(100vw - 200px);
      margin-top: 100px;
      margin-left: 100px;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    
    img {
      max-width: 100%;
      max-height: 100%;
      object-fit: contain;
      background: blue;
      border: 200px solid blue;
      outline: 2px solid red;
      outline-offset: -187px;
    }
    

    wenn das Bild verkleinert werden muss und die proportionen nicht mehr stimmen, wird allerdings der Abstand der roten Linie zum Bild ggf. größer als gewünscht.

    Warum soll der Abstand eigentlich genau 13px sein?

    Bis demnächst
    Matthias

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

      hm ... sieht jetzt irgendwie nicht so aus wie gedacht. Der blaue Bereich (ja, der kommt dann nicht vom div, sondern vom img), ist fix, der passt sich also nicht dynamisch der Fenstergröße an. Und wenn man das Fenster "unproportional" verkleinert, dann bleibt der Rahmen nicht mehr am Bild.

      Allerdings muss ich mir die Sache mit outline mal genauer anschauen, weiß gar nicht gleich, was genau damit möglich ist.

      Viele Grüße, Stefan

      1. Hallo,

        Warum soll der Abstand eigentlich genau 13px sein?

        ...

        Können wir bitte für das neue Jahr in die Charta mitaufnehmen, dass keine Rückfragen mehr gestellt werden, weil sie sowieso nicht beantwortet werden…

        Gruß
        Kalk

        1. Hallo,

          der Abstand des Rahmens zu Bild soll umlaufend einen festen Wert haben. Rein visuell schien mir für ein normalgroßes Browserfenster da 13 Pixel ganz gut. Später werde ich es über eine CSS-Query ermutlich bei kleinen Browserfenstern (Mobil-Devices etc.) vermutlich ganz ausblenden, da dort ja nicht soviel Platz ist.

          Um die Frage zu beantworten, aktuell sind es 13 Pixel, weil es für mich so am Schönsten aussieht 😁

          Viele Grüße, Stefan

  3. Aus der unklaren Beschreibung und den bekannten CSS-Angaben vermute ich dass ein zentriertes Bild mit einem Rahmen, der 13px Abstand vom Bild haben soll, das Ziel ist.

    Erst mal sollten die Attribute aus dem img-Element entfernt werden, zumal die nur Probleme verursachen, also:

    <body>
       <div>
          <img alt="" src="https://via.placeholder.com/700x400?text=Platzhalterbild">
       </div>
    </body>
    
    

    und dazu folgendes CSS:

    div {
       background: #009;
       width: calc(100% - 200px);
       margin: 100px auto;
       display: flex;
       justify-content: center;
       align-items: center;
    }
    img {
       display: block;
       max-width: 100%;
       padding: 13px;
       border: 2px solid red;
       margin: 30px;
    }
    
    
    1. Hallo,

      sah erstmal ganz vielversprechend aus, aber ganz passt es nicht. Je nach Größe des Viewports ist der blaue Bereich größer oder kleiner. Und in diesen soll sich das Bild "einpassen". Also entweder es wird vergrößert oder verkleinert. Jeweils so, dass Breite und/oder Höhe den blauen Bereich ausfüllen (abzgl. Abstand und Rand für das Bild).

      Bei Deiner Variante stehen links und rechts die roten Ränder über, was aber vermutlich leicht zu korrigieren ist. Allerdings wird das Bild nicht auf die Höhe des Viewports gezoomt, was ein Problem ist. Auch wenn man die Höhe des Browserfensters verkleinert, wird es nicht angepasst.

      Viele Grüße, Stefan

    2. @@Mr.Murphy

      Erst mal sollten die Attribute aus dem img-Element entfernt werden, zumal die nur Probleme verursachen

      Das ist falsch.

      Browser kennen bei (richtig) gesetzten width- und height-Attributen das Seitenverhältnis des Bilds, bevor dieses geladen ist, und reservieren (auch bei responsiven Bildern) den entsprechenden Platz, sodass nach dem Laden des Bilds kein erneuter Seitenaufbau nötig ist.

      Ist also so gut wie immer sinnvoll, width und height anzugeben.

      😷 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
  4. Hallo,

    habe mal jetzt noch drei Screenshots erstellt, da wird hoffentlich besser erkennbar, was ich möchte. Der schmale grüne Rahmen soll nur die Grenzen des Viewports markieren, d.h. den möchte ich nicht erzeugen. Wäre ja auch sehr einfach. Ich möchte gern direkt um das Bild (mit z.Bsp. 13 Pixel Abstand) einen Rahmen haben.

    Die drei Ansichten sind nur durch Veränderung der Browserfenstergröße entstanden und sind in Bezug auf das Bild genau das gewünschte Verhalten.

    Variante 1 - Browserfenster in Normalgröße

    Variante 2 - Browserfenster hoch und schmal

    Variante 3 - Browserfenster breit und niedrig

    Soweit die verschiedenen Varianten, wie bekomme ich da die Sache mit dem Rahmen "am Bild" hin?

    Viele Grüße, Stefan

    1. Das Hauptproblem bei der Hilfe durch uns bist offensichtlich du.

      Du verschweigst uns zum Einen wichtige Angaben und bist zum Anderen nicht in der Lage unsere Angaben in dein vorhandenes HTML/CSS einzufügen. Übersetzt: Dein CSS macht unser CSS "kaputt", woran wir aber nichts ändern können, da wir dein HTML und CSS nicht kennen. Wenn du uns dein HTML/CSS verheimlichst solltest du zumindest in der Lage sein, unsere Lösungen so einzufügen, dass die durch deine Angaben nicht zerstört werden.

      Deine 200px Abstand oben und unten scheint die Höhe für header und footer zu sein. Woher sollen wir das wissen? Das können wir erst durch deinen Antworten vermuten.

      Das Bilder über ihre Größe hinaus vergrößert werden sollen ist in der Regel auch nicht gewünscht. Dass du das wahrscheinlich trotzdem willst erschließt sich erst aus deinen Antworten.

      Wo bei meiner Lösung die "roten Ränder überstehen" sollen (was immer du damit überhaupt meinst) kann ich nicht nachvollziehen.

      Offensichtlich willst du ein sogenannten Holy-Grail-Layout mit einer Kopfzeile (header), einem Hauptteil (main) und einer Fußzeile (footer). In dem Hauptteil soll ein Bild die Fläche größtmöglich ausfüllen ohne selbst zu verzerren.

      Dann sollten feste Höhenangaben komplett vermieden werden. Die Höhe von Kopf- und Fußzeile ergeben sich aus deren Inhalt.

      Und was soll passieren, wenn der Text unter dem Foto umbricht?

      1. Hallo Mr.Murphy,

        Das Hauptproblem bei der Hilfe durch uns bist offensichtlich du.

        Einen Menschen als Problem zu bezeichnen, ist wirklich nicht besonders nett.

        Du verschweigst uns zum Einen wichtige Angaben und bist zum Anderen nicht in der Lage unsere Angaben in dein vorhandenes HTML/CSS einzufügen.

        zum einen macht er das vielleicht nicht absichtlich und zum anderen ist ihm das nicht unbedingt vorzuwerfen.

        Möglicherweise solltest du gezielter nachfragen und geduldiger sein.

        Bis demnächst
        Matthias

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

        mein vollständiges HTML/CSS, wo sich das Problem nachvollziehen lässt, habe ich doch im ersten Beitrag mit eingefügt? OK, vielleicht war die Beschreibung nicht so leicht nachvollziehbar, aber was in der Kopf- oder Fußzeile steht, ist doch völlig irrelevant? Letztlich geht es darum, dass das Bild sich automatisch in einem Bereich maximal skalieren soll und darum (direkt um das Bild) noch ein Rahmen sein soll. Vermutlich könnte ich die Sache mit dem div auch zur Vereinfachung weglassen, so dass das Bild body komplett ausfüllt und dort das gewünschte Verhalten hat. Vermute wenn es dafür eine Lösung gibt, kann ich die dann für meinen Anwendungsfall weiterverwenden.

        Den Begriff "Holy-Grail-Layout" kenne ich nicht, werde ich mich dann mal schlaumachen. Die Höhe der Kopf- und Fußzeilen möchte ich (zumindest wenn die Größe des Browserfensterns unverändert bleibt) fix haben. Der Nutzer kann sich am Ende hintereinander Bilder anschauen (immer einzeln) und da wäre es unschön, wenn z.Bsp. das Layout der Fußzeile springt.

        Was den Text unter dem Foto betrifft, der ist immer recht kurz und ich werde da später auch die Schriftgröße abhängig von der Viewport-Breite anpassen. Die Frage an sich verstehe ich, habe ich auf dem Schirm das Thema.

        Das Hauptproblem bei der Hilfe durch uns bist offensichtlich du.

        Uih, hoffentlich habe ich "früher" sowas nicht auch geantwortet, aber ab und an war es ja auch mal etwas ruppig 😂

        Viele Grüße, Stefan

    2. Padding ist als CSS-Eigenschaft auch für Elemente vom Typ img erlaubt.

      img.articleHeadImage
      {
          padding: 1rem;
          // …
      }
      
      1. Hallo Raketenwilli, hallo Stefan

        div {
          height: calc(100vh - 200px);
          width: calc(100vw - 200px);
          margin-top: 100px;
          margin-left: 100px;
          display: flex;
          justify-content: center;
          align-items: center;
        }
        
        img {
          max-width: 100%;
          max-height: 100%;
          object-fit: contain;
          background: blue;
          border: medium solid red;
          padding: 1rem;
        }
        

        Bis demnächst
        Matthias

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

          also vielleicht stelle ich mich wirklich an, mein Quelltext sieht dann wie folgt aus:

          <!doctype html><html lang="de"><head><meta charset="utf-8"><title>test</title>
          
          	<style>
          
          div {
            height: calc(100vh - 200px);
            width: calc(100vw - 200px);
            margin-top: 100px;
            margin-left: 100px;
            display: flex;
            justify-content: center;
            align-items: center;
          }
          
          img {
            max-width: 100%;
            max-height: 100%;
            object-fit: contain;
            background: blue;
            border: medium solid red;
            padding: 1rem;
          }
          
          	</style>
          
          </head><body>
          
          	<div><img alt="" src="https://via.placeholder.com/700x400?text=Platzhalterbild" height="400" width="700"></div>
          
          </body></html>
          
          

          Der blaue Bereich (hier das img) füllt das div nicht aus. Und sobald das Bild sich verkleinert, liegt der rote Rahmen nicht mehr am Bild an.

          Habe da nicht den Überblick, gibt es sowas wie jsfiddle, wo ich Euch ohne Anmeldung mal den Quelltext reinkopieren und ihr ihn auch ändern könnt?

          Viele Grüße, Stefan

          1. <img alt="" src="https://via.placeholder.com/700x400?text=Platzhalterbild" height="400" width="700">
            

            Also ich erziele wesentlich interessanter erscheinende Ergebnisse, wenn ich das height="400" width="700" im HTML kurzerhand weglasse...

            1. Ich geh jetzt feiern. Ganz brav nur mit genau einer Freundin.

          2. Hallo Stefan Einspender,

            Der blaue Bereich (hier das img) füllt das div nicht aus. Und sobald das Bild sich verkleinert, liegt der rote Rahmen nicht mehr am Bild an.

            Das kann ich nicht bestätigen.

            Habe da nicht den Überblick, gibt es sowas wie jsfiddle, wo ich Euch ohne Anmeldung mal den Quelltext reinkopieren und ihr ihn auch ändern könnt?

            Ja. jsfiddle. Codepen. …

            Bis demnächst
            Matthias

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

              danke, habe jetzt ein jsfiddle erstellt. Wenn ich nur das Ausgabefenster aufrufe, dann wird bei mir der blaue Bereich nur so groß wie das Bild. Aber der soll ja von der Größe des Browserfensters abhängig sein (und das Bild dann entsprechend größer). Und wenn ich das Browserfenster verkleinere, ist der rote Rahmen nicht mehr um das Bild, sondern bleibt am Rand des blauen Bereichs.

              Wenn es bei Dir wirklich nicht so aussieht, dann kann ich auch noch Screenshots nachliefern ...

              Viele Grüße, Stefan

              PS: Der Link mit dem Ausgabefenster funktioniert jetzt scheinbar nicht mehr, ist vielleicht sessionbasiert o.ä. Egal, dann halt im jsfiddle den Bereich unten rechts vergrößern/verkleinern.

              1. Hallo Stefan Einspender,

                lass mal die HTML-Attribute weg. Vielleicht kommt das deinen Vorstellungen mehr entgegen.

                Bis demnächst
                Matthias

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

                  habe ich gemacht und auch mal das Platzhalterbild vergrößert, dann sieht es so aus. Ja, was soll ich sagen, da gibt es jetzt nix auszusetzen. Das Bild wird so skaliert, wie ich es mir vorstelle und der Rahmen bleibt auch beim Bild.

                  Danke an der Stelle, werde ich dann nächstes Jahr weiterverarbeiten und wünsche derweil Dir und allen Beteiligten einen guten Rutsch 😊

                  Viele Grüße, Stefan

                2. @Matthias Apsel:

                  Du hast recht, aber Gunnar Bittersmann schreibt dazu:

                  Das ist falsch.

                  Browser kennen bei (richtig) gesetzten width- und height-Attributen das Seitenverhältnis des Bilds, bevor dieses geladen ist, und reservieren (auch bei responsiven Bildern) den entsprechenden Platz, sodass nach dem Laden des Bilds kein erneuter Seitenaufbau nötig ist.

                  Ist also so gut wie immer sinnvoll, width und height anzugeben.

                  Grundsätzlich ist nicht vorgesehen ein Bild über seine reale Größe hinaus mittels CSS zu vergrößern. Das zerstört schlicht jedes Layout.

                  Um überhaupt mal zu einem Ergebnis zu kommen habe ich mal eine komplette Seite erstellt. Schriften, Farben, Ränder, Abstände, ... können natürlich noch angepasst werden:

                  
                  <!DOCTYPE html>
                  <html lang="de">
                  <head>
                     <meta charset="utf-8">
                     <title>Layout</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>
                        * {
                           box-sizing: border-box;
                           min-width: 1px;
                        }
                        html {
                        }
                        body {
                           margin: 0;
                           height: 100vh;
                           display: grid;
                           grid-template-rows: 100px 1fr 100px;
                        }
                        header {
                           background-color: antiquewhite;
                           display: flex;
                           justify-content: flex-end;
                           align-items: center;
                        }
                        header h1 {
                           font-size: 40px;
                           padding: 20px;
                           margin: 0;
                        }
                        main {
                           background-color: dodgerblue;
                        }
                        main div {
                           background-color: gold;
                           width: 100%;
                           height: 100%;
                           padding: 10px;
                           display: flex;
                           justify-content: center;
                           align-items: center;
                        }
                        main img {
                           min-width: 1px;
                           max-width: 100%;
                           max-height: calc(100vh - 220px);
                           padding: 13px;
                           border: 2px solid red;
                        }
                        footer {
                           background-color: antiquewhite;
                           padding: 10px 20px;
                           display: flex;
                           justify-content: center;
                           align-items: center;
                        }
                        footer>* {
                           margin: 0;
                        }
                     </style>
                  </head>
                  <body>
                     <header>
                        <h1>Blindtext</h1>
                     </header>
                     <main>
                        <div>
                           <img src="https://via.placeholder.com/2100x1200?text=Platzhalterbild" alt="Platzhalterbild">
                        </div>
                     </main>
                     <footer>
                        <p>Kurzer Text</p>
                     </footer>
                  </body>
                  </html>
                  
                  

                  Für die üblichen Kritiker: Dass das schlechtes HTML ist ist klar. Es geht erst mal nur um die Darstellung.

                  1. Hallo,

                    auch Dir vielen Dank, funktioniert einwandfrei, genau so wie gewünscht. Werde mir dann auch Deine Variante nächstes Jahr genau anschauen und für mich für Deine oder die von Matthias entscheiden. Auf jeden Fall betrachte ich damit mein Problem als gelöst, vielen Dank nochmals!

                    Viele Grüße, Stefan