nocheinPoet: Frage an CSS Profis 2 - Dynamisches Menue ohne JS Positionierung

Moin,

ich nun wieder, bisher konntet Ihr mir ja immer schnell einen guten Tipp geben, ich vermute aber mal, hier ist die Grenze von CSS3 dann einfach erreicht. Ziel ist ein Menue ohne JavaScript, ohne weitere Klassen im Menue, dass dazu noch dynamisch was die Breite und die Höhe der Inhalte ist. Die beiden letzten Punkte sind nun wirklich ein Problem, ich vermute mal, es ist nicht zu lösen, man müsste aus einem Container ausbrechen können, oder deren Höhe und Breite abfragen und dann nach innen für die Positionierung übernehmen.

Hier nun aber erstmal der aktuelle Quellcode, Farben, Margins und Paddings dienen der Visualisierung der einzelnen Container:

<!doctype html>  
  
<html>  
  
    <head>  
  
        <title>CSS3 Menu without JavaScript</title>  
  
        <meta charset="utf-8">  
  
        <style type="text/css">  
  
            body                                        {background: #eeeeee; font-size:12px;font-family: arial, verdana, sans-serif;			}  
  
            .menue                                      {background: #B2CCE6; margin-bottom: 1px; float: left; width: 100%; font-weight:bold;}  
  
            .menue a                                    {background: #B2B2E6; padding:8px; margin: 2px; color: #333333; display:block; text-decoration:none;}  
  
            .menue ul                                   {background: #CCB2E6; padding:2px; margin: 2px; list-style-type:none; float: left;}  
  
            .menue ul li                                {background: #E6B2E6; padding: 2px; margin: 2px; float:left;}  
            .menue ul li ul                             {background: #E6B2CC; padding: 1px; margin: 2px; position: absolute;} /*left:px; top:40px;*/  
  
            .menue ul li ul li                          {clear: both; }  
  
            .menue ul li ul li ul                       {background: #E6B2B2;margin-left: 2px; margin-top: -35px;  left:175px; white-space:nowrap; }  
  
            .menue li    > a:not(:last-child)::after    {background: #E6CCB2; content: '▼';  margin: 0px 0px 0px 10px;}  
            .menue li li > a:not(:last-child)::after    {background: #E6E6B2; content: '►';  margin: 0px 0px 0px 10px;}  
  
        </style>  
  
        </head>  
  
        <body>  
  
            <div class="menue">  
  
                <ul>  
  
                    <li><a href="#">Punkt 1</a></li>  
  
                    <li>  
  
                        <a href="#">Punkt 2</a>  
  
                        <ul>  
  
                            <li><a href="#">Punkt 2.1 [variable width] </a></li>  
                            <li><a href="#">Punkt 2.2</a></li>  
  
                            <li>  
  
                                <a href="#">Punkt 2.3</a>  
  
                                <ul>  
  
                                    <li><a href="#">Punkt 2.3.1</a></li>  
  
                                    <li>  
  
                                        <a href="#">Punkt 2.3.2</a>  
  
                                        <ul>  
                                            <li><a href="#">Punkt 2.3.2.1</a></li>  
                                            <li><a href="#">Punkt 2.3.2.2</a></li>  
                                            <li><a href="#">Punkt 2.3.2.3</a></li>  
                                        </ul>  
  
                                    </li>  
  
                                    <li><a href="#">Punkt 2.3.3</a></li>  
  
                                </ul>  
  
                            </li>  
  
                            <li><a href="#">Punkt 2.4</a></li>  
  
                        </ul>  
  
                    </li>  
  
                    <li><a href="#">Punkt 3</a></li>  
                    <li><a href="#">Punkt 4</a></li>  
                    <li><a href="#">Punkt 5</a></li>  
  
                </ul>  
  
            </div>  
  
            <div style="background: #ddd; clear: both; height: 300px; padding: 5px;">CONTENT</div>  
    </body>  
  
</html>

Probleme macht eben dieses Konstrukt:

.menue ul li ul li ul                       {background: #E6B2B2;margin-left: 2px; margin-top: -35px;  left:175px; white-space:nowrap; }  

Das „margin-top“ könnte man ja noch hinnehmen, aber „left:“ ist echt ätzend. Ich finde keinen Weg, das innere „ul“ automatisch neben dem äußerem „ul“ zu positionieren, man müsste irgendwie aus dem übergeordneten „ul“ ausbrechen.

Ein weiteres aber nur kleines Problem bereitet das hier:

.menue li li > a:not(:last-child)::after    {background: #E6E6B2; content: '►';  margin: 0px 0px 0px 10px;}  

Es wäre ja nun toll, wenn das „►“ nun immer rechts am Rand im Container positioniert wäre, da wo es im Grunde ja hingehört.

Einige werden nun vermutlich sagen - hat man auch schon -, was soll der Mumpitz, nimm jQuery und gut ist das. Klar geht es dann alles ohne Probleme, man kann sich überall hinhangeln, und jedes Attribut greifen und manipulieren. Es wäre doch aber geil, wenn es auch ohne JS geht. Auch übt es mit CSS sinnvoll umzugehen. Und ja ich weiß, es gibt schon ganz tolle Menues, die man als Plugin für jQuery einbinden und konfigurieren kann. Also vorab Danke, kenne ich alle, dazu brauche ich keinen Link. Ich sehe es auch als Denksportaufgabe, und nein ich habe nicht zu viel Zeit und langweile mich den ganzen Tag.

Was mich einwenig ärgert ist, ich schaue mir den http://acid3.acidtests.org/ an, also den Code und denke, geil - ist ja der Hammer. Und was es alles so im Web gibt, viele Seiten zeigen tolle Effekte und betonen, alles nur mit CSS3 und ohne JavaScript, hier nur ein

Beispiel: http://andrew-hoyer.com/andrewhoyer/experiments/walking/

Was bin ich doch begeisterst, aber so ein einfaches Menue, wie es mir vorschwebt, wie es überall ja im Web gebraucht wird, was wirklich einfach nur Standart wäre, das ist so in der Form ohne JavaScript offenbar einfach nicht mit CSS3 umzusetzen. Da werde ich wohl auf CSS6 und HTML8 warten müssen. Na nun genug geschimpft, eventuell bin ich auch nur zu „unwissend“ und einer von Euch zaubert hier eine geniale Lösung aus dem Hut.

Mit Gruß

Manuel

  1. Ich bin ja weiter auf der Suche, habe nun "Flexbox"

    http://webkrauts.de/artikel/2012/css3-flexbox-abloesung-fuer-float-layouts

    gefunden, kennt sich damit wer aus, eventuell kann man das ja nutzen.

  2. So das kleinere Problem habe ich wider erwartend so:

      
    .menue li li                      {background: #E6CCB2; width: 100%;}  
    .menue li li > a:not(:last-child) {background: #E6E6B2; min-width: 100px}  
      
    .menue li > a:not(:last-child)::after {background: #CCE6B2; content: '▼'; margin-right: 10px;}  
      
    .menue li li > a:not(:last-child)::after  
    {  
        background: #B2E6B2; content: '►'; margin-right: 10px; float: right;  
    }  
    
    

    gelöst. Die min-width: 100px sind nur für das Unter-Unter-Menue nötig, warum auch immer.

    1. Om nah hoo pez nyeetz, nocheinPoet!

      Ich habe dein Beispiel etwas reduziert und folgendes CSS für dein im OP gepostetes HTML erstellt.

      Das Menü lässt sich nicht mit der Tastatur bedienen, dazu Bedarf es JavaScript, weil nur a-Elemente den Focus erhalten können. Wenigstens klappt bei Durchsteppen die Liste auf.

      Falls du wirklich erreichen möchtest, dass _alle_ verweissensitiven Flächen gleich breit sind, musst du min-width ebenfalls per JS setzen.

      Falls das nicht nur eine theoretische Spielerei ist, würde ich mich freuen, die originale Seite zu sehen, dann lässt sich dir u.U. zielgerichteter helfen.

      ul, li {margin: 0; padding: 0;}  
      			  
      li {  
      	min-width: 8em;  
      	display: block;  
      	position: relative;  
      	background: #B2B2E6;  
      }  
      					  
      nav > ul > li {  
      	display: inline-block;  
      	vertical-align: top;  
      	margin-right: 1em;  
      }  
      			  
      li > ul {  
      	position: absolute;  
      	left: -1000%;  
      }  
      			  
      li:hover > ul, a:focus ~ ul{  
      	left: 0;  
      }  
      			  
      li > ul > li:hover > ul {  
      	left: 100%;  
      	top: 0;  
      }  
      			  
      a  {  
      	display: inline-block;  
      	width: 100%;  
      	margin: .2em;  
      }  
        
      a:not(:last-child)::after {  
      	content: '►';  
      	position: absolute;  
      	right: 0;  
      }  
      			  
      li:hover > a:not(:last-child)::after {  
      	content: '▼';  
      }  
      			  
      li > ul > li:hover > a:not(:last-child)::after {  
      	content: '►';  
      }
      

      Link zum Beispiel

      Matthias

      --
      1/z ist kein Blatt Papier.

      1. Cool,

        danke für Deine Arbeit, hatte den Beitrag hier übersehen.

        Es soll nicht nur eine Spielerei sein, ich habe sonst immer mit Superfish für jQuery gearbeitet, aber ich finde das noch zu störrisch. Es soll ganz ohne Höhen und Breitenangaben gehen, nur optional können dann min-width oder Margins und Paddings gesetzt werden.

        Ziel ist es dann die default Styles herauszuziehen, und dann Themes zu machen, hover und Transition, also Effekte auch als eigene CSS-Datei.

        So kann man es über CSS alleine nutzen, aber noch für JS mit jQuery tolle Effekte und Animationen dazuschrauben. Das Gute wäre eben, es geht auch ohne JS und kann direkt mit Daten aus einer DB befühlt werden. Auch bei x-Ebenen, es sieht immer sauber aus.

        Ich werde in den nächsten zwei Tagen, das Ergebnis, also den aktuellen Stand als Demo auf meine Seite laden, dann kannst Du es Dir ansehen.

        Mal eine Frage, warum verschiebst Du die „ul“ mit left -1000%, warum nicht mit visibility arbeiten?

        1. Om nah hoo pez nyeetz, nocheinPoet!

          Mal eine Frage, warum verschiebst Du die „ul“ mit left -1000%, warum nicht mit visibility arbeiten?

          visibility: hidden und display: none haben den Nachteil, für screenreader nicht vorhanden zu sein.

          Matthias

          --
          1/z ist kein Blatt Papier.

        2. Om nah hoo pez nyeetz, nocheinPoet!

          Ich werde in den nächsten zwei Tagen, das Ergebnis, also den aktuellen Stand als Demo auf meine Seite laden, dann kannst Du es Dir ansehen.

          Vielleicht magst du es auch im Wiki als Artikel zur Verfügung stellen? Dann allerdings mit Tastaturbedienbarkeit. Vielleicht als Schritt-für-Schritt-Anleitung?

          Wäre ne tolle Sache und dadurch, dass du dann beschreiben müsstest, wie es gemacht wird, würdest du auch gleich wieder was lernen.

          Matthias

          --
          1/z ist kein Blatt Papier.