TSO: Footer Hintergrundbild über ganze Breite

Guten Morgen,

ich habe ein kleineres Problem mit dem Redesign einer Webseite. Und zwar war es mein Ziel möglichst viele unnötige Container-Divs zu entfernen. Eines der Divs hatte die Aufgabe den Seiteninhalt auf eine maximale Breite zu begrenzen und horizontal zu zentrieren und meine Intention war es, diese Aufgabe dem Body-Tag zukommen zu lassen.
Grob soll die Seitenstruktur dann also so aussehen:~~~html <body>
<header>…</header>
Unterschiedlicher Content …
<footer>…</footer>
</body>

  
Mein Problem ist jedoch, dass sich die Hintergrundbilder von header und footer auf die gesammte Viewport-Breite erstrecken sollen. Da der body jedoch in seiner Gesamtbreite begrenzt ist, und header und footer Kindelemente sind, muss da eine Lösung her.  
Für den Header habe ich eine akzeptable Lösung gefunden:  
~~~css
  
body > header   {  
  width:950px;  
  height:140px;  
  position:absolute;  
  top:0; left:0; right:0;  
  margin:0 auto;  
  background-image: url(<URL>);  
  padding: 0 calc((100% - 950px)/2);  
}  
body { margin-top: 140px;}  

Ich setze den Header also absolut ans obere Ende zentriere ihn und verpasse ihm ein berechnetes Padding um das Hintergrundbild auf beiden Seiten bis zum Rand anzuzeigen. (Die 100% im calc() entsprechen in der absoluten Position ja der Viewport-Breite)

Problematischer gestaltet sich für mich aber der Footer. Eine absolute Positionierung kommt hier nicht in Frage. Der Footer kann eine variable Höhe haben. Bei relativer Positionierung fehlen mir allerdings die richtigen Werte um zum Rand des Viewports zu gelangen.

Die Variante, mit der ich mich im Moment behelfe ist folgende:

body > footer   {  
  clear:both;  
  width:950px;  
  background:url(<URL>);  
  margin-left: -999px;  padding-left: 999px;  
  padding-right: calc(50vw - 50% - 8px);  
}

Ich verschiebe den Footer also mit margin-left weit außerhalb des Sichtbereiches um ihn dann mit padding-left wieder zurück zu holen. Damit ist das Hintergrundbild auf der linken Seite schonmal bis zum Rand zu sehen.
Für die rechte Seite berechne ich das Padding über die Breite des viewports und des Elements (100vw-100%)/2 und ziehe dann noch 8px ab. Diese 8px sind die gewöhnliche Breite der vertikalen Bildlaufleisten. Mache ich das nicht, wird die gesamte Seite breiter und erhält auch noch horizontale Bildlaufleisten.

Die jetzige Lösung missfällt mir aber grundsätzlich. Unter anderem aus den folgenden zwei Gründen:
1. Kann ich mir nicht sicher sein, dass 8px wirklich ausreichen.
2. Opera hat Probleme mit der Einheit vw im calc-Statement.

