MartinL: Div Box an unterschiedlichen Stellen anzeigen je nach Displaygröße

Hallo,

ich arbeite mich gerade etwas tiefer in HTML5 und CSS ein und habe eine Frage, die ich bisher nicht lösen konnte. Ist es möglich, eine Box je nach Displaygröße an einer ganz anderen Stelle der Webseite anzuzeigen?

Beispiel:

Ich habe für große Displays ein zweispaltiges Design. Rechts ist der Hauptinhalt, links daneben mittels float:left die Navigation und unter der Navigation ein Feld mit Kontaktdaten. Die .html Datei ist folgendermaßen aufgebaut:

<nav> 
</nav>
<div id="kontakt">
</div>
<main role="main"> 
</main

So soll es für große Displays aussehen:

---------------
- NAVI - MAIN -
- NAVI - MAIN -
- ---- - MAIN -
- MAIL - MAIN -
- MAIL - MAIN -
-------- MAIN -
-------- MAIN -
- F o o t e r -
---------------

So soll es für kleine Displays aussehen:

------------
--- NAVI ---
--- NAVI ---
------------
--- MAIN ---
--- MAIN ---
--- MAIN ---
--- MAIN ---
--- MAIN ---
--- MAIN ---
--- MAIN ---
------------
--- MAIL ---
--- MAIL ---
------------
-- Footer --
------------

Das mit dem Navigationsmenü ist kein Problem. Ich nehme einfach float:left für kleine Displaygrößen raus und das Menü wandert nach oben. Mein Problem ist das Kontaktfeld. Wie bekomme ich das unter den Text?

