heinetz: Zuviel Markup

Hallo Forum,

ich habe hier das Verhalten zweier Content-Elemente im Viewport simuliert:

a) https://codepen.io/heinetz/pen/jQpBKZ
b) https://codepen.io/heinetz/pen/pQZbEg

Man sieht das beide Elemente sich konstruktionsbedingt unterschiedlich ausbreiten. Um diese Darstellung zu erreichen, braucht es um jedes Content-Element zusätzliches Markup. Ohne das zusätzlich Markup kann ich die Darstellung nur bis hierher annähern:

c) https://codepen.io/heinetz/pen/wQxddX
d) https://codepen.io/heinetz/pen/mQjmEw

Ist die Darstellung von a und b mit dem Markup aus c und d möglich? Mit Pseudoelementen vielleicht? Oder kommt man zumindest mit weniger Markup aus?

Was meint Ihr?

danke und

gruss, heinetz

(Edit by Rolf B: Links zu Links und Listen zu Listen gemacht)

  1. Hallo heinetz,

    Codepen a) ist falsch, da sind die divs nicht paarig. Aber das Extradiv kann man entfernen ohne das Ergebnis zu verändern.

    Ansonsten sehe ich zwischen a) und c) keinen Unterschied.

    Was ich angesichts der Demo-Eigenschaft ignoriere:

    • ein <h2> hat als Textinhalt "Content" - Was denn nun? Heading oder Content 😀
    • Größenangaben in Pixel, das gehört sich nicht, das ist nicht responsiv.

    Worauf ich hinweisen möchte:

    • in c) ist ein - für die Demo - unnötiges position:relative und margin-bottom:10px
    • display:block ist für divs nicht nötig
    • mutmaßlich sind divs nicht das Markup der Wahl, aber das weiß man erst wenn man den Kontext sieht, in dem das nachher landet.
    • Du hast magic numbers - die max-width der Kind-Elemente sind aus der width des Eltern-Elements berechnet. Vorschlag: lass CSS rechnen. Gib dem Eltern-Element width:320px und padding:0 40px (also, eigentlich NICHT px, sondern irgendwas sinnvolles in em), und dem Kind-div einfach width:100%. Wenn Du die width des Eltern-Elements lieber auf die echte Breite setzen willst, dann mach width:400px und box-sizing:border-box;
    • die Texte deiner h2 Elemente kleben am oberen Rand. Das liegt daran, dass der margin von h2 aus der Box hinausragt - ein div erzeugt keinen Block Formatting Context (BFC). Das kannst Du in den Entwicklerwerkzeugen des Browsers schön sehen. Du könntest das äußere Element auf display:flex; flex-direction:column setzen. Die inneren divs sind dann Flex-Items, die bilden einen BFC und der Margin der h2 bleibt innerhalb des Flex-Items. Statt dessen kannst Du auch das overflow:hidden nutzen, das Du im Pen c) stehen hast, der baut auch einen BFC. Das hängt aber von deinem Usercase ab, was hier richtig ist.

    Bei c) und d) sehe ich nur den Unterschied, dass in d) die Margins des Content 1 fehlen, aber die hast Du ja auch nicht gesetzt.

    Also - eigentlich ist deine Aufgabe doch von Dir gelöst - da ist kein unnötiges Markup mehr. Vielleicht die falschen Elemente, aber wie gesagt: das kann man erst bei Kenntnis des Usecase richtig stellen.

    Rolf

    --
    sumpsi - posui - clusi
  2. @@heinetz

    Was meint Ihr?

    Na, da hast du uns ja ein schönes Rätsel zum Wochenanfang gestellt. Wobei das Rätsel nicht darin besteht umzusetzen, was du willst; sondern darin herauszufinden, was du willst.

    Ich rate mal: Bei schmalem Viewport sollen manche Elemente (Bilder bspw.) über die volle Breite vom linken bis zum rechten Viewportrand gehen. Andere Elemente (Text) sollen links und rechts Abstand zum Viewportrand haben. Bei breitem Viewport sollen aber alle (Bilder und Texte) dieselbe Maximalbreite haben und horizontal zentriert sein.

    Dafür brauchst du keine dreifach verschachtelten Elemente. Nur den Container und dessen Kinder. In meinem Beispiel sind das:

    <figure>
    	<img/>
    	<figcaption></figcaption>
    	<footer></footer>
    </figure>
    

    Mit Grid ist das einfach gemacht: 3 Spalten, die linke und rechte gleich breit, mindestens 1rem (bspw.). Die mittlere Spalte höchtens 40rem (bspw.). Die Spaltenlinien erhalten sprechende Namen:

    figure
    {
    	display: grid;
    	grid-template-columns:
    		[full-start] minmax(1rem, 1fr)
    		[text-start] minmax(auto, 40rem)
    		[text-end] minmax(1rem, 1fr)
    		[full-end];
    }
    

    Bild über volle Breite:

    figure > img
    {
    	grid-column: full;
    }
    

    Text im Bereich zwischen den Linien text-start und text-end:

    figcaption,
    figure > footer
    {
    	grid-column: text;
    }
    

    Ab einem Breakpoint wird das Bild auch durch die Linien text-start und text-end begrenzt:

    @media (min-width: 42em)
    {
    	figure > img
    	{
    		grid-column: text;
    	}
    }
    

    Fertig.

    Anstatt die Breiten der Elemente von außen durch ein Grid festzulegen, kann man auch für die Elemente Breiten und Außenabstände angeben.

    LLAP 🖖

    --
    „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
  3. hallo

    Ist die Darstellung von a und b mit dem Markup aus c und d möglich? Mit Pseudoelementen vielleicht? Oder kommt man zumindest mit weniger Markup aus?

    Klar

    Dazu musst du einfach die sich verschieden zu verhaltenden Elemente mit verschiedenen Klassen bezeichnen, oder mit anderen Selektoren wie :nth-child() arbeiten.