Ankündigung

Einklappen
Keine Ankündigung bisher.

per Flexbox Modell maximale Höhe von Tabs regeln

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • per Flexbox Modell maximale Höhe von Tabs regeln

    Hallo,

    ausgehend von folgendem Code der von W3Schools Tryit Editor stammt versuche ich, dass der Tabinhalt die volle restliche Höhe einnimmt :

    <!DOCTYPE html>
    <html>
    <head>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <style>
    body {font-family: Arial;}

    /* Style the tab */
    .tab {
    overflow: hidden;
    border: 1px solid #ccc;
    background-color: #f1f1f1;
    }

    /* Style the buttons inside the tab */
    .tab button {
    background-color: inherit;
    float: left;
    border: none;
    outline: none;
    cursor: pointer;
    padding: 14px 16px;
    transition: 0.3s;
    font-size: 17px;
    }

    /* Change background color of buttons on hover */
    .tab button:hover {
    background-color: #ddd;
    }

    /* Create an active/current tablink class */
    .tab button.active {
    background-color: #ccc;
    }

    /* Style the tab content */
    .tabcontent {
    display: none;
    padding: 6px 12px;
    border: 1px solid #ccc;
    border-top: none;
    flex: 1;
    height: 100%;
    width: 100%;

    }
    </style>
    </head>
    <body>

    <h2>Tabs</h2>
    <p>Click on the buttons inside the tabbed menu:</p>

    <div class="wrapper">

    <div class="tab">
    <button class="tablinks" onclick="openCity(event, 'London')">London</button>
    <button class="tablinks" onclick="openCity(event, 'Paris')">Paris</button>
    <button class="tablinks" onclick="openCity(event, 'Tokyo')">Tokyo</button>
    </div>

    <div id="London" class="tabcontent">
    <h3>London</h3>
    <p>London is the capital city of England.</p>
    </div>

    <div id="Paris" class="tabcontent">
    <h3>Paris</h3>
    <p>Paris is the capital of France.</p>
    </div>

    <div id="Tokyo" class="tabcontent">
    <h3>Tokyo</h3>
    <p>Tokyo is the capital of Japan.</p>
    </div>

    </div>

    <script>
    function openCity(evt, cityName) {
    var i, tabcontent, tablinks;
    tabcontent = document.getElementsByClassName("tabcontent");
    for (i = 0; i < tabcontent.length; i++) {
    tabcontent[i].style.display = "none";
    }
    tablinks = document.getElementsByClassName("tablinks");
    for (i = 0; i < tablinks.length; i++) {
    tablinks[i].className = tablinks[i].className.replace(" active", "");
    }
    document.getElementById(cityName).style.display = "block";
    evt.currentTarget.className += " active";
    }
    </script>

    </body>
    </html>
    Um dies zu realisieren, habe ich folgende Änderungen vorgenommen, die ich jeweils in rot markiert habe :

    Um den html Code der Tabs habe ich eine Wrapper-Klasse gepackt, der als Container für meine Flex Elemente (also Tab Inhalt) diesen soll, mit folgenden CSS :

    Code:
    .wrapper {
      display: flex;
      flex-direction: column;
      height: 100%;
    }
    Die Klasse .tabcontent hab ich dann auf flex 1 gesetzt in der Hoffnung, dass der Inhalt dann die restliche verfügbahe Höhe des Browserfensters einnimmt was er nicht tut,
    habe dann noch zusätzlich die height property auf 100% gesetzt was nichts ändert.

    Habe die Wrapper Klasse auch schon direkt nach dem DIV mit der Klasse "tab" gesetzt, funzt auch nicht.

    Jemand ne Idee ?

  • #2
    Zitat von Midget Beitrag anzeigen
    ausgehend von folgendem Code der von W3Schools stammt versuche ich, dass der Tabinhalt die volle restliche Höhe einnimmt :
    Wie oft ist der Code von W3Schools Müll: neben falschen Einheiten (keine Pixel verwenden!), unvollständigen Angaben (nicht jeder hat Arial als Schriftart) und Attributen die im HTML nichts zu suchen haben (onclick gehört ins JS ausgelagert) ist der JS-Code recht antiquiert: var möchte const/let sein, statt getElementsByClassName würde ich querySelectorAll verwenden, statt for forEach, für das arbeiten mit Klassen gibt es className.add() usw. und css-Eigenschaften sollten nicht per Script gesetzt sondern über Klassen zugewiesen werden.

    Die Klasse .tabcontent hab ich dann auf flex 1 gesetzt in der Hoffnung, dass der Inhalt dann die restliche verfügbahe Höhe des Browserfensters einnimmt was er nicht tut,
    habe dann noch zusätzlich die height property auf 100% gesetzt was nichts ändert.
    100% wovon? Warum der Wrapper nicht höher wird, weiß ich jetzt auch nicht, ich würde da aber auch kein flex- sondern ein grid-Layout für verwenden. Und: Finger weg von outline:none, du machst die Seite damit unbedienbar da bei Tastaturbedienung nicht mehr erkennbar ist welcher Button aktiv ist.

    Kommentar


    • #3
      neben falschen Einheiten (keine Pixel verwenden!)
      ich benutze em

      onclick gehört ins JS ausgelagert
      besser mit addEventListener und dann auslagern

      statt getElementsByClassName würde ich querySelectorAll verwenden
      den Grund versteh ich nicht, beide geben doch eine Collection mit allen gefundenen Elementen zurück

      statt for forEach, für das arbeiten mit Klassen gibt es className.add()
      du meinst addClass und RemoveClass, aber ich muss doch trotzdem die Collection mit allen Elementen per Schleife durchlaufen (forEach, For mit Zähler wie auch immer) ?

      Warum der Wrapper nicht höher wird
      na dann sind wir schon zu zweit

      ich würde da aber auch kein flex- sondern ein grid-Layout für verwenden
      schade, hab mich grade in Flexbox eingelesen, dachte das sei das richtige Modell dafür um Elemente auf ein Maximum vergrößern zu lassen, Grid kenn ich nicht

      Kommentar


      • #4
        Zitat von Midget Beitrag anzeigen
        den Grund versteh ich nicht, beide geben doch eine Collection mit allen gefundenen Elementen zurück
        PHP-Code:
        tabcontent document.getElementsByClassName("tabcontent");
        for (
        0tabcontent.lengthi++) {
            
        tabcontent[i].style.display "none";

        ... wird zu ...

        PHP-Code:
        document.querySelectorAll('.tabcontent').forEach(el => el.style.display 'none'); 

        Zitat von Midget Beitrag anzeigen
        du meinst addClass und RemoveClass, aber ich muss doch trotzdem die Collection mit allen Elementen per Schleife durchlaufen (forEach, For mit Zähler wie auch immer)?
        classList war wohl gemeint:

        PHP-Code:
        document.querySelectorAll('.tablinks').forEach(el => el.classList.remove('active')) 

        Kommentar


        • #5
          Es ist keine so gute Idee, Elementen ein
          Code:
          style.display="none"
          zu verpassen, ohne den vorherigen Status dieser Eigenschaft zu sichern.

          Ich weiß nicht, ob es noch zeitgemäß ist, Klassen und ID´s zur Identifikation einzelner Elemente zu benutzen, das muss jeder für sich entscheiden.

          Ich benutze Klassen i.d. Regel zur Dekoration der Elemente.

          Wenn ich das Aussehen verändern will und einzelnen Elementen eine andere Klasse gebe, müsste ich Javascript auch ändern. Daher arbeite ich lieber mit Datasets.

          Ich weiß nicht so recht, was mit der vollen Höhe gemeint ist, vermute aber, dass Du die maximal verbleibende Höhe meinst.

          Code:
          flex: 1 1 auto;
          Ich habe den Code mal so abgeändert, wie ich es als zeitgemäß erachte.

          https://jsfiddle.net/gjb8z2dp/

          HTML-Code:
          <!DOCTYPE html>
          <html lang="de">
          <head>
            <meta name="viewport" content="width=device-width, initial-scale=1">
            <meta charset="UTF-8">
            <title>Document</title>
            <style>
            *{
            font-family:  -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
            box-sizing: border-box;
            font-size: 18px;
            }
            html{
              min-height:100vh;
            }
            body{
              height: 100vh;
              display: flex;
              flex-direction: column;
              align-content: stretch;
              margin: 0 auto;
              width:90%;
              max-width: 768px;
            }
            .tabs, .tabs button{
              background:#eee;
          
            }
              .tabs{
                font-size:0;
              }
            .tabs button[data-active]{
              background: #ccc;    
            }
            .tabs button{
              border:none;
              padding: .5em 1em;
              margin:0;
              cursor: pointer;
              transition: 0.3s;
              margin:0;
            }
            .tabs button:hover{
              background:#ddd;
            }
            .tabcontent{
                flex: 1 1 auto;
                padding: 0 .5em;
                border: 1px solid #ddd;
            }
            footer{
              padding: 1em;
            }
            </style>
          </head>
          <body>
            <h2>Tabs</h2>
            <p>Click on the buttons inside the tabbed menu:</p>
            <div class="tabs">
              <button data-tab=London data-active>London</button>
              <button data-tab=Paris>Paris</button>
              <button data-tab=Tokyo>Tokyo</button>
            </div>
            <div data-tabs class="tabcontent">
              <div data-tab=London>
                <h3>London</h3>
                <p>London is the capital city of England.</p>
              </div>
              <div data-tab=Paris hidden>
                <h3>Paris</h3>
                <p>Paris is the capital of France.</p>
              </div>
              <div data-tab=Tokyo hidden>
                <h3>Tokyo</h3>
                <p>Tokyo is the capital of Japan.</p>
              </div>
            </div>
            <footer>Fußzeile</footer>
            <script>
              const $ = sel => document.querySelector(sel)
              $('body').addEventListener( 'click', el => {
                if (el.target.dataset.tab){
                  delete $('button[data-active]').dataset.active
                  el.target.dataset.active=true;
                  $('[data-tabs]>div:not([hidden])').hidden=true;
                  $(`[data-tabs]>div[data-tab=${el.target.dataset.tab}]`).hidden=false
                }
              })
            </script>
          </body>
          </html>

          Kommentar


          • #6
            Zitat von Midget Beitrag anzeigen
            den Grund versteh ich nicht, beide geben doch eine Collection mit allen gefundenen Elementen zurück
            Nein,
            querySelectorAll() -> static NodeList object
            getElementsByClassName() -> live HTML collection
            HTML-Code:
            <!DOCTYPE html>
            <html lang="en">
            <head>
              <meta charset="UTF-8">
              <title>Document</title>
            </head>
            <body>
              <div>
                <p class="test">eins</p>
                <p class="test">zwei</p>
              </div>
               <script>
                  let sel = document.querySelectorAll('.test')
                  let css = document.getElementsByClassName('test')
            
                  let newNode = document.createElement('p')
                  newNode.innerHTML='drei'
                  newNode.classList.add('test')
                  document.querySelector('div').append(newNode)
            
                  for (let i = 0; i < sel.length; i++) {
                     sel[i].classList.add('sel')
                  }
                  for (let i = 0; i < css.length; i++) {
                     css[i].classList.add('css')
                  }
            </script>
            </body>
            </html>
            
            
            RESULT:
            HTML-Code:
            <div>
                <p class="test sel css">eins</p>
                <p class="test sel css">zwei</p>
                <p class="test css">drei</p>
            </div>
            PS: Ich weiß, dass es forEach gibt...

            Kommentar


            • #7
              Ich weiß nicht so recht, was mit der vollen Höhe gemeint ist, vermute aber, dass Du die maximal verbleibende Höhe meinst.
              Ja genau das meinte ich und das genau macht dein Code, vielen Dank ! Habe bloss noch der Klasse .tabcontent ein overflow: auto verpasst und ich habe mein gewünschtes Resultat.
              html{ min-height:100vh; } und body{ height: 100vh; } waren hier ausschlaggebend.

              Code:
               
               const $ = sel => document.querySelector(sel)
              Interessant, diese Definition kannte ich noch gar nicht, somit kann ich quasi wie mit Jquery Elemente selektieren wie ich seh.

              Besten Dank auch für den Exkurs mit dem Unterschied zwischen QuerySelector und ClassSelector

              Kommentar

              Lädt...
              X