Markus Steffen: Bekomme Responsive-Design nicht hin

Hallo liebe Forum-Gemeinde,

ich versuche mich an einer sehr einfachen Webseite, die allerdings angepasst an die gängigen Geräte (PC, Tablet, Smartphone) dargstellt werden soll.

Bei einem PC soll eine Grafik 2/3 des Bildschirms einnehmen (volle Höhe, 66% der Breite), daneben (den restlichen 33%) soll Text dargestellt werden. Die Grafik liegt in 1258x1020x24 BPP vor. Der Text soll eine Mindestbreite haben, damit er sich nicht zusammenschiebt, wenn das Fenster skaliert wird. Die Grafik soll sich automatisch skalieren bis zu einer Mindestbreite/Höhe, dann soll die Grafik und der Text untereinander dargestellt werden.

Was mache ich falsch? Wahrscheinlich lässt sich das total leicht und mit der Hälfte der Zeilen lösen?

Vielen Dank für Eure Hilfe.

MfG MS

<!DOCTYPE html>
<html>
<title>Meine Firma</title>
<meta http-equiv="content-type" content="text/html; UTF-8">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
	body,table,tr,td 
	{ 
		font-family:Verdana; 
		font-size:10pt; 
		margin: 0px;
		padding: 0px;
		font-size: 20pt;
		line-height: 25pt;
		letter-spacing: -0.5px;
		color: #999999;
	}
	.bild 
	{
		background: url("bgimage2.jpg") center no-repeat;
		border: 1px solid black;
		min-width: 480px;
		height: 100vh;
	}
	.impressum
	{
		padding-top:15px;
		min-width: 250px;
	}

	@media only screen and (min-width: 1025px) 
	{
		.bild 
		{
			width: 66%;
			margin-right: 20px;
			float:left;
		}
		.impressum 
		{
			padding-top:15px;
			min-width: 250px;
		}
	}

	@media only screen and (max-width: 1024px) 
	{
		.bild 
		{
			width: 66%;
			margin-right: 20px;
			float:left;
		}
		.impressum 
		{
			padding-top:15px;
			min-width: 250px;
		}
	}

	@media only screen and (max-width: 480px) 
	{
		.bild 
		{
			width: 100%;
		}
		.impressum 
		{
			padding-top:15px;
			min-width: 250px;
		}
	}


</style>
<body>
<div id="container">
	<div class="bild">&nbsp;</div>
	<div class="impressum">
		Meine Firma<br/>
		Meine Strasse<br/>
		D-PLZ Ort<br/>
		Deutschland<br/>
		<br/>
		Ust.IdNr: DE1122334455<br/>
		<br/>
		Telefon: 0800 - 11 22 333<br/>
		Telefax: 0800 - 11 22 444<br/>
		Mobile: 0172 - 123 45 67<br/>
		</table>
		<br/>
		info@meinefirma.de<br/>
		www.meinefirma.de
	<div>
