Gustav: Responsive Layout mit Flexbox

Hallo

ich möchte gern eine selfhtml-Design-Vorlage an meine Bedürfnisse anpassen und komme in der Navigationszeile an meine Grenzen. Sie sieht so aus:

Navigation IST

Sollte aber so aussehen: Navigation SOLL

HTML

<nav>
  <ul>
    <li><a aria-current="page">Home</a></li>
    <li><a href="./Kat1.html">Kat 1</a></li>
    <li><a href="./Kat2.html">Kat 2</a></li>
    <li><a href="./Kat3.html">Kat 3</a></li>
    <li><a href="./de/">de</a></li>
  </ul>
</nav>

CSS

nav ul {
  text-align: center;
  margin: 0;
  padding: 0;
  list-style: none;
}

nav a {
  background-color: transparent;
  color: black;
  text-decoration: none;
  display: inline-block;
  width: 95%;
  margin: .5em 0;
  padding: .5em 1em;
  border: 1px solid gray;
  border-radius: .5em;
}

Es dürften wohl zwei Punkte anzupassen sein:

  1. Statt des 'Home'-Textes soll eine home.svg Grafik eingebunden werden.
  2. Die Menu-Punkte 'Home' und 'de' sollen bei horizontaler Navigationsleisten-Darstellung in der Breite kleiner ausfallen als die Übrigen.

Ich habe bei beiden Punkten schon viel ausprobiert. Hat jemand einen Rat, wie ich weiter komme?

