Как-то меня заинтересовала технология создания меню без JS. Т.е. чисто на CSS. Через Яндекс нашел на Codepen нужный пример. Разбирая пример, я к радости обнаружил, что на этом сайте можно использовать препроцессоры HTML и CSS. Забросив все дела и дачу, я потратил пару дней на "баловство". С препроцессором CSS - Less я был уже знаком по Bootstap. А вот препроцессор HTML - был для меня откровением. Потратив пару часов я остановил свой выбор на Slim. Потом еще сутки на изучение основ Ruby. Можно, кстати, обойтись и без Raby, но с ним намного круче. И вот для закрепления я решил перелопатить найденный пример меню на Less и Slim.

Здесь вложенные тэги вычисляются по отступам. Например этот slim

    
    ul
      li Я из лесу вышел...
      li Как много в этом звуке... 
   
   
отобразится в
   
    <ul>
      <li>
        Я из лесу вышел...
      </li>
      <li>
        Как много в этом звуке...   
      </li>
    </ul>
   
   

И тут я решил добавить ul в li

    
    ul
      li Я из лесу вышел...
        ul
          li Некрасов Н.
      li Как много в этом звуке... 
   
   
и получил.....
   
    <ul>
      <li>
        Я из лесу вышел...
        ul
          li Некрасов Н.
      </li>
      <li>
        Как много в этом звуке...   
      </li>
    </ul>
   
а в просмотре:
  • Я из лесу вышел... ul li Некрасов Н.
  • Как много в этом звуке...

Ошарашенный, я уж подумал - это глюк Slim. Была мысль перейти на Haml. Но полазив часа 2 по инету и посмотрев примеры, я нашел такие, где вложенные тэги обрабатывались нормально.

В итоге если сделать так:

    ul
      li 
        |Я из лесу вышел...
        ul
          li Некрасов Н.
      li Как много в этом звуке... 
получим как и хотели:
  • Я из лесу вышел...
    • Некрасов Н.
  • Как много в этом звуке...

А дело в том, что если написать текст в одной строке с тэгом, то все что ниже и с отступом большим чем у тэга - будет считаться текстом. Если мы применяем черту("|"), мы можем задать новую границу отступа для текста. Но черту эту надо ставит на новой строке (иначе будет считаться текстом). И вообще все тэги и прочие элементы одного уровня следует располагать с одинаковыми отступами.

Исходный HTML:

<ul class="nav">
  <li>
    <a href="" title="Home">Home</a>
  </li>
  <li>
    <a href="" title="About us">About us</a>
  </li>
  <li>
    <a href="" title="Portfolio">Portfolio
      <ul>
        <li>
          <a href="" title="Websites">Websites</a>
        </li>
        <li>
          <a href="" title="Webshops">Webshops</a>
        </li>
        <li>
          <a href="" title="SEO">SEO</a>
        </li>
        <li>
          <a href="" title="Responsive webdesign">Responsive webdesign</a>
        </li>
      </ul>
    </a>
  </li>
  <li>
    <a href="" title="Contact">Contact</a>
  </li>
  <div class="clear"></div>
</ul>

Slim:

ul.nav
  li: a href="" title="Home" Home
  li: a href="" title="About us" About us
  li: a href="" title="Portfolio"
     |Portfolio
     ul
       li: a href="" title="Websites" Websites
       li: a href="" title="Webshops" Webshops
       li: a href="" title="SEO" SEO
       li: a href="" title="Responsive webdesign" Responsive webdesign
  li: a href="" title="Contact" Contact
  .clear
Классная вещь...

Исходный CSS:

    .clear {
  clear: both;
}
.nav {
  list-style: none;
  padding: 0;
  margin: 0;
  background: #3a3a3a;
  border-top: solid 3px #fff;
  border-bottom: solid 3px #fff;
}
.nav li {
  float: left;
}
.nav li:hover {
  background: #2e2e2e;
}
.nav li:hover > ul {
  display: block;
  background: #2e2e2e;
  border: solid 3px #fff;
  border-top: 0;
  -webkit-border-radius: 0 0 8px 8px;
  border-radius: 0 0 8px 8px;
  -webkit-box-shadow: 0px 5px 5px 0px rgba(0, 0, 0, 0.25);
  box-shadow: 0px 5px 5px 0px rgba(0, 0, 0, 0.25);
}
.nav li:hover > ul li:hover {
  -webkit-border-radius: 0 0 5px 5px;
  border-radius: 0 0 5px 5px;
  background: #1d1d1d;
}
.nav li:hover > ul > li:hover {
  background: #1d1d1d;
}
.nav li:first-child {
  -webkit-border-radius: 0 0 5px 5px;
  border-radius: 0 0 5px 5px;
}
.nav li:last-child a:hover {
  -webkit-border-radius: 0 0 5px 5px;
  border-radius: 0 0 5px 5px;
}
.nav li a {
  display: block;
  padding: 0 20px;
  text-decoration: none;
  line-height: 40px;
  color: #fff;
}
.nav ul {
  display: none;
  position: absolute;
  list-style: none;
  margin-left: -3px;
  padding: 0;
  overflow: hidden;
}
.nav ul li {
  float: none;
}

Less:

@color_li:rgb(58,58,58);
.rad(@r){-webkit-border-radius: 0 0 @r @r;
         border-radius: 0 0 @r @r;}
.shadow(@r){-webkit-box-shadow:  0px @r @r 0px rgba(0, 0, 0, 0.25);
            box-shadow:  0px @r @r 0px rgba(0, 0, 0, 0.25);}
.clear {
  clear: both;
}
.nav{
  list-style: none;
  padding: 0;
  margin: 0;
  background: @color_li;
  border-top: solid 3px #fff;
  border-bottom: solid 3px #fff;
  li{   float: left;     
        &:hover{background: @color_li*0.8;
                 >ul{
                      display: block;
                      background: @color_li*0.8;
                      border: solid 3px #fff;
                      border-top: 0;  
                      .rad(8px);
                      .shadow(5px);
                      li{&:hover{.rad(5px);
                      background: @color_li*0.5;}}
                      >li{&:hover{background: @color_li*0.5;}}
                 }
               }
        &:first-child{.rad(5px);}
        &:last-child{a{&:hover{.rad(5px);}}}   
        a{display: block;
          padding: 0 20px;
          text-decoration: none;
          line-height: 40px;
          color: #fff;}
   }
  ul{display: none;
     position: absolute;
     list-style: none;
     margin-left: -3px;
     padding: 0;
     overflow: hidden;
     li{float: none;}
  }
}
    

See the Pen CSS menu(from Slim & Less) by cpp-v (@cpp-v) on CodePen.


Можно посмотреть и на Codepen.