5202

ein Blog über technische Fragen zu Blogger

Eine Content-Menü im Kacheldesign

von
Ich wurde gebeten darüber zu schreiben, wie man ein Menü baut. Ich denke, für einfache Menüs gibt's genug Anleitungen im Netz, muss ich ja nicht auch noch was schreiben - um's nicht allzu langweilig zu machen, werde ich heute also über etwas schreiben, was eher 'unüblich' ist, nämlich ein Content-Menü im Kachel-Design. Content-Menü meint, das der Inhalt des Menüs keine Links sind, sondern kurze Texte, Bilder oder Grafiken.

Demo

So sieht's aus, wenn alles fertig ist:

Demo

HTML: Die Liste

Wir fangen mit einer ungeordneten Liste an - 13 <li> Tags untereinander:
<ul>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
Listenpunkte eine id geben
Um jeden Listenpunkt später auch im IE einzeln ansprechen zu können, müssen wir leider umständlich id's vergeben:
<ul class="menu">
<li id="one"></li>
<li id="two"></li>
<li id="three"></li>
<li id="four"></li>
<li id="five"></li>
<li id="six"></li>
<li id="seven"></li>
<li id="eight"></li>
<li id="nine"></li>
<li id="ten"></li>
<li id="eleven"></li>
<li id="twelve"></li>
<li id="thirten"></li>
</ul>
Content einbauen
Innerhalb jedes Listenpunktes kommt nun ein Content-Container, in dem später der Inhalt eingefügt wird.
<ul class="menu">
<li id="one"><div class="content">Lorem ipsum dolor sit amet ...</div></li>
<li id="two"><div class="content">Lorem ipsum dolor sit amet ...</div></li>
<li id="three"><div class="content">Lorem ipsum dolor sit amet ...</div></li>
<li id="four"><div class="content">Lorem ipsum dolor sit amet ...</div></li>
<li id="five"><div class="content">Lorem ipsum dolor sit amet ...</div></li>
<li id="six"><div class="content">Lorem ipsum dolor sit amet ...</div></li>
<li id="seven"><div class="content">Lorem ipsum dolor sit amet ...</div></li>
<li id="eight"><div class="content">Lorem ipsum dolor sit amet ...</div></li>
<li id="nine"><div class="content">Lorem ipsum dolor sit amet ...</div></li>
<li id="ten"><div class="content">Lorem ipsum dolor sit amet ...</div></li>
<li id="eleven"><div class="content">Lorem ipsum dolor sit amet ...</div></li>
<li id="twelve"><div class="content">Lorem ipsum dolor sit amet ...</div></li>
<li id="thirten"><div class="content">Lorem ipsum dolor sit amet ...</div></li>
</ul>
Demo
Bis jetzt sieht das ganze so aus:

Titel geben
Im letzten Schritt geben wir noch jedem Listenpunkt einen Titel - damit wir das Menu später leichter gestalten können, nummerieren wir die Titel von eins bis dreizehn durch:
<ul class="menu">
 <li id="one">
  <span class="title">One</span>
   <div class="content">Lorem ipsum dolor sit amet ...
  </div>
 </li>
 <li id="two">
  <span class="title">Two</span>
   <div class="content">Lorem ipsum dolor sit amet ...
   </div>
  </li>
 <li id="three">
  <span class="title">Three</span>
   <div class="content">Lorem ipsum dolor sit amet ...
   </div>
 </li>
 <li id="four">
  <span class="title">Four</span>
   <div class="content">Lorem ipsum dolor sit amet ...
   </div>
 </li>
 <li id="five">
  <span class="title">Five</span>
   <div class="content">Lorem ipsum dolor sit amet ...
   </div>
 </li>
 <li id="six">
  <span class="title">Six</span>
   <div class="content">Lorem ipsum dolor sit amet ...
   </div>
 </li>
 <li id="seven">
  <span class="title">Seven</span>
   <div class="content">Lorem ipsum dolor sit amet ...
   </div>
 </li>
 <li id="eight">
  <span class="title">Eight</span>
   <div class="content">Lorem ipsum dolor sit amet ...
   </div>
 </li>
 <li id="nine">
  <span class="title">Nine</span>
   <div class="content">Lorem ipsum dolor sit amet ...
   </div>
 </li>
 <li id="ten">
  <span class="title">Ten</span>
   <div class="content">Lorem ipsum dolor sit amet ...
   </div>
 </li>
 <li id="eleven">
  <span class="title">Eleven</span>
   <div class="content">Lorem ipsum dolor sit amet ...
   </div>
 </li>
 <li id="twelve">
  <span class="title">Twelve</span>
   <div class="content">Lorem ipsum dolor sit amet ...
   </div>
 </li>
 <li id="thirten">
  <span class="title">Thirten</span>
   <div class="content">Lorem ipsum dolor sit amet ...
   </div>
 </li>