Gruß Martin

  1. Hallo

    Eine aktuelle Lösung mit dem CSS3 Grid Layout oder Flexbox, die in hinreichend vielen Browsern funktioniert, gibt es für dein Problem leider nicht.

    Deshalb bleibt nur die drittbeste Lösung mit float.

    Mein Problem ist das Kontaktfeld. Wie bekomme ich das unter den Text?

    Das Kontaktfeld (bei mir in einem aside-Element) muss sich im Quelltext unter dem main-Element befinden:

       <nav role="navigation">
          <h2>nav</h2>
       </nav>
       <main role="main">
          <h2>main</h2>
          <p>Und noch etwas Text</p>
          <p>Das main-Element muss höher sein als das nav-Element, damit diese Lösung funktioniert.</p>
       </main>
       <aside>
          <h2>aside</h2>
       </aside>
       <footer role="contentinfo">
          <h2>footer</h2>
       </footer>
    

    Das CSS dazu könnte dann so aussehen:

       @media all {
          nav {
             float: left;
             width: 30%;
          }
          main {
             float: right;
             width: 70%;
          }
          aside {
             float: right;
             width: 30%;
          }
          footer {
             float: left;
             width: 100%;
          }
       }
       @media only screen and (max-width: 800px) {
          nav {
             width: 100%;
          }
          main {
             width: 100%;
          }
          aside {
             width: 100%;
          }
          footer {
             width: 100%;
          }
       }
    

    Der gesamte Quelltext mit ein paar zusätzlichen CSS-Anweisungen dann so:

    <!DOCTYPE html>
    <html lang="de">
    <head>
       <meta charset="utf-8">
       <title>Float Layout 01</title>
       <meta name="description" content="HTML5, CSS3">
       <meta name="viewport" content="width=device-width, initial-scale=1.0">
       <style>
    
       @media all {
          header, nav, main, aside, footer, section, article, figure, figcaption, audio, video {
             display: block;
          }
          * {
             box-sizing: border-box;
          }
          html {
             font-family: sans-serif;
             font-size: 120%;
             line-height: 1.3;
          }
          body {
             margin: 0;
          }
          body>* {
             padding: 0.5rem;
             border: 3px solid gray;
             margin: 0;
          }
          nav {
             float: left;
             width: 30%;
          }
          main {
             float: right;
             width: 70%;
          }
          aside {
             float: right;
             width: 30%;
          }
          footer {
             float: left;
             width: 100%;
          }
       }
       @media only screen and (max-width: 800px) {
          nav {
             width: 100%;
          }
          main {
             width: 100%;
          }
          aside {
             width: 100%;
          }
          footer {
             width: 100%;
          }
       }
    
       </style>
    </head>
    <body>
       <nav role="navigation">
          <h2>nav</h2>
       </nav>
       <main role="main">
          <h2>main</h2>
          <p>Und noch etwas Text</p>
          <p>Das main-Element muss höher sein als das nav-Element, damit diese Lösung funktioniert.</p>
       </main>
       <aside>
          <h2>aside</h2>
       </aside>
       <footer role="contentinfo">
          <h2>footer</h2>
       </footer>
    </body>
    </html>
    

    Gruss

    MrMurphy

    1. @@MrMurphy1

      Eine aktuelle Lösung mit dem CSS3 Grid Layout oder Flexbox, die in hinreichend vielen Browsern funktioniert, gibt es für dein Problem leider nicht.

      Ach was‽ Wirklich nicht?

      "kenne ich nicht" ≠ "gibt es nicht".

      Problematisch an der Umsortierung könnte sein, dass die Elemente im Hauptinhalt in der Tab-Reihenfolge vor denen im Kontaktfeld kommen, obwohl ein Nutzer (mit breitem Viewport) das aufgrund der visuellen Darstellung vielleicht anders erwarten würde.

      Das Kontaktfeld (bei mir in einem aside-Element)

      address wäre angebracht.

      <nav role="navigation">

      <main role="main">

      <footer role="contentinfo">

      All diese role-Attribute sind nicht angebracht. Diese Elemente haben schon diese Rollen; dann sollten sie nicht noch mal angegeben werden.

      @media all

      Wozu soll das gut sein?

      @media only screen and (max-width: 800px)

      Wozu soll only screen gut sein?

      Media queries sollten in em angegeben werden, nicht in px.

      audio, video { display: block; }

      Inline-Elemente global als Block zu formatieren ist auch nicht unbedingt die beste Idee.

      LLAP 🖖

      --
      “You might believe there are benefits for the developer, but first of all, you should put those behind the interest of the user.” —Stefan Tilkov
      Selfcode: sh:) fo:} ch:? rl:) br:> n4:& va:| de:> zu:} fl:{ ss:| ls:# js:|
    2. @@MrMurphy1

        aside {
           float: right;
           width: 30%;
        }
      

      Wieso right, wenn das Kontaktfeld doch links sein soll?

        <p>Das main-Element muss höher sein als das nav-Element, damit diese Lösung funktioniert.</p>
      

      Nein. Das funktioniert auch, wenn ein clearendes Wort gesprochen wird. Da kuckst du.

      LLAP 🖖

      --
      “You might believe there are benefits for the developer, but first of all, you should put those behind the interest of the user.” —Stefan Tilkov
      Selfcode: sh:) fo:} ch:? rl:) br:> n4:& va:| de:> zu:} fl:{ ss:| ls:# js:|
    3. Danke sehr, das scheint schon mal eine Lösung zu sein. Mir kam über Nacht noch eine andere Lösung in den Sinn. Ich weiß jetzt nicht, welche Lösung eventuell mehr Vor- oder Nachteile mit sich bringt.

      Meine Idee war, einfach zwei Elemente zu erstellen und diese je nach Kontext mit display:none auszublenden bzw. mit display:block anzuzeigen. Dadurch würde sich die Tab-Reihenfolge erhalten denke ich. Der Quelltext wird dabei zwar etwas länger aber mit passenden Kommentaren kann man das ja ordentlich halten. Gibt es dabei Nachteile, die ich beachten müsste?

      Gruß Martin

  2. @@MartinL

    je nach Displaygröße

    Du meinst: je nach Viewportgröße. Das Browserfenster muss ja nicht den gesamten Bildschirm ausfüllen; auch Sidebars im Browser können den Viewport einschränken.

    <nav> 
    </nav>
    <div id="kontakt">
    </div>
    <main role="main"> 
    </main
    

    Dass fürs Kontaktfeld address angebracht und role="main" überflüssig ist, sagte ich schon.

    Ich nehme einfach float:left für kleine Displaygrößen raus

    Bessr als etwas rauszunehmen ist immer, es gar nicht erst reinzutun.

    Also nicht per @media (max-width:) float zurücksetzen, sondern erst per @media (min-width:) setzen.

    LLAP 🖖

    --
    “You might believe there are benefits for the developer, but first of all, you should put those behind the interest of the user.” —Stefan Tilkov
    Selfcode: sh:) fo:} ch:? rl:) br:> n4:& va:| de:> zu:} fl:{ ss:| ls:# js:|
    1. Ja, da habe ich mich missverständlich ausgedrückt. Ich mache es aktuell per @media (min-width:..) und meinte natürlich die Viewportgröße und nicht die Displaygröße. Adress werde ich mir noch einmal als Alternative anschauen, das war mir bisher unbekannt. Deine Antwort ist also nicht untergegangen, keine Sorge. Allerdings steht im Einsteigertutorial, dass man bei <main> die Rolle schon noch mit angeben sollte, bis das alle Browser verstehen.

      Trotzdem bleibt die Frage, ob es überhaupt gut ist, die Elemente je nach Viewportgröße an unterschiedlichen Stellen zu platzieren, oder ob es nicht besser ist, unterschiedliche Elemente anzulegen und diese je nach Viewportgröße anzuzeigen bzw. auszublenden.

      Gruß Martin

      1. Hallo

        Trotzdem bleibt die Frage, ...

        Das ist grundsätzlich nicht zu empfehlen.

        Zum einen wird die Pflege der Seite aufwändiger, da Änderungen immer an mehreren Stellen vorgenommen werden müssen.

        Viele User verzichten zudem auf das CSS - die würden den Inhalt dann doppelt bekommen. Zudem kann es Probleme mit der Zugänglichkeit / Barrierefreiheit geben.

        Eine bewährte Grundregel ist, dass der HTML-Quelltext auch ohne CSS sinnvoll angezeigt werden soll. Dadurch treten viele Nachfolgeprobleme gar nicht erst auf.

        Gruss

        MrMurphy