Schöne Grüße, Gustav

  1. Hallo Gustav,

    hast Du die SVG Grafik? Dann setze an Stelle des Wortes Home ein <img> Element, natürlich mit alt="Home".

    Für die Breite solltest Du Dich mit den Attributen flex-grow, flex-shrink und flex-basis beschäftigen. Die geben die "Normalgröße" eines Elements an (-basis), sowie den Anteil, den das Element bei Vergrößerungen oder Verkleinerungen übernimmt.

    In deinem Fall sollten Home und de ein flex-grow von 0 haben und die normalen Menüpunkte ein flex-grow von 1. Als flex-basis kannst Du auto nehmen.

    flex-grow, flex-shrink und flex-basis kann man zum Attribut flex zusammenfassen (dahinter dann die Werte für grow, shrink und basis). Könnte man z.B. so machen:

    nav a {
       flex: 1 0 auto;
    }
    nav a:first-of-type(), nav a:last-of-type() {
       flex-grow: 0;
    }
    

    Dein nav ul Element braucht natürlich noch display: flex. Das display:inline-block für die li Elemente ist dann unnötig.

    Für schmale Viewports musst Du Dir eine passende Media-Abfrage überlegen, die die Menüpunkte dann wieder untereinander setzt.

    Rolf

    --
    sumpsi - posui - obstruxi
    1. Hallo Rolf,

      vielen Dank für Deine detaillierten Anregungen.

      Ich habe zunächst alles so umgesetzt, doch leider nicht den gewünschten Effekt erzielen können.

      nav ul {
        text-align: center;
        display: flex;
        margin: 0;
        padding: 0;
        list-style: none;
      }
      
      nav a {
        background-color: transparent;
        color: black;
        text-decoration: none;
        flex: 1 0 auto;
        width: 95%;
        margin: .5em 0;
        padding: .5em 1em;
        border: 1px solid gray;
        border-radius: .5em;
      }
      
      nav a:first-of-type(), nav a:last-of-type() {
         flex-grow: 0;
      }
      

      Die mittleren Menu-Punkte füllen den verbliebenen Platz nicht auf und wie du schon anmerktest, zerschießt es bei schmaleren Viewports die dann über die gesamte Bildschirmbreite angelegte Darstellung der Naviagtionspunkte untereinander.

      Zwischenzeitig habe ich auch noch diverse modifizierte Eingaben ausprobiert, aber auch damit nicht die beabsichtigte Darstellung hinbekommen. Habe ich vielleicht irgend etwas falsch gemacht?

      Schöne Grüße, Gustav

      1. Hallo Gustav,

        sorry, ich war unaufmerksam.

        Das ul Element ist die Flexbox und die li Elemente sind demnach die Flex-Items. Die Flex-Eigenschaft auf den a Elementen findet keine Beachtung.

        D.h. man muss das so stylen:

        nav ul {
          display: flex;
          ... etc
        }
        
        nav li {
          flex: 1 0 auto;
        }
        nav li:first-of-type(), nav li:last-of-type() {
           flex-grow: 0;
        }
        
        nav a {
           width: 100%;
           ... etc
        }
        

        Du musst gucken, welche Styles Du den <li> und welche den <a> gibst, damit es so aussieht wie Du es haben möchtest.

        Wenn Du Flexbox besser verstehen willst, ist dieses Spielchen hier eine gute Übung 😉.

        Rolf

        --
        sumpsi - posui - obstruxi
        1. Hallo Rolf,

          ich habe einiges ausprobiert, aber bekomme es leider nicht hin. Nach der Eingabe deiner letzten Anregungen, kann ich bei den flex-Parametern oder bei padding eingeben, was ich will, an der Darstellung ändert es nichts und sieht so aus, wie in meiner vorherigen Mail dargestellt.

          Da sich wie zuvor beschrieben damit auch die Ansicht bei kleineren Viewports zerschiesst, bin ich inzwischen soweit, die im ursprünglichen Design angelegte gleichmäßige Breite aller Menueinträge hinzunehmen.

          Mich würde höchstens noch grundsätzlich interessieren, ob ich irgend etwas vergessen oder falsch gemacht habe oder ob es mit display:flex auch nicht besser geht.

          Herzlichen Dank in jedem Fall für deine Anregungen und übrigens auch für den Link zu den Fröschen ;o)

          Schönen Feiertag, Gustav

          1. Hallo Gustav,

            hast Du einen Ort, wo man sich deine Experimente anschauen kann?

            Oder kannst Du das Problem in einem Code-Labor wie Codepen oder jsFiddle demonstrieren? Es ist sicherlich ein einfaches Mistverständnis.

            Ich habe mal was gebastelt. Da ich kein Home-SVG hatte, benutze ich ein Haus-Emoji.

            Rolf

            --
            sumpsi - posui - obstruxi
            1. Hallo Rolf,

              entschuldige erst einmal, dass es etwas gedauert hat, ich war am WE weitestgehend anderweitig eingebunden.

              Dann habe ich versucht, das bei jfiddle aufzusetzen, habe aber nicht den Button gefunden, der das ganze anzeigt :o) https://jsfiddle.net/ukzoc023/1/#&togetherjs=pvV99pnIUx

              Also habe ich es heute nun auf einer Subdomain angelegt: http://1.eyes2k.com

              Schöne Grüße, Gustav

              1. Hallo Gustav,

                Dann habe ich versucht, das bei jfiddle aufzusetzen, habe aber nicht den Button gefunden, der das ganze anzeigt :o)

                Oben links in jsFiddle steht "> Run", und ein Tooltip der den Hotkey Ctrl+Enter verrät.

                Ein Fehler bei Dir stammt aus meinem Posting oben, und den hab ich in meinem Fiddle korrigiert: Es heißt :first-of-type und :last-of-type, ohne die Klammern. Damit funktioniert schon mal die Breitenverteilung.

                Und dann gib deinen a Elementen noch display:inline-block, damit sie sich in der Breite beeinflussen lassen, und box-sizing:border-box, damit dein width:95% auch Rand und Padding beinhaltet. Andernfalls müsstest Du Rand und Padding aus der width herausrechnen.

                Rolf

                --
                sumpsi - posui - obstruxi
                1. Ja, super!

                  Ich glaube, ich werde noch mal in mich gehen, ob das jetzt nicht doch die bessere Lösung ist.

                  Herzlichen Dank Rolf, dass du noch dran geblieben bist.

                  Beste Grüße, Gustav