</ul>
Das ist die gesamte HTML - den Rest machen wir mit CSS und Javascript!
Demo
Die pure HTML schaut nun so aus:

CSS

Fangen wir damit an, das wir den einzelnen Listen-Punkte eine Höhe,Breite, Hintergrundfarbe und Abstand geben:
.menu li {
  cursor: pointer;
  height: 120px; width: 200px;
  margin: 10px 0 0 10px;
  background: #ddd

} 
Demo
Breite des Menü's bestimmen
Das zukünftige Menü soll maximal 4 Kacheln à 200px nebeneinander darstellen - mit 10px Trennung kommen wir also auf 830px; innerhalb dieser 830px lassen wir das Menü nach links fließen. Noch stehen nur drei Kacheln in einer Reihe, weil es links noch einen Rand von 10px gibt, den wir später _nur_ für die Kacheln links außen antfernen.
.menu {
  width: 830px
}
.menu li {
  position: relative;
  float: left
}

Demo
Listenpunkte entfernen - Rahmen gestalten
Wir entfernen die Listenpunkte und gestalten für das Menu einen Rahmen:
.menu {
  padding: 15px;
  list-style: none;
  background: #eee;
  -webkit-box-shadow: 0 1px 2px rgba(0,0,0,.1) inset;
     -moz-box-shadow: 0 1px 2px rgba(0,0,0,.1) inset;
      -ms-box-shadow: 0 1px 2px rgba(0,0,0,.1) inset;
       -o-box-shadow: 0 1px 2px rgba(0,0,0,.1) inset;
          box-shadow: 0 1px 2px rgba(0,0,0,.1) inset;
   -webkit-border-radius: 10px;
      -moz-border-radius: 10px;
           border-radius: 10px;
}
Demo
Menüpunkte vebreitern
Der erste und neunte Menüpunkte soll drei beziehungsweise zwei Kacheln breit werden - damit vier Kacheln in eine Reihe 'rutschen', entfernen wir jetzt links beziehungsweise oben den Rand:
.menu #one, .menu #three, .menu #seven, .menu #ten{
 margin-left: 0;     
}
.menu #one, .menu #two {
margin-top: 0px
}
#one{
  width: 620px;
}
#nine {
width:410px
}
Demo
Hintergrundfarbe
Jede Kachel bekommt eine eigene Hintergrund-Farbe - die zusätzlichen Klassen sind für später wichtig:
.menu #one,
.menu #one .content,
.menu #one .close{
  background-color: #2c618f;
}         

.menu #two,
.menu #two .content,
.menu #two .close{
  background-color: #91ab31;   
}   

.menu #three,
.menu #three .content,
.menu #three .close{
  background-color: #714a28;   
}

.menu #four,
.menu #four .content,
.menu #four .close{
  background-color: #e58600;      
}

.menu #five,
.menu #five .content,
.menu #five .close{
  background-color: #c33a00;
}

.menu #six,
.menu #six .content,
.menu #six .close{
  background-color: #7f5dac;
}

.menu #seven,
.menu #seven .content,
.menu #seven .close{
  background-color: #5672b7;     
}

.menu #eight,
.menu #eight .content,
.menu #eight .close{
  background-color: #ce7c9d;
}

.menu #nine,
.menu #nine .content,
.menu #nine .close{
  background-color: #DAA520;
}
.menu #ten,
.menu #ten .content,
.menu #ten .close{
  background-color: #2e855e;
}
.menu #eleven,
.menu #eleven .content,
.menu #eleven .close{
  background-color: #393043;
}
.menu #twelve,
.menu #twelve .content,
.menu #twelve .close{
  background-color: #CD5C5C;
}
.menu #thirten,
.menu #thirten .content,
.menu #thirten .close{
  background-color: #A0522D;
}