Kennt jemand evtl. eine bessere Lösung für mich?
Ich würde nur ungerne wieder das Container-Div einfügen, welches alles außer footer und header enthält, um auf die Breitenbeschränkung des body zu verzichten.

  1. @@TSO:

    nuqneH

    Mein Problem ist jedoch, dass sich die Hintergrundbilder von header und footer auf die gesammte Viewport-Breite erstrecken sollen. Da der body jedoch in seiner Gesamtbreite begrenzt ist, und header und footer Kindelemente sind, muss da eine Lösung her.

    Gehören die Inhalte der header- und footer-Elemente denn zum Hauptinhalt der Seite? Wenn nein, dann begrenze nicht das body-Element, sondern das main-Element in der Breite.

    <body>  
      <header></header>  
      <main role="main">  
        Unterschiedlicher Content …  
      </main>  
      <footer></footer>  
    </body>
    

    Qapla'

    --
    „Talente finden Lösungen, Genies entdecken Probleme.“ (Hans Krailsheimer)
    1. Gehören die Inhalte der header- und footer-Elemente denn zum Hauptinhalt der Seite? Wenn nein, dann begrenze nicht das body-Element, sondern das main-Element in der Breite.

      Ich meine gelesen zu haben, dass die Unterstützung für das main-Element bei weitem nicht so verbreitet sei, wie für die anderen HTML5-Elemente.

      Wenn ich allerdings nach der Semantik gehe, dann müsste ich das main-Element noch einige div-Ebenen tiefer ansetzen.

      Ich schätze da bleibt mir dann wohl doch nichts anderes übrig, als noch einen div-Container zu verwenden.

      1. Hallo,

        Ich meine gelesen zu haben, dass die Unterstützung für das main-Element bei weitem nicht so verbreitet sei, wie für die anderen HTML5-Elemente.

        Das ist richtig, denn es ist relativ neu. Fragt sich nur, was Unterstützung heißt:

        1. Sie parsen das Element korrekt
        2. Sie formatieren das Element korrekt
        3. Sie verstehen die Bedeutung

        Alle drei Phasen lassen sich nachrüsten:

        1. Alle Browser mit HTML5-Parser parsen das Element korrekt, alte IEs bekommen den HTML5-Shim
        2. Für ältere Browser einfach display: block setzen, genau wie für andere HTML5-Sectioning-Elementen
        3. Für ältere Browser role="main" setzen, damit assistive Techniken die Bedeutung verstehen

        Wenn ich allerdings nach der Semantik gehe, dann müsste ich das main-Element noch einige div-Ebenen tiefer ansetzen.

        Das klingt gut.

        Ich schätze da bleibt mir dann wohl doch nichts anderes übrig, als noch einen div-Container zu verwenden.

        Sofern es kein passenderes Element gibt, ja.

        Mathias

  2. Hallo,

    Ich behaupte, du müsstest hier ein bisschen pragmatischer denken.

    <body>  
    <header></head>  
    <main></main>  
    <footer></footer>  
    </body>
    

    main { max-width: 950px }

    Problem gelöst. Funktioniert in jedem Browser. Kein Gerechne mit calc(), kein Verwenden von Einheiten, die die meisten Browser nicht oder falsch umsetzen.

    Falls <main> hier nicht als Wrapper dienen kann (es hat schließlich eine bestimmte Semantik und es könnte noch weitere Sections daneben geben, etwa ein aside):

    Und zwar war es mein Ziel möglichst viele unnötige Container-Divs zu entfernen.

    UNNÖTIGE, ja. Wenn du mit dem div ein robusteres Layout umsetzen kann als ohne, dann setze es in Gottes Namen. Das div schadet nicht. Es sind sind nur ein paar Bytes. Dafür sind divs gedacht. Sie gruppieren Elemente ohne eine spezielle Bedeutung.

    Dein Ansatz geht von hinten durch die Brust ins Auge (erst zentrieren, dann rückgängig machen…) und ist dementsprechend technisch fragil. Ich will nicht ausschließen, dass sich da etwas tricksen lässt. Ich würde das aber gar nicht weiter verfolgen. Am ehesten würde mir Flexbox mit vertikalem Stacking und horizontaler Zentrierung einfallen, aber damit handelst du dir genauso Kompatibilitätsprobleme ein.

    Mathias

    1. @@molily:

      nuqneH

      main { max-width: 950px }

      Problem gelöst. Funktioniert in jedem Browser.

      Bist du sicher?

      Vielleicht sollte man doch noch ein display: block spendieren.

      Und role="main" im Markup.

      Qapla'

      --
      „Talente finden Lösungen, Genies entdecken Probleme.“ (Hans Krailsheimer)
      1. Hallo!

        Funktioniert in jedem Browser.

        Vielleicht sollte man doch noch ein display: block spendieren.

        Ja. Der Vollständigkeit halber: Ein HTML5-Shim ist auch nötig, wenn man Prä-HTML5-Browser unterstützen will (IE 8 etwa). Also so etwas:

        <!--[if lt IE 9]>  
        <script> [code lang=javascript]'abbr article aside audio canvas details figcaption figure footer header main mark meter nav output progress section summary time video'.replace(/\w+/g,function(n){document.createElement(n)})
        ~~~ </script>  
        <![endif]-->[/code]  
          
        display: block sollten dann alle Sectioning-Elemente bekommen.  
          
        
        > Und `role="main"` im Markup.  
          
        +1  
          
        Mathias
        
        -- 
        [Chaplin.js - JavaScript application architecture on top of Backbone.js](http://chaplinjs.org/)