Рассмотрим два варианта:

  • средствами css: position: fixed без шапки сайта,
  • коснёмся более интересной реализации вместе с шапкой сайта, когда мы фиксируем только меню при активной прокрутке, оставляя его всегда на виду, но если посетитель возвращается к шапке сайта, то наше меню «становится на своё место». Пример реализации такого подхода Вы можете посмотреть у Yandex а.

Примечание автора: перейдите на страницу Yandex а, задайте фразу для поиска, после чего прокрутите колёсиком мышки вниз страницы, что Вы увидите? Отображение поиска изменилось, он «зафиксировался» на белом фоне в уменьшенном виде вверху страницы. Мы рассмотрим, как поступить так же с меню.

Фиксируем горизонтальное меню с CSS: position:fixed.

   С одной стороны всё просто и легко решается средствами css в два счёта:

   Пример HTML вёрстки фиксированного горизонтального меню:

<body>
<div id="menu-top-almost-fixed" class="menu-top-almost-fixed">
<ul>
    <li><a href="#">Главная</a></li>
    <li><a href="#">Новости</a></li>
    <li><a href="#">Контакты</a></li>
    <li class="last"><a href="#">Поиск</a></li>
</ul>
</div>
<div id="content">
[содержимое страницы]
</div>
<div id="footer">
[подвал сайта]
</div>
</body>

   CSS вёрстка фиксированного горизонтального меню:

<style type="text/css">
# menu-top-almost-fixed{
position: fixed;
top: 10px;
left: 0;
height: 30px;
width: 100%;
margin: 0;
}
</style>

А теперь зададим отступ для содержимого страницы, равный высоте меню:

   CSS:

<style type="text/css">
#content {
margin-top: 30px;
}
</style>

   И вот у нас «почти» всё получилось. Меню у посетителя «всегда на виду». Но что же делать, если у нас в дизайне расположена шапка сайта, после которой следует само меню, а в шапке у нас логотип, девиз сайта, баннеры.

   Ну что ж, мы можем зафиксировать и шапку сайта, сделав отступ содержимого равным высоте шапки и меню, вместе с отступами между ними.

   Но возникает проблема. Мы значительно ограничиваем пространство просмотра содержимого страницы для наших посетителей. Вариант отказаться от шапки вообще нас не устраивает.

Фиксируем горизонтальное меню при помощи javascript.

   Итак, рассмотрим вариант, когда меню «идёт» за шапкой сайта, но если посетитель активно прокручивает вниз, меню «фиксируется» вверху и остаётся на месте. Шапка сайта при этом не видна. Если же посетитель возвращается к шапке страницы, меню «становится» на своё место «за шапкой сайта».

   Для начала привёдем полную HTML вёрстку примера макета страницы:

HTML:

<body id="bd">
<div id="header">
    <h2>Логотип сайта</h2>
    <h3>Слоган сайта</h3>
    <div id="banner">Баннер</div>
</div>
<div id="menu-top-almost-fixed" class="menu-top-almost-fixed">
<ul>
    <li><a href="#">Главная</a></li>
    <li><a href="#">Новости</a></li>
    <li><a href="#">Контакты</a></li>
    <li class="last"><a href="#">Поиск</a></li>
</ul>
</div>
<div class="content">
     [содержимое страницы]
</div>
<div id="footer">
[подвал сайта]
</div>
</body>

   Шаблон нашего сайта состоит из нескольких типичных областей:

  • шапки сайта - #header, высотой 150px
  • горизонтального меню - #menu-top-almost-fixed – высотой 30px,
  • основной информационной области страницы - #content,
  • подвала сайта - #footer.

   Приведём css вёрстку:

   CSS:

    #menu-top-almost-fixed{
        position: fixed;
        margin: 0;
        left: 0;
        top: 150px;
        height: 30px;
    }
    #header{
        display: block;
        height: 150px;
        overflow: hidden;
        position: relative;
        margin-bottom: 55px;
    }
    #menu-top-almost-fixed ul,
    #menu-top-almost-fixed li{
         list-style: none;
         margin: 0;
         padding: 0;
     }
    #menu-top-almost-fixed ul{
         display: block;
         text-align: center;
         width: 100%;
         float: left;
     }
    #menu-top-almost-fixed ul li{
         display: inline;
         line-height: 30px;
         width: 120px;
         padding: 0 5px;
         text-align: center;
}

   Для начала зададим отступ от шапки до содержимого, равный высоте нашего меню + небольшой отступ с запасом для эстетической красоты. #header { margin-bottom: 55px; } . Зафиксируем наше меню сразу за шапкой: #menu-top-almost-fixed{ position: fixed; margin: 0; left: 0; top: 150px; height: 30px; } .

   А теперь позаботимся о том, чтобы при прокрутке меню «фиксировалось» точно вверху страницы.

   Поместим следующий javascript между <head> и </head>:

   Javascript:

<script type="text/javascript">
var m1 = 150; /* высота шапки в пикселях */
var m2 = 2; /* отступ, когда во время прокрутки шапка
 уже не видна */
var menuID = "menu-top-almost-fixed";
/* id горизонтального меню для закрепления */
var menuOpacityOnChange = "0.7";
/* прозрачность меню при
скроллинге:
1   - непрозрачное,
0.5 - полупрозрачное
0.0 - полностью прозрачное*/
var menuOpacityOnChangeIE = menuOpacityOnChange * 100;
/* функция кроссбраузерного определения
отступа от верха документа к текущей позиции
скроллера прокрутки */
function getScrollTop() {
           var scrOfY = 0;
           if( typeof( window.pageYOffset ) == "number" ) {
                   //Netscape compliant
                   scrOfY = window.pageYOffset;
           } else if( document.body
           && ( document.body.scrollLeft
           || document.body.scrollTop ) ) {
                   //DOM compliant
                   scrOfY = document.body.scrollTop;
           } else if( document.documentElement
           && ( document.documentElement.scrollLeft
            || document.documentElement.scrollTop ) ) {
                   //IE6 Strict
                   scrOfY = document.documentElement.scrollTop;
           }
           return scrOfY;
}
/* функция, которая устанавливает верхний отступ
 для «плавающего» фиксированного горизонтального
меню в зависимости от положения
 скроллера и видимости шапки */
function marginMenuTop() {
            var top  = getScrollTop();
            var s    = document.getElementById(menuID);
            if(typeof s != "undefined" && s){
              if (top+m2 < m1) {
                  s.style.top       = (m1-top) + "px";
                  s.style.filter    = s.style.filter.replace("progid:DXImageTransform.Microsoft.Alpha(opacity="+menuOpacityOnChangeIE+")","");
                  s.style.opacity   = "1";
              } else {
                  s.style.top       = m2 + "px";
                  s.style.opacity   = menuOpacityOnChange;
                  s.style.filter    = s.style.filter.replace("progid:DXImageTransform.Microsoft.Alpha(opacity="+menuOpacityOnChangeIE+")","");
                  s.style.filter    += "progid:DXImageTransform.Microsoft.Alpha(opacity="+menuOpacityOnChangeIE+")";
              }
            }
}
/** функция регистрирует
вычисление позиции
 «плавающего» меню при прокрутке страницы
**/
function setMenuPosition(){
if(typeof window.addEventListener != "undefined"){
    window.addEventListener("scroll", marginMenuTop, false);
} else if(typeof window.attachEvent != "undefined"){
    window. attachEvent("onscroll", marginMenuTop);
}
    marginMenuTop();
}
/** регистрируем вызов
необходимых функций после
 загрузки страницы **/
if(typeof window.addEventListener != "undefined"){
    window.addEventListener("load", setMenuPosition, false);
} else if(typeof window.attachEvent != "undefined"){
    window. attachEvent("onload", setMenuPosition);
}
</script>

   Примечание автора: разбор данного javascript а мы выполняли в одной из предыдущих статей «Как зафиксировать вертикальное меню», но всё итак можно понять по условным комментариям.

А пример реализации Вы можете посмотреть по этой ссылке, и воспользовавшись колёсиком прокрутки.

   Итак, здесь всё просто. В настройках мы передаём скрипту следующие параметры:

  • var m1 = 150; - высота шапки в пикселях,
  • var m2 = 2; - отступ, когда во время прокрутки шапка уже не видна,
  • var menuID = "menu-top-almost-fixed"; - id горизонтального меню для закрепления,
  • var menuOpacityOnChange = "0.7";- прозрачность меню при скроллинге:
    • 1 - непрозрачное
    • 0.5 – полупрозрачное
    • 0.0 - полностью прозрачное

   В этом варианте мы немножко «тюнинговали» наше меню, и при прокрутке мы добавляем ему полупрозрачности.

   Сразу напрашивается более классический вариант, когда мы не меняем прозрачность меню, а просто делаем для меню подложку в виде фона с цветом меню и нижней полупрозрачной границей (в которой градиент плавно «переходит» от непрозрачного цвета к прозрачному):

   Изменяем немного CSS вёрстку для нашего горизонтального фиксированного меню:

   CSS:

#menu-top-almost-fixed{
        position: fixed;
        margin: 0;
        left: 0;
        top: 150px;
        height: 30px;
        background: url(./images/white-gradient-l.png) bottom left repeat-x;
 }

   А теперь приведём изменённый javascript код, который поместим между <head> и </head>:

   Javascript:

<script type="text/javascript">
var m1 = 150; /* высота шапки в пикселях */
var m2 = 0; /* отступ, когда во время прокрутки шапка
 уже не видна */
var menuID = "menu-top-almost-fixed";
/* функция кроссбраузерного определения
отступа от верха документа к текущей позиции
скроллера прокрутки */
function getScrollTop() {
           var scrOfY = 0;
           if( typeof( window.pageYOffset ) == "number" ) {
                   //Netscape compliant
                   scrOfY = window.pageYOffset;
           } else if( document.body
           && ( document.body.scrollLeft
           || document.body.scrollTop ) ) {
                   //DOM compliant
                   scrOfY = document.body.scrollTop;
           } else if( document.documentElement
           && ( document.documentElement.scrollLeft
            || document.documentElement.scrollTop ) ) {
                   //IE6 Strict
                   scrOfY = document.documentElement.scrollTop;
           }
           return scrOfY;
}
/* функция, которая устанавливает верхний отступ
 для «плавающего» фиксированного горизонтального
меню в зависимости от положения
 скроллера и видимости шапки */
function marginMenuTop() {
            var top  = getScrollTop();
            var s    = document.getElementById(menuID);
            if(typeof s != "undefined" && s){
              if (top+m2 < m1) {
                  s.style.top       = (m1-top) + "px";
              } else {
                  s.style.top       = m2 + "px";
              }
            }
}
/** функция регистрирует
вычисление позиции
 «плавающего» меню при прокрутке страницы
**/
function setMenuPosition(){
if(typeof window.addEventListener != "undefined"){
    window.addEventListener("scroll", marginMenuTop, false);
} else if(typeof window.attachEvent != "undefined"){
    window. attachEvent("onscroll", marginMenuTop);
}
}
/** регистрируем вызов
необходимых функций после
 загрузки страницы **/
if(typeof window.addEventListener != "undefined"){
    window.addEventListener("load", setMenuPosition, false);
} else if(typeof window.attachEvent != "undefined"){
    window. attachEvent("onload", setMenuPosition);
}
</script>

Итак, здесь всё просто. В настройках мы передаём скрипту следующие параметры:

  •  var m1 = 150; - высота шапки в пикселях,
  •  var m2 = 0; - отступ, когда во время прокрутки шапка уже не видна.

   Пример реализации Вы можете посмотреть, перейдя по этой ссылке, и воспользовавшись колёсиком прокрутки.

Меню работает отлично, но, если перезагрузить страницу, меню появляется с первым отступом

   При наличии такой проблемы необходимо вызвать меню после загрузки страницы единоразово.

   Для этого изменим код вызова функции с:

function setMenuPosition(){
if(typeof window.addEventListener != "undefined"){
    window.addEventListener("scroll", marginMenuTop, false);
} else if(typeof window.attachEvent != "undefined"){
    window. attachEvent("onscroll", marginMenuTop);
}
};

   На следующий код:

function setMenuPosition(){
if(typeof window.addEventListener != "undefined"){
    window.addEventListener("scroll", marginMenuTop, false);
} else if(typeof window.attachEvent != "undefined"){
    window. attachEvent("onscroll", marginMenuTop);
}
    marginMenuTop();
};

   После загрузки страницы мы сразу вызываем нашу функцию marginMenuTop, которая проверит положение меню на странице, и применит нужный стиль

Реализуем частично фиксированное меню при помощи jQuery плагина Afixx из Twitter Bootstrap

   В продолжение этой темы для Вас была написана статья реализации почти фиксированного меню при помощи jQuery плагина Affix из Twitter Bootstrap framework.

Больше информации о веб технологиях можно узнать из нашего перечня всех статей на сайте:

Комментарии   

 
0 #11 max 02.06.2013 05:07
:lol: Спасибо, все работает на ура!
Цитировать
 
 
+3 #10 Administrator 28.03.2013 12:36
Цитирую Наталия:
Цитирую Administrator:
После загрузки страницы мы сразу вызываем нашу функцию marginMenuTop, которая проверит положение меню на странице, и применит нужный стиль