Demo
Content-Container ausblenden
Wir blenden jetzt erst mal den Content-Container aus und gestalten die Menü-Titel a bisserl:
.menu .content{
  opacity: 0; display: none;
.menu .title{
  position: absolute;
  height: 100%; width: 100%;
  text-align: center;
  font: italic bold 1.8em 'trebuchet MS', Arial, helvetica;
  opacity: .2;
} 
Demo
Hover
Als letzten Schritt vor dem Javascript geben wir den Kacheln noch ein Hover:
.menu li:hover {
  background-image: -webkit-linear-gradient(top, rgba(255,255,255,.2), rgba(255,255,255,0));
     background-image: -moz-linear-gradient(top, rgba(255,255,255,.2), rgba(255,255,255,0));
      background-image: -ms-linear-gradient(top, rgba(255,255,255,.2), rgba(255,255,255,0));
       background-image: -o-linear-gradient(top, rgba(255,255,255,.2), rgba(255,255,255,0));
          background-image: linear-gradient(top, rgba(255,255,255,.2), rgba(255,255,255,0));
}
.menu li:hover .title{
  opacity: .7;
}
Demo

Javascript

Zum öffnen und schließen der einzelnen Kacheln benützen wir Javascript - jeder Kachel wird mit der Klasse close ein kleines "x" als Trigger zum schließen gegeben. Bei einem Click-Ereignis auf einem Listenpunkt bekommt der innere Container eine neue Klasse expanded.
<script type='text/javascript'>
//<![CDATA[
$(document).ready(function() {
$('.menu .content').append('<span class="close">x</span>');  
  function showContent(elem){
   hideContent();
   elem.find('.content').addClass('expanded');
   elem.addClass('cover'); 
  }
  $('.menu li').click(function() {
   showContent($(this));
  });  
  $('.menu .close').click(function(e) {
   e.stopPropagation();
   hideContent();
  });  
});
//]]>
</script>
Wir geben den beiden neuen Klassen etwas Layout mit:
.menu .expanded{
  opacity: .95; display: block\9;
  overflow: visible;
  padding: 40px;
  height: 120px; width: 170px;
}
.menu .close {
  display: none;
  border: 5px solid #fff;
  color: #fff;
  cursor: pointer;
  height: 40px; width: 40px;
  font: bold 20px/40px arial, helvetica;
  position: absolute;
  text-align: center;
  top: -20px; right: -20px;
  -webkit-border-radius: 40px;
     -moz-border-radius: 40px;
          border-radius: 40px;      
}
Demo
Mit click auf die Kachel öffnet sie sich.

Smoothie

Im Menüs steht jetzt die Funktion - nun geht es darum, die Bewegung 'smoothier' zu gestalten. Als erstes machen wir die geöffnete Kachel so groß wie der Innenraum des Menüs:
.menu .expanded{
  opacity: .95; display: block;
  overflow: visible;
  padding: 40px;
  height: 430px; width: 630px;
}

Dann wird mit der CSS3-Eigenschaft transition die Bewegung anmiert:
.menu .content {
  -webkit-transition: all .3s ease-out;
     -moz-transition: all .3s ease-out;
      -ms-transition: all .3s ease-out; 
       -o-transition: all .3s ease-out;  
          transition: all .3s ease-out;  
}
Demo
Kacheln einpassen
Im letzten Schritt werden die einzelnen Kacheln genau eingepasst:
.menu #five .expanded,
.menu #nine .expanded,
.menu #twelve .expanded{ 
margin-left: -360px
}
.menu #four .expanded,
.menu #eight .expanded,
.menu #eleven .expanded{ 
margin-left: -180px
}
.menu #two .expanded,
.menu #six .expanded,
.menu #thirten .expanded{ 
margin-left: -540px
}
.menu #three .expanded,
.menu #four .expanded,
.menu #five .expanded,
.menu #six .expanded{ 
margin-top: -130px
}
.menu #seven .expanded,
.menu #eight .expanded,
.menu #nine .expanded{ 
margin-top: -260px
}
.menu #ten .expanded,
.menu #eleven .expanded,
.menu #twelve .expanded,
.menu #thirten .expanded{ 
margin-top: -390px
}
Demo
Geschafft!!!


Zusammenfassung

