Fragen zur grid-Anwendung
Tommy A.
- css
- design/layout
Hallo zusammen,
nachdem ich zufällig im Forum darauf gestoßen bin, dass man mit grid relativ schnell responsive Seiten erstellen kann, habe ich begonnen, mich einzulesen und herumzuprobieren.
Jetzt habe ich erste Fragen.
Wie bekomme ich ein Bild, dann einen Text und dann noch ein Bild in den Header, wobei der aus mehreren Worten bestehende Text einzeilig bleiben sollte, soweit Platz vorhanden ist.
Das Ganze sollte im Header horizontal und vertical zentriert sein.
Mein Versuch:
header {
display: grid;
grid-template-columns: auto auto auto;
grid-column-gap: 1.5em;
}
index.html:
<header>
<img src="/fotos/bild1.GIF" alt="...." />
<h1>Das ist ein Test</h1>
<img src="/fotos/bild2.GIF" alt="...." />
</header>
Ergebnis:
.................................................................................................................
.................................................................................................................
Die punkt. Linien sollen die Breite des angezeigten Header darstellen.
Servus!
Hallo zusammen, nachdem ich zufällig im Forum darauf gestoßen bin, dass man mit grid relativ schnell responsive Seiten erstellen kann, habe ich begonnen, mich einzulesen und herumzuprobieren.
Jetzt habe ich erste Fragen.
Wie bekomme ich ein Bild, dann einen Text und dann noch ein Bild in den Header, wobei der aus mehreren Worten bestehende Text einzeilig bleiben sollte, soweit Platz vorhanden ist.
Du hast als Breite der Rasterfelder auto
eingestellt.
In der Referenz findest du die Seite für grid-template-columns:
Dort findest Du für den Wert auto folgende Beschreibung: auto
, "die sich am minimalen Bedarf des vorhandenen Inhalts ausrichtet"
Setze entweder auto 1fr auto
oder, wenn Du weißt, wie groß Deine Grafiken sind, deren Breite, z.B.: 100px 1 fr 100px
Herzliche Grüße
Matthias Scharwies
Die drei Elemente sollen nahe beieinander stehen (getrennt durch die gap-Größe).
Daher möchte ich den minimalen Inhalt, allerdings beim Text keinen Umbruch.
Eine Größe für die Bilder kann ich nicht angeben, da diese variieren können.
Servus!
Die drei Elemente sollen nahe beieinander stehen (getrennt durch die gap-Größe).
Daher möchte ich den minimalen Inhalt, allerdings beim Text keinen Umbruch.
white-space: nowrap;
Eine Größe für die Bilder kann ich nicht angeben, da diese variieren können.
ok
Herzliche Grüße
Matthias Scharwies
@@Matthias Scharwies
white-space: nowrap;
Nein. Wegen „wobei der aus mehreren Worten bestehende Text einzeilig bleiben sollte, soweit Platz vorhanden ist.“ (Hervorhebung von mir)
Das ist wohl ein Fall für width: max-content
, gepaart mit max-width: 100%
– bei Grid.
Mit Flexbox geht’s in dem Fall einfacher.
😷 LLAP
Hallo Gunnar,
geht beides, und max-content braucht man nicht. Siehe meine Antwort und das fiddle.
Was man brauchen könnte, wäre sowas wie max-real-content, damit das h1 Element bei umgebrochenem Inhalt nicht breiter ist als nötig. Aber das gibt's wohl nicht.
Rolf
@@Rolf B
geht beides, und max-content braucht man nicht. Siehe meine Antwort und das fiddle.
Von Zentrierung hatte Tommy nichts gesagt; die Headerinhalte sollen nach links ausgerichtet sein.
😷 LLAP
Hallo Gunnar,
RTFOP!
Das Ganze sollte im Header horizontal und vertical zentriert sein.
Sein Bild zeigte das, was er bisher erreicht hatte und womit er nicht zufrieden war.
Rolf
@@Rolf B
RTFOP!
Wer lesen kann, ist klar im Vorteil.
😷 LLAP
Hallo Tommy,
was Du da tust, kann man mit Grid gestalten, aber auch mit Flexbox. Grid ist vorzuziehen, wenn Du bei schmalen Bildschirmen eine andere Anordnung als "nebeneinander" erreichen möchtest.
Aber du kannst Grid natürlich auch grundsätzlich verwenden.
Eine Lösung kann so aussehen - ja, tatsächlich, mit auto für h1, nicht 1fr. Mit 1fr würdest Du die Breite des Bildschirms immer ausfüllen und die Flaggen würden immer am Rand stehen, nicht bündig an der Überschrift.
header {
display: grid;
grid-template-columns: auto auto auto;
grid-column-gap: 1.5em;
justify-content: center;
align-items: center;
}
header h1 {
margin: 0;
text-align: center;
}
Mit justify-content:center
sorgst Du dafür, dass die Gridzellen alle in der Mitte des Bildschirms stehen. Mit align-items:center
sorgst Du dafür, dass Flaggen und Text auch vertikal ordentlich ausgerichtet sind.
Und das text-align:center
in der h1 sorgt dafür, dass bei Umbruch in der Überschrift die beiden Teile zentriert übereinander stehen.
Es gibt aber ein ästhetisches Problem: Das "toi" steht allein auf der Zeile und ist viel schmaler als der erste Teil. Es wäre doch schöner, wenn da
C'est un test
pour toi
stünde. Das kriegt man hin:
<h1><span>C'est un test</span> <span>pour toi</span></h1>
und im CSS
header h1 span {
display: inline-block;
}
Ein Problem bekomme ich allerdings nicht gelöst: Sobald im h1 Element umgebrochen wird, stehen die Flaggen am Rand. Das h1 Element wird nicht automatisch so schmal, wie der umgebrochene Text Platz braucht. Ich glaube, das ist auch nicht lösbar.
Ein Fiddle zum anschauen: https://jsfiddle.net/Rolf_b/s4xo1a3h/
Ändere die Klasse des header Elements von grid auf flex, um die Flexbox-Lösung zu aktivieren (nicht wundern wenn sich visuell nichts tut, das soll ja gerade so sein 😉 ). Das Fiddle enthält zwei Header, einen mit grid, einen mit flex. Sie sehen gleich aus. Aber die grid-Lösung braucht deutlich weniger CSS Regeln.
Nur zum Spaß: Für den footer zeige ich, wie man sowas auch ohne Grid und ohne explizite img-Elemente lösen kann. Ich hatte auch kurz mit background-image experimentiert, aber dann kommt das entweder mit der Höhe der Flaggen oder mit der Ausrichtung des Textes nicht hin.
Rolf
Un merci à toi - et aux autres! Tommy
Hallo Rolf, jetzt habe ich doch noch eine Frage. Irgendwo hatte ich gelesen, dass mit grid die responsive Eigenschaft autom. gegeben sei oder aber einfach zu realisieren sei. Wie würde dies in Deinem Beispiel aussehen? Gruß Tommy
Hallo Tommy,
es ist doch schon responsiv. Die Breite passt sich automatisch an.
Welche weitergehende Flexibilität wünschst Du? Mit einer Kombination aus Grid und Media-Queries kannst Du beim Übergang von einem Breitenbereich in einen anderen die ganze Seite umbauen, wenn Du das willst, indem Du die Layout-Angaben für das Grid veränderst.
Dazu kann man Beispiele machen, es gibt aber schon reichlich davon im wilden weiten Web. Ohne deine konkreten Vorstellungen zu kennen läuft ein beliebiges Beispiel daher ins Leere.
Hast Du schon unser Grid-Tutorial durchgearbeitet? Dort findet sich gegen Ende ein Beispiel für unterschiedliche Grid-Layouts je nach Viewportbreite.
Wenn Du das durch hast und dann noch konkrete Fragen hast, stehen wir gern zur Verfügung. Dir ein fertiges Layout zum Kopieren vorzukauen ist hier eher nicht so beliebt.
Rolf
Hallo Tommy,
es ist doch schon responsiv. Die Breite passt sich automatisch an.
Ich dachte, dass sich auch die Schrift und die Bilder verkleinern.
Dir ein fertiges Layout zum Kopieren vorzukauen ist hier eher nicht so beliebt.
Das möchte ich auch nicht, aber wenn man anfängt, kommt man nun einmal vom Hundertsten ins Tausendste.
Muss ich demnach für die obige Frage (Schrift und die Bilder verkleinern)
Literatur über Responsive-Techniken lesen?
Für mich wäre es frustrierend, wenn ich mich erst wochenlang einlesen müsste, bevor ich ein kleines Erfolgserlebnis habe in Form eines kleinen Gerüsts meiner geplanten Anwendung.
Gruß
Tommy
Hallo,
Ich dachte, dass sich auch die Schrift und die Bilder verkleinern.
Damit kleine Geräte nur von Leuten mit sehr guten Augen verwendet werden können? Ich glaub du hast das Ziel von RWD nicht verstanden.
Gruß
Kalk
Wieso habe ich es nicht verstanden? Hier etwas zur Anpassung von Bildern an unterschiedliche Screengrößen.
Bilder im Responsive Design – Tipps für Seitenverhältnisse & Motive in flexiblen Layouts
Variante 1: Bilder behalten immer ihr Seitenverhältnis
....
Variante 2: Bilder ändern das Seitenverhältnis
....
Variante 3: Bilder werden ausgetauscht
....
Zu finden z.B. hier
Hallo Tommy,
Kalk war etwas sehr direkt. Aber im Prinzip hat er recht: wenn man bei responsivem Design nicht aufpasst, kann man je nach Bildschirmgröße zu unerwarteten bis unbrauchbaren Ergebnissen kommen. Man muss dafür viel testen, von der Smartwatch (die ich nicht habe) bis zum curved 32:10 Monster (was seit Weihnachten vor mir steht 😍).
Möglichkeiten zur Absicherung gibt es: Media-Queries und min/max Funktionen.
Rolf
@@Tabellenkalk
Ich dachte, dass sich auch die Schrift und die Bilder verkleinern.
Damit kleine Geräte nur von Leuten mit sehr guten Augen verwendet werden können?
Was man nicht machen darf: font-size: 5vw
Was man machen kann: font-size: min(1em + 1vw, 4em)
(siehe Heydon)
😷 LLAP
Hallo,
Was man machen kann:
font-size: min(1em + 1vw, 4em)
(siehe Heydon)
Warum lässt du meinen Bro calc()
weg, obwohl Heydon das nicht empfiehlt und wie wirkt sich das aus?
Gruß
Kalk
@@Tabellenkalk
Was man machen kann:
font-size: min(1em + 1vw, 4em)
(siehe Heydon)Warum lässt du meinen Bro
calc()
weg, obwohl Heydon das nicht empfiehlt und wie wirkt sich das aus?
Hättest du den Thread verfolgt, wärest du auf dies und das gestoßen.
😷 LLAP
Hallo Tabellenkalk,
tjaaa, Heydon schreibt: I tested, and without the calc() user-defined browser body font-size is not respected.
Aber wenn ich das in einem Fiddle (unter Chrome) probiere, wird die font-size des Body auch ohne calc berücksichtigt. So, wie Cos es sagte. Keine Ahnung welche Randbedingungen Heydon da noch hatte oder ob ihm einfach ein Irrtum unterlaufen ist.
Jedenfalls lernt man so mal wieder was dazu. Ich hatte Tommy ein max(3vw, 14px) vorgeschlagen; sicherlich wäre max(3vw, 0.9em) besser gewesen. Auf die Idee, den Font auch nach oben zu limitieren, bin ich nicht gekommen. Heydons Methode ist sehr clever, und vor allem variiert der Font dann auch nicht so stark.
Rolf
Hallo Tommy,
da gibt es diverse Möglichkeiten. Man kann zum Beispiel die Schriftgröße abhängig von der Breite des Viewports oder des Elternelements setzen; man muss dann nur, wie Kalk erwähnte, die Größen limitieren oder es kann unleserlich werden.
Die Techniken sind nicht so kompliziert. Du musst die unterschiedlichen Arten lernen, wie man Größen ausdrückt. Dazu haben wir im Wiki einen Artikel über CSS Maße.
Zum Responsiv-sein gibt es zwei wichtige Themen:
em ist eine ganz wichtige Einheit, sie basiert auf der Höhe eines Zeichens der an dieser Stelle gesetzten Schrift. Solange man nicht selbst etwas festlegt und der Browser auf einer Skalierung von 100% steht sind das sehr häufig 16px. Aber dafür gibt's keine Garantie, das darf man nicht gleichsetzen. Es gibt Leute, die setzen Media-Umschalter auf 37.5em oder 46.875em, weil sie vorher 500px oder 750px hatten und jetzt unbedingt responsiv sein wollen. Das ist Quatsch. So genau kommt es nicht drauf an, da hätten sie dann auch 38em und 47em nehmen können, oder gleich auf 40em und 50em runden.
Es ist deshalb ganz wichtig, auch ein bisschen zu experimentieren, welcher em Wert sinnvoll ist, um beispielsweise von einer Anordnung nebeneinander auf eine Anordnung untereinander umzuschalten. Einfach mal mit der Fenstergröße herumspielen, oder die Entwicklertools vom Browser öffnen (F12) und den Device-Simulator benutzen.
Media-Abfragen auf feste Pixelwerte (480px, 960px, etc) findet man zwar häufig in Beispielen, aber die sind nicht responsiv. Weil sie nicht auf die Zoomstufe im Browser reagieren.
Was man auch wissen muss: Ein CSS Pixel ist nicht unbedingt ein Gerätepixel. Ein iPhone hat mit seinem Retina-Display winzigkleine Pixel. Eine Webseite, die font-size:16px verlangt, würde ein Mikroskop benötigen. Weil es davon leider viel zu viele gibt, haben die Browser etwas eingeführt, was sie device-pixel-ratio nennen. In JavaScript ist das eine Eigenschaft des window-Objekts, im CSS war das mal ein Wert, den man in media-Queries verwenden konnte. Ein iPhone X hat eine device-pixel-ratio von 3 haben, dann ist 1 CSS Pixel = 3 Gerätepixel. Während das Gerät tatsächlich 1125×2436 Pixel hat, behauptet CSS, es habe 375×812. Wegen dieses Tricks musst Du Dich normalerweise nicht um die Pixeldichte des verwendeten Geräts kümmern. Aber wenn Du es willst, gibt es media-Queries auf resolution, womit Du die dpi (dots per inch) prüfen kannst.
Wenn Du die Schriftgröße abhängig von der Breite des Fensters haben willst: setze zum Beispiel font-size: 3vw. Das heißt: 3% der Fensterbreite. Wenn das Fenster 800px breit ist, wäre das eine Fontsize von 24px.
Damit die Schrift nicht zu klein wird, kann man die max-Funktion verwenden. Sie wählt den größeren der angegebenen Werte aus. font-size: max(3vw, 14px);
bedeutet: Nimm 3vw wenn es mehr als 14px sind, sonst 14px.
Bei den Fahnen könntest Du so vorgehen, dass Du die Grid-Spalte, die die Fahnen enthält, nicht auf auto setzt, sondern auf 9vw. Oder so. Auch hier ist eine Untergrenze sinnvoll: max(9vw, 50px) zum Beispiel.
Ich habe mein Fiddle dafür mal neu aufgelegt: https://jsfiddle.net/Rolf_b/neog8ztx/
Da ich die Fahnen nicht als Bild einbinde, sondern per linear-gradient erzeuge, musste ich einen weiteren Trick anwenden, um die Höhe auf 2/3 der Breite zu setzen: padding-top und padding-bottom kann man in % angeben, aber das ist der prozentuale Anteil der Breite des Elements, nicht der Höhe. width:100%; padding-top:66%;
sorgt bei einem ansonsten leeren div dafür, dass es so breit ist wie sein Container (was die grid-Spalte ist) und seine Höhe 2/3 dieser Breite beträgt. So, wie es die Trikolore sein soll.
D.h. man muss für ein responsives Layout diverse CSS Techniken kombinieren. Unser Wiki-Fleißkärtchensammler Matthias Scharwies hat dazu diese Artikelgruppe verfasst. Da steht eine Menge drin über relative Maße, Media-Queries und responsive Bilder.
Rolf
Sorry, ich bin es noch einmal:
Dazu kann man Beispiele machen, es gibt aber schon reichlich davon im wilden weiten Web. Ohne deine konkreten Vorstellungen zu kennen läuft ein beliebiges Beispiel daher ins Leere.
Beispiele sind hilfreich, allerdings nicht immer.
Du hast Dir mit Deinem viel Mühe gemacht, dafür danke ich.
Es ist aber auch ein Beispiel, das Anfänger zurückschreckt, wenn zahlreiche noch unbekannte Konstrukte vorkommen wie
.flagged::before, .flagged::after {
calc(0.75em + 75px)
linear-gradient(to right, #0055A4 33%, white 33%, white 67%, #ef4531 67%)
Wie ich vorhin schon geschrieben hatte, müsste ich mich wochenlang einarbeiten, um das zu verstehen und ggf. weiter anpassen zu können.
Schönen Gruß
Tommy
Hallo Tommy,
Wie ich vorhin schon geschrieben hatte, müsste ich mich wochenlang einarbeiten, um das zu verstehen und ggf. weiter anpassen zu können.
Leider kann ich Dich da nicht recht trösten. CSS ist eine umfangreiche Angelegenheit, und für ein responsives Layout benötigst Du einiges davon.
Die gute Nachricht ist: Viele meiner Spielereien aus dem Fiddle brauchst Du nicht. Im neu aufgelegten Fiddle habe ich die Flexbox und das ::before/::after wieder entfernt.
Mittels ::before und ::after habe ich mit CSS Pseudoelemente erzeugt, um Flaggen draus zu machen.
calc ist ein wichtiges Werkzeug. Gelegentlich muss man Größen berechnen, dafür dient calc. Das brauchte ich aber nur für die Platzierung der ::before/::after Pseudoelemente.
Gradienten kann man verwenden, muss man aber nicht. Deine Frankreichfahne war ein img Element. Nur hatte ich dafür keine URL. Darum habe ich es mit einem Lineargradienten (=Farbverlauf) in einem div simuliert.
Rolf
Hallo Rolf
Im neu aufgelegten Fiddle habe ich die Flexbox und das ::before/::after wieder entfernt.
Und der Text ist auch schon responsive!
Danke, das gibt mir Hoffnung.
Gruß
Tommy
@@Rolf B
Ein Fiddle zum anschauen: https://jsfiddle.net/Rolf_b/s4xo1a3h/
linear-gradient(to right, #0055A4 33%, white 33%, white 67%, #ef4531 67%)
?
Dir ist mein TIL entgangen?
linear-gradient(to right, #0055A4 33%, white 0 67%, #ef4531 0)
.
😷 LLAP
Hallo Gunnar,
ja. Entgangen oder vergessen. 2019, mein Gott, letztes Jahrzehnt!
Und verstanden habe ich es auch nicht. Wieso funktioniert die 0?
Rolf
@@Rolf B
2019, mein Gott, letztes Jahrzehnt!
Seitdem ein paar kleine Fortschritte bei mir. 😏
Und verstanden habe ich es auch nicht. Wieso funktioniert die 0?
„Wieso funktioniert was?“ ist eine Frage, die man bei der CSSBattle besser nicht stellt. 😉
§3.4.3 dürfte die richtige Stelle sein:
2. If a color stop or transition hint has a position that is less than the specified position of any color stop or transition hint before it in the list, set its position to be equal to the largest specified position of any color stop or transition hint before it.
😷 LLAP
Hallo Gunnar,
ok, danke. Also nichts, was man einem Einsteiger vorsetzen sollte 😉
Aber das Einsparen des Farbnamens ist eine gute Idee.
Rolf
@@Rolf B
ok, danke. Also nichts, was man einem Einsteiger vorsetzen sollte 😉
Doch …
Aber das Einsparen des Farbnamens ist eine gute Idee.
… auch das Einsparen der Wiederholung des Color-Stop-Wertes ist eine gute Idee.
😷 LLAP
Hallo,
wenn ich das Ergebnis des Fiddle-Beispiels von Rolf ansehe, so stelle ich fest, dass durch die beiden span-tags eine zusätzliche Spalte entstanden ist.
Definiert in CSS aber waren nur drei Spalten.
Für die vierte Spalte wären dann doch keine Eigenschaften definiert. Trotzdem ist die Ausgabe korrek? Wie kommt dies?
Jetzt habe ich dazu eine weitergehende Frage.
Welche Tags bewirken eine Darstellung des Tag-Inhalts in einer neuen Spalte(Zelle)?
Wie kann ich erreichen, dass derartige Tags mit Inhalt in einer Zelle bleiben?
Hallo,
woran liegt es, dass sich meine Bilder (nach vielen Versuchen) noch immer nicht bei kleinem Viewport verkleinrt?
Hier der Code:
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Stop-Test</title>
<style>
* {
box-sizing: border-box;
}
body {
display: grid;
}
@media (min-width: 45em) {
body {
grid-template-columns: 1fr 3fr 1fr;
}
}
header {
grid-column: 1 / -1;
display: grid;
grid-template-columns: auto auto auto;
grid-column-gap: 1.5em;
justify-content: center;
align-items: center;
}
header h1 {
margin: 0;
text-align: center;
font-size: max(3vw, 14px);
}
header img {
max-width: 100%;
width: 100%;
height: auto;
}
h1 span {
display: inline-block;
}
</style>
</head>
<body>
<header>
<img src="logo.JPG" alt="Stop-Schild" />
<h1>Stop</h1>
<img src="logo.JPG" alt="Stop-Schild" />
</header>
Hallo Tommy,
du hast zwei Grids. Eins auf dem Body, und der hat nur für min-width:45em ein Template. Aber 1fr 3fr 1fr ist wenig wirksam, wenn das Element im Grid (der Header) die Angabe grid-column: 1 / -1 hat, denn das heißt: von ganz links bis ganz rechts.
Und dann ist eins auf dem header, das hat ein unveränderliches Template.
Ich glaube, da ist Dir was durcheinander geraten.
Rolf
Hallo Rolf,
Du magst Recht haben.
Mit grid und responsive gleichzeitig bin ich offensichtlich überfordert.
Der Text wurde ja verkleinert, nicht aber das Bild.
Gerade habe ich mir noch einmal Dein Jsfiddle angeschaut, aber das ist auch nicht responsive, da es ja für einen anderen Zweck erstellt wurde.
Trotzdem vielen Dank für Deine Bemühungen.
Schönen Gruß
Tommy
Hallo Tommy,
was willst Du denn haben?
Wenn Du im Grid die Spaltenbreite für das Bild auf auto setzt und dem Bild width:100% gibst, dann kann der Browser ja nur die intrinsische[1] Bildgröße als Maßstab nehmen.
Da die font-size die Schrifthöhe bestimmt, wäre es demnach sinnvoll, dem Bild eine Höhe vorzugeben. Der Browser berechnet dazu an Hand der intrinsischen Maße des Bildes die Breite.
Am elegantesten fände ich, die font-size im <header> festzulegen und an das <h1> zu vererben. Dann schreibst Du an das Bild einfach nur eine Höhe von beispielsweise 1.5em und das Bild orientiert sich automatisch an der Schriftgröße im Header. Der Abstand zwischen Bild und Text ebenso.
Guckst Du: https://jsfiddle.net/Rolf_b/48bf1npo
Rolf
Das, was in der Bilddatei an Breite und Höhe gespeichert ist. ↩︎
Vielen Dank an alle, insbesondere aber an Rolf!