А как сделать, чтобы это происходило еще до полной загрузки страницы?

Или вообще было скрыто до полной загрузки страницы и появлялось только после её завершения?


До полной загрузки страницы это можно сделать по событию onDocumentReady . Или же перед закрытием тега поместить следующий код:
<script type="text/javascript">
marginMenuTop();
</script>
</body>


Также можно добавить в стили сайта следующее:
<style type="text/css">
#menu-top-almost-fixed{ visibility: hidden;}
</style>
Обратите внимание! Не display: none, а visibility: hidden, чтобы правильно инициализировал ись ширина, высота меню, а также координаты его положения на странице.
После чего:
<script type="text/javascript">
marginMenuTop();
document.getElementById('menu-top-almost-fixed').style.visibility = "visible";
</script>
Цитировать
 
 
0 #9 Наталия 28.03.2013 11:07
Цитирую Administrator:
После загрузки страницы мы сразу вызываем нашу функцию marginMenuTop, которая проверит положение меню на странице, и применит нужный стиль


А как сделать, чтобы это происходило еще до полной загрузки страницы?

Или вообще было скрыто до полной загрузки страницы и появлялось только после её завершения?
Цитировать
 
 
0 #8 zabrat 29.01.2013 21:13
Цитирую Administrator:

По сути вызвать хоть единожды функцию для частично фиксированного меню сразу после загрузки страницы, чтобы посчитала отступы.

Теперь ок) Спасибо. а я пробовал вызывать её в конце скрипта через
Цитата:
window.onload=function(){
marginMenuTop();
}
но так не сработало. надо больше читать мат.часть :-*
Цитировать
 
 
0 #7 Administrator 29.01.2013 20:24
Внимание. В конце статьи ссылка на новую статью на эту тему Twitter Bootstrap javascript часть вторая, в этой статье рассказывается на примере о jQuery плагине affix из Twitter Bootstrap. Который реализует похожую функциональност ь. В статье имеется пример частично зафиксированног о меню.
Цитировать
 
 
0 #6 Administrator 29.01.2013 20:22
Цитирую zabrat:
Здравствуйте. Спасибо огромное за пример скрипта. Все заработало, кроме того, что при обновлении страницы, если фиксированный элемент div id="menu-top-almost-fixed" находится не на месте, т.е. страница прокручена вниз, он появляется с отступом из css, а хотелось бы чтоб уже применялся стиль m2. Еще раз спасибо).

Все легко и просто, обратите внимание на обновленную статью.
Вам нужно изменить код:
Цитата:
function setMenuPosition(){
if(typeof window.addEventListener != "undefined"){
window.addEventListener("scroll", marginMenuTop, false);
} else if(typeof window.attachEvent != "undefined"){
window. attachEvent("onscroll", marginMenuTop);
}
};
На следующий код:
Цитата:
function setMenuPosition(){
if(typeof window.addEventListener != "undefined"){
window.addEventListener("scroll", marginMenuTop, false);
} else if(typeof window.attachEvent != "undefined"){
window. attachEvent("onscroll", marginMenuTop);
}
marginMenuTop();
};
По сути вызвать хоть единожды функцию для частично фиксированного меню сразу после загрузки страницы, чтобы посчитала отступы.
Цитировать
 
 
0 #5 zabrat 29.01.2013 19:23
Здравствуйте. Спасибо огромное за пример скрипта. Все заработало, кроме того, что при обновлении страницы, если фиксированный элемент div id="menu-top-al most-fixed" находится не на месте, т.е. страница прокручена вниз, он появляется с отступом из css, а хотелось бы чтоб уже применялся стиль m2. Еще раз спасибо).
Цитировать
 
 
0 #4 Administrator 23.01.2013 08:42
Продолжение этого примера - реализация частично фиксированного меню при помощи Twitter Bootstrap и плагина Affix. Читайте в наших статьях: Twitter Bootstrap javascript часть первая.
Цитировать
 
 
0 #3 Alex1 23.01.2013 06:48
На Wordpress`е не получается по указанному алгоритму :-| Пример анализировал. Есть здесь кто-нибудь, у кого получилось на WP?
Цитировать
 
 
+7 #2 Administrator 05.12.2011 02:59
Спасибо за Ваше мнение. Очень приятно. Просто очень часто приходится задумываться над улучшением usability сайта, а иногда и поделиться мыслями хочется.
Цитировать
 

Добавить комментарий


Яндекс.Метрика