<style>
/* Reset
-------------------------------- */
.widget ul.menu,
.widget .post-body ul.menu {
    padding: 0;
    margin: 0;
    list-style: none;
    line-height: 0;
}
.post-body .menu { font-size: 1em }
/* Clearfix
-------------------------------- */
.menu::after {
    content: ".";
    display: block;
    clear: both;
    visibility: hidden;
    line-height: 0;
    height: 0;
}
/* Menu
-------------------------------- */
.menu {
    width: 830px;
    margin: 20px 50px !important;
    padding: 15px !important;
    list-style: none;
    background: #eee;
    -moz-box-shadow: 0 1px 2px rgba(0,0,0,.1) inset;
    -webkit-box-shadow: 0 1px 2px rgba(0,0,0,.1) inset;
    box-shadow: 0 1px 2px rgba(0,0,0,.1) inset;
    -moz-border-radius: 10px;
    -webkit-border-radius: 10px;
    border-radius: 10px;
}
    .menu .cover { z-index: 2 }
    .menu .cover:focus { outline: 0 }
/* -------------------------------- */
    .menu li {
        position: relative;
        float: left;
        cursor: pointer;
        height: 120px;
        width: 200px;
        margin: 10px 0 0 10px;
        color: #fff;
    }
#one { width: 620px }
#nine { width: 410px }
.menu li:hover,
.menu li:focus {
    background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(255,255,255,.2)), to(rgba(255,255,255,0)));
    background-image: -webkit-linear-gradient(top, rgba(255,255,255,.2), rgba(255,255,255,0));
    background-image: -moz-linear-gradient(top, rgba(255,255,255,.2), rgba(255,255,255,0));
    background-image: -ms-linear-gradient(top, rgba(255,255,255,.2), rgba(255,255,255,0));
    background-image: -o-linear-gradient(top, rgba(255,255,255,.2), rgba(255,255,255,0));
    background-image: linear-gradient(top, rgba(255,255,255,.2), rgba(255,255,255,0));
}
.menu #one,
.menu #two { margin-top: 0px }
.menu #one,
.menu #three,
.menu #seven,
.menu #ten { margin-left: 0 }
/* -------------------------------- */
    .menu #one,
    .menu #one .content,
    .menu #one .close { background-color: #2c618f }
.menu #two,
.menu #two .content,
.menu #two .close { background-color: #91ab31 }
.menu #three,
.menu #three .content,
.menu #three .close { background-color: #714a28 }
.menu #four,
.menu #four .content,
.menu #four .close { background-color: #e58600 }
.menu #five,
.menu #five .content,
.menu #five .close { background-color: #c33a00 }
.menu #six,
.menu #six .content,
.menu #six .close { background-color: #7f5dac }
.menu #seven,
.menu #seven .content,
.menu #seven .close { background-color: #5672b7 }
.menu #eight,
.menu #eight .content,
.menu #eight .close { background-color: #ce7c9d }
.menu #nine,
.menu #nine .content,
.menu #nine .close { background-color: #DAA520 }
.menu #ten,
.menu #ten .content,
.menu #ten .close { background-color: #2e855e }
.menu #eleven,
.menu #eleven .content,
.menu #eleven .close { background-color: #393043 }
.menu #twelve,
.menu #twelve .content,
.menu #twelve .close { background-color: #CD5C5C }
.menu #thirten,
.menu #thirten .content,
.menu #thirten .close { background-color: #A0522D }
/* -------------------------------- */
.menu .content {
    opacity: 0;
    overflow: hidden;
    font: 18px Arial, Helvetica;
    position: absolute;
    height: 120px;
    width: 200px;
    -webkit-transition: all .3s ease-out;
    -moz-transition: all .3s ease-out;
    -ms-transition: all .3s ease-out;
    -o-transition: all .3s ease-out;
    transition: all .3s ease-out;
}
.menu .expanded {
    opacity: .95;
    display: block;
    overflow: visible;
    padding: 40px;
    height: 440px;
    width: 750px;
}
.menu #ten .content,
.menu #eleven .content,
.menu #twelve .content,
.menu #thirten .content { bottom: 0 }
.menu #five .expanded,
.menu #nine .expanded,
.menu #twelve .expanded { margin-left: -420px }
.menu #four .expanded,
.menu #eight .expanded,
.menu #eleven .expanded { margin-left: -210px }
.menu #two .expanded,
.menu #six .expanded,
.menu #thirten .expanded { margin-left: -630px }
.menu #three .expanded,
.menu #four .expanded,
.menu #five .expanded,
.menu #six .expanded { margin-top: -134px }
.menu #seven .expanded,
.menu #eight .expanded,
.menu #nine .expanded { margin-top: -267px }
.menu #ten .expanded,
.menu #eleven .expanded,
.menu #twelve .expanded,
.menu #thirten .expanded { margin-top: -390px }
/* -------------------------------- */
.menu .title {
    position: absolute;
    height: 100%;
    width: 100%;
    text-align: center;
    font: italic bold 1em/120px 'trebuchet MS', Arial, helvetica;
    opacity: .2;
}
.menu li:hover .title { opacity: .7 }
/* -------------------------------- */
.menu .close {
    display: none;
    border: 5px solid #fff;
    color: #fff;
    cursor: pointer;
    height: 40px;
    width: 40px;
    font: bold 20px/40px arial, helvetica;
    position: absolute;
    text-align: center;
    top: -20px;
    right: -20px;
    -moz-border-radius: 40px;
    -webkit-border-radius: 40px;
    border-radius: 40px;
}
.menu .cover .close { display: block }

    </style>