</div>
</body>
</html>
  1. Hallo Markus,

    da ist einiges zu tun bei Dir ;)

    Zunächst mal: Es ist heute üblich, Schriftgrößen relativ zu der vom User eingestellten Default-Schriftgröße festzulegen. Dazu bezieht man sich auf die Größeneinheiten em und rem. "em" ist die Breite eines "m" in der gewählten Schriftart. Legst Du für ein Element eine Breite von 10em fest, dann ist es so breit wie 10 m in der Schrift, die für das Element festgelegt ist. In den meisten Browsern ist - sofern die Defaults gelten - 16px, aber darauf verlässt man sich nicht. Der User kann einen Zoom eingestellt haben. "rem" steht für "root em", das sind die m in der Schriftart des body, damit bist Du unabhängig von Schriften, die irgendwo in der Elementhierarchie des DOM eingestellt wurden.

    Dementsprechend setzt man auch keine Media-Breaks in Pixel. Du überlegst Dir, welche Umschaltpunkte für deine Inhalte sinnvoll sind, gemessen in em. Wenn Dein Impressum bspw. 15em benötigt, dann legst Du eine Mindestbreite von 15em fest. Den media break, ab dem die Darstellung untereinander erfolgt, sollte dann bei 25em oder 30em liegen, damit Du keine Darstellungen bekommst wo das Bild zu sehr gequetscht ist.

    Und drittens gilt: Mobile first (oder "kleiner Bildschirm hat Vorrang"). Du designst deine Seite so, dass sie ohne Mediabreaks auf einem Smartphone oder in einem kleinen Desktopfenster brauchbar aussieht. Und dann fügst Du mit Media-Abfragen zusätzliche Styles hinzu, die bei breiteren Fenstern zu einer besseren Platznutzung führen.

    Viertens ist ein Container-DIV etwas, was in vielen Beispielen zu sehen ist - aber es ist unnötig. Wenn Deine Seite nicht mehr enthält als dein Beispiel zeigt, kannst Du das body-Element als Container nutzen. Aber für meinen Vorschlag lasse ich es mal drin, ich weiß ja nicht, ob du noch anderes auf der Seite hast.

    Es ist auch üblich, statt einer Div-Wüste semantisch sprechendere Elemente zu verwenden. HTML5 bietet eine Menge davon. Was für Dich richtig ist, hängt auch vom Rest des Seiteninhalts ab, aber wenn Du NUR das Bild und den Impressumtext hast, dann kann das Bild ein <aside> sein und das Impressum wäre <main>. Das Bild kann auch eigentlich ein <img> sein - es sei denn, du willst CSS Features für Hintergrundpositionierung nutzen. Eventuell könnte man das Bild sogar als Hintergrund des Containers setzen und auf das <aside> (oder .bild div bei Dir) ganz verzichten. Das lasse ich jetzt aber mal bleiben.

    Ich würde es so schreiben:

    <main>
    	<aside></aside>
    	<article>
        <h1>Impressum</h1>
        <p>Meine Firma
           Meine Strasse
           D-PLZ Ort
           Deutschland</p>
        <p>Ust.IdNr: DE1122334455</p>
        <p>Telefon: 0800 - 11 22 333
           Telefax: 0800 - 11 22 444
           Mobile: 0172 - 123 45 67</p>
        <p>info@meinefirma.de
           www.meinefirma.de</p>
      </article>
    </main>
    

    Und das passende Styling wäre

    body { 
      font-family:Verdana, sans-serif; 
    	margin: 0px;
    	padding: 0px;
    }
    
    @media (min-width: 40em) {
      main {
        display: flex;
        max-width: 100vw;
      }
      aside { 
        flex: 0 1 66%;
      }
      article { 
        flex: 1 0 20em;
      }
    }
    
    aside
    {
    	background: url("bgimage2.jpg") center no-repeat;
    	border: 1px solid black;
    	height: 100vh;
      box-sizing: border-box;
    }
    
    article
    {
      padding: 0.5em;
    }
    h1
    {
    	font-size: 1.5rem;
    	color: #999999;
    }
    p
    {
      white-space: pre-line;
    	margin: 0 0 0.5em 0; 
    	font-size: 1.5rem;
    	line-height: 125%;
    	color: #999999;
    }
    

    Die normale Anzeige erfolgt untereinander. Sobald der Viewport mindestens 42em breit ist, wird der Container (das main Element) zu einer Flexbox gemacht (display:flex). Flexbox ist nicht mehr ganz neu, aber jedenfalls deutlich neuer als float, und es extra dafür gemacht, Dinge nebeneinander zu stellen.

    Wie sich die Kinder der Flexbox verhalten, wird durch die flex Eigenschaft festgelegt. Es gibt 3 Werte: Streckverhalten (0=nein, 1=ja), Schrumpfverhalten (0=nein, 1=ja) und Basisbreite. Ok, die Aussage "1=ja" ist eine Lüge für Kinder, man kann auch andere Zahlen angeben. Schau Dir das in unserem Wiki an.

    Für Dich habe ich dem aside ein flex: 0 1 66%; gegeben. Heißt: Wächst nicht, kann aber bedarfsweise schrumpfen und hat eine Ausgangsbreite von 66%. Der Impressum-Artikel hat flex: 1 0 20em;, kann also wachsen, aber nicht schrumpfen, und ist dadurch mindestens 20em breit. Ist der Bildschirm breit genug (mindestens 60em), kann das Impressum also breiter werden. Ist er schmaler als 60em, bleiben es 20em und das Bild schrumpft.

    Unterhalb von 40em (doppelte Impressumbreite, kannst Du natürlich anders wählen) verschwindet die Flexerei und alles steht untereinander.

    Deine <br>achiale Art des Zeilenum<br>uchs habe ich durch <p> Elemente ersetzt. Mit white-space: pre-line wird erreicht, dass die Spaces aus dem Markup nicht erscheinen, aber sehr wohl die Zeilenumbrüche. Und natürlich braucht dein Impressum auch eine Überschrift (aber ist auf deiner Seite vielleicht eh schon da, nur anderswo).

    Passe es für Dich an, viel Spaß damit. Sicherlich wird es noch Kommentare zu diesem Vorschlag geben, guck Dir dann an was davon für Dich passt.

    Rolf

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

      erstmal herzlichen Danke für Deine ausführliche Antwort. Mit einer solchen super Erklärung hab ich gar nicht gerechnet. Lieben Dank.

      Kannst Du mir vielleicht noch einen Tipp geben, wie ich das schnell und einfach für die verschiedenen Devices testen kann?

      Ich habe Dein Beispiel mal 1zu1 übernommen und auf meinem PC gestestet, indem ich das Browserfenster einfach immer weiter verkleinert habe. Dabei hat sich die Grafim zwar auch verkleinert, aber nicht ausreichend, sodass nur ein immer kleinerer Teil der Grafik gezeigt wurde.

      Und auch, wenn dann der Umbruch erfolgt ist, also die Breite kleiner 40em wurde, dann sind die beide Elemente zwar untereinander dargestellt worden, aber es wurde auch nur ein Teilauschnitt der Grafik angezeigt.

      Hätte die Angabe height: 100vw; nicht dafür sorgen sollen, dass die Grafik immer proportional zur Fensterhöhe skaliert angezeigt wird?

      MS

      1. Hallo Markus,

        Hätte die Angabe height: 100vw; nicht dafür sorgen sollen, dass die Grafik immer proportional zur Fensterhöhe skaliert angezeigt wird?

        ja, aber abhängig vom Höhe/Breite-Verhältnis kann sie immer noch beschnitten werden, wenn sie breiter ihr Elternelement ist - oder man kann horizontal scrollen.

        Wenn das nicht sein soll, sondern die Graik dann auch in der Breite gestaucht werden soll (notfalls sogar so, dass die Proportionen verzerrt werden), könntest du mit max-width nachhelfen.

        Ciao,
         Martin

        --
        Frage an die Kollegin am Montagmorgen: "Na, wie war dein Wochenende?"
        Depressive Kollegin: "Hell, dunkel, hell, dunkel, Montag."
      2. Hallo Markus,

        Devices teste ich - sofern nicht physisch vorhanden - entweder über Fenstergrößen oder über die Device-Simulation der Entwicklerwerkzeuge von Chrome.

        height:100vw setzt die Höhe des Containers auf 100% Viewporthöhe. Aber dein Bild ist Hintergrund, und der wird nicht automatisch skaliert. Dafür brauchst du die background-size Eigenschaft. Der Wert "cover" könnte Dir helfen. Du verwendest die Kombi-Eigenschaft background, da gehört die size-Angabe zwischen Position und Repeat.

        Alternativ könntest Du überlegen, statt Hintergrundbild ein <img> Element zu nutzen.

        Rolf

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

          nochmals lieben Dank. Die Angabe background-size: cover; hat die Anzeige extrem verbessert. Dann werde ich nun weiter mit den CSS-Eigenschaften spielen, Deine Ausführungen haben mir dabei sehr geholfen.

          MS

  2. @@Markus Steffen

    Rolf ja schon eine Layoutmöglichkeit gezeigt, hier nun eine andere – die einfachere: CSS Grid. Da legt man (fast) alles fürs Containerelement fest; die Kindelemente muss man gar nicht anfassen.

    Wie Rolf schon sagte, kann body oder main das Containerelement sein. In meinem Beispiel ist es main.

    Bei einem PC soll eine Grafik 2/3 des Bildschirms einnehmen (volle Höhe, 66% der Breite), daneben (den restlichen 33%) soll Text dargestellt werden.

    	main
    	{
    		display: grid;
    		grid-template-columns: 2fr 1fr;
    		gap: 1em;
    	}
    

    teilt den Container in zwei Spalten, wobei die erste (2fr) doppelt so breit ist wie die andere (1fr).

    Damit der Text nicht am Bild klebt, etwas Zwischenraum (gap) dazwischen.

    Der Text soll eine Mindestbreite haben, damit er sich nicht zusammenschiebt, wenn das Fenster skaliert wird.

    Kleine Abwandlung:

    	main
    	{
    		display: grid;
    		grid-template-columns: 2fr minmax(15em, 1fr);
    		gap: 1em;
    	}
    

    legt für die zweite Spalte eine Mindestbreite von 15em fest.

    Die Grafik soll sich automatisch skalieren bis zu einer Mindestbreite/Höhe,

    img
    {
    	width: 100%;
    	height: auto;
    }
    

    dann soll die Grafik und der Text untereinander dargestellt werden.

    In Mobile-first-Denke: Erst must du gar nichts tun, weil untereinander schon das Verhalten ohne Zutun ist.

    Dann, ab einer bestimmten Viewportbreite (in meinem Beispiel 40em) soll’s anders sein. Also obige Regel in ein media query gepackt. (Und wie Rolf sagte: in em!)

    @media (min-width: 40em)
    {
    	body
    	{
    		display: grid;
    		grid-template-columns: 2fr minmax(15em, 1fr);
    		gap: 1em;
    	}
    }
    

    Das war’s dann auch schon. Der Rest ist Schmuck am Kleid.

    Kein Schmuck hingegen:

    <!DOCTYPE html>
    <html>
    

    Da fehlt die Angabe der Sprache. <html lang="de"> für Deutsch.

    LLAP 🖖

    --
    „Man kann sich halt nicht sicher sein“, sagt der Mann auf der Straße, „dass in einer Gruppe Flüchtlinge nicht auch Arschlöcher sind.“
    „Stimmt wohl“, sagt das Känguru, „aber immerhin kann man sich sicher sein, dass in einer Gruppe Rassisten nur Arschlöcher sind.“

    —Marc-Uwe Kling
    1. Hallo Gunnar,

      auch Dir herzlichen Dank für das Beispiel und die Erläuterungen. Mit Grid hatte ich es tatsächlich auch schon versucht, aber da wohl irgendwelchen Fehler gemacht, denn da hatte es so gut wie gar nicht funktioniert. Anders als Dein Beispiel, denn hier verkleinert sich die Grafik sogar noch besser.

      Somit komme ich jetzt bestens weiter. Nochmals besten Dank.

      LG, MS