<ul class="menu">
 <li id="one">
  <span class="title">One</span>
   <div class="content">Lorem ipsum dolor sit amet %u2026
  </div>
 </li>
 <li id="two">
  <span class="title">Two</span>
   <div class="content">Lorem ipsum dolor sit amet ...
   </div>
  </li>
 <li id="three">
  <span class="title">Three</span>
   <div class="content">Lorem ipsum dolor sit amet ...
   </div>
 </li>
 <li id="four">
  <span class="title">Four</span>
   <div class="content">Lorem ipsum dolor sit amet ...
   </div>
 </li>
 <li id="five">
  <span class="title">Five</span>
   <div class="content">Lorem ipsum dolor sit amet ...
   </div>
 </li>
 <li id="six">
  <span class="title">Six</span>
   <div class="content">Lorem ipsum dolor sit amet ...
   </div>
 </li>
 <li id="seven">
  <span class="title">Seven</span>
   <div class="content">Lorem ipsum dolor sit amet ...
   </div>
 </li>
 <li id="eight">
  <span class="title">Eight</span>
   <div class="content">Lorem ipsum dolor sit amet ...
   </div>
 </li>
 <li id="nine">
  <span class="title">Nine</span>
   <div class="content">Lorem ipsum dolor sit amet ...
   </div>
 </li>
 <li id="ten">
  <span class="title">Ten</span>
   <div class="content">Lorem ipsum dolor sit amet ...
   </div>
 </li>
 <li id="eleven">
  <span class="title">Eleven</span>
   <div class="content">Lorem ipsum dolor sit amet ...
   </div>
 </li>
 <li id="twelve">
  <span class="title">Twelve</span>
   <div class="content">Lorem ipsum dolor sit amet ...
   </div>
 </li>
 <li id="thirten">
  <span class="title">Thirten</span>
   <div class="content">Lorem ipsum dolor sit amet ...
   </div>
 </li>
</ul>

<!-- The JavaScript -->
<script type="text/javascript">
   (function(){
  $('.menu .content').append('<span class="close">x</span>');  
  function showContent(elem){
   hideContent();
   elem.find('.content').addClass('expanded');
   elem.addClass('cover'); 
  }
  function hideContent(){
   $('.menu .content').removeClass('expanded');
   $('.menu li').removeClass('cover');  
  }
  $('.menu li').click(function() {
   showContent($(this));
  });  
  
  $('.menu .close').click(function(e) {
   e.stopPropagation();
   hideContent();
  }); 
  $(document).keyup(function(e) {
   if (e.keyCode == 27) { 
     hideContent();
   }
  });
  
   })();
 </script>

Kommentare

Ich weiß, kein leichtes Thema :=) - ich hoffe aber, dass wenn sich jemand ernsthaft dafür interessiert ein 'unübliches' Menü zu bauen, er mit diesem Post vielleicht die eine oder andere Anregung bekommt. Auf den ersten Blick scheint das Menü sehr komplex zu sein, aber wenn man es in die einzelnen Arbeitsschritte zerlegt, wird's schnell übersichtlicher. Lasst euch von dem vielen Code nicht schrecken - Fragen, Anregungen, Lob und Kritik könnt ihr jederzeit in den Kommentaren hinterlassen.