Закрепление блока с position:fixed

29 08 2008

   За столь продолжительный период верстки сегодня мне впервые пришлось столкнуться с необходимостью разместить на странице фиксированный блок (используя CSS-свойство position:fixed), который бы при скролле страницы всегда сидел в одном месте окна браузера.

   Информацию по этому поводу я, естественно, почитал на разных блогах и форумах. Но все решения, которые я встретил, описывают немного не то, что понадобилось мне. Они описывают, как зафиксировать блок относительно края окна браузера, например, левый сайдбар или шапку.

   У меня же стояла несколько иная задача. Имеется основной родительский блок с фиксированной шириной, выровненный по центру окна (margin: 0 auto). И необходимо справа от этого блока поместить фиксированный блок, т.е. позиционироваться он должен не от края окна браузера, а от основного блока. Вот готовый пример, о котором я веду речь.

   Ниже расскажу, как я это реализовал, с учетом следующих моментов:

  • во-первых, с надеждой на то, что кому-нибудь это пригодится;
  • во-вторых, как шпаргалка себе на будущее (или написание поста с целью закрепления материала, аля “повторение — мать учения”, моя практика показывает, что написание поста с решением какой-либо незнакомой мне до этого задачи очень хорошо помогает запомнить это самое решение);
  • в-третьих, с надеждой на то, что кто-то предложит более элегантное решение.

Итак, поехали.

HTML-код

Имеем следующую базовую разметку:
<div id="wrapper"><div id="container">
основное содержание страницы
</div><div id="fixed">
<div class="fixed">
блок, который надо зафиксировать
</div>
</div>
</div>

CSS-код

Имеем следующие стили для основного и контентного блоков:

#wrapper {
width: 642px;
margin: 0 auto;
padding-right: 243px;
}
#container {
position: relative;
z-index: 10;
}

   Т.е. у нас имеется основной контейнер шириной 885px, размещенный по центру окна, из них 642px отдано под контент, который будет находиться в левой части, а 243px в правой части выделяем под наш фиксированный блок шириной в 240px. Собственное это и делает идентификатор #wrapper.

   Хочу заострить внимание на параметрах идентификатора #container, используемого для блока с основным контентом. Необходимо обязательно обозначить уровень этого слоя выше (здесь — z-index: 10), чем слой с фиксированным блоком (это согласно условиям моего примера, в других случаях сие может быть не обязательным), иначе в FireFox’e нельзя будет выделить текст в этом блоке в части высоты, равной высоте фиксированного блока.

   Чтобы получить возможность привязать фиксируемый блок к основному контентному, я сначала задал фиксируемому блоку соответствующее позиционирование (position: fixed), растянув на всю ширину окна браузера, а затем поместил в него еще один блок, к которому применил абсолютное позиционирование относительно зафиксированного родительского блока, т.е. получилось следующее:

#fixed {
position: fixed;
top: 0;
left: 0;
width: 100%;
}
.fixed {
position: relative;
width: 240px;
margin: 0 auto;
top: 10px;
left: 323px;
}

   Подобрав отступ с помощью свойства left: 323px; к блоку .fixed, отцентрированному относительно окна браузера (margin: 0 auto;), я сдвинул фиксируемый блок в предназначенное для него место.

   В результате у меня получилось то, что я и хотел. Смотрим пример всего описанного выше.

   Данный пример прекрасно работает в следующих браузерах: Opera, FireFox, Safari, IE7, но не работает в…

Internet Explorer 6

   Ну а как же без него? 🙂 Само-знамо, курилка даже не представляет, ЧТО есть значение position: fixed, поэтому опять приходится латать его дыры его же ява-скриптами.

   Чтобы укротить IE6 для нашей задачи, необходимо, во-первых, вместо position: fixed использовать абсолютное позиционирование position: absolute, во-вторых, применить expression, который и фиксирует блок. И поместим код в условные комментарии.

Вот что у нас получилось:

<;!--[if lt IE 7]>
<;style type="text/css">
#fixed {
position: absolute;
top: expression(parseInt(document.documentElement.scrollTop, 0) + "px");
left: 50%;
margin-left: -321px;
}
<;/style>
<;![endif]-->

   Объясняю, для чего здесь понадобились свойства left: 50%; и margin-left: -321px;. Дело в том, что, если использовать тот же самый отступ слева, что и для других браузеров, (left: 323px;), то фиксированный блок в IE6 ведет себя неправильно — при сужении окна браузера он смещается вправо от основного блока. Поэтому при помощи left: 50%; (данное свойство имеет здесь решающее значение, выявил “методом тыка”) и следующего дополнительного отрицательного отступа блок возвращается на предназначенное ему место.

   Все. Теперь и в IE6 мы наблюдаем тот же результат, что и в остальных браузерах.

   Однако, если посмотрите на пример в этом браузере, то заметите следующий артефакт — при прокручивании страницы блок некрасиво подергивается. Чтобы устранить данный недостаток, необходимо тегу body назначить прозрачный фоновый рисунок с фиксированным позиционированием, т.е. вот так:

body {
background: url(i/pixel.gif) fixed;
}

   Что интересно, даже не обязательно наличие картинки pixel.gif на сервере, достаточно просто этой записи, чтобы дергание исчезло.

   К сожалению, не всегда можно будет воспользоваться данным исправлением, поскольку фон body уже может быть занят элементом дизайна сайта. Тогда этот грех останется за IE6.

   Статья скачана у Dimox’а — оригинал.


Actions

Информация

4 комментария на “Закрепление блока с position:fixed”

20 04 2010
mikdmst (15:02:01) :

мысль не по теме:

вообще не понимаю. почему, если написано #wrapper {width: 642px;…

то реальная ширина width: 642px; + padding-right: 243px; = 885px

стандарты-стандарты, логика где?

25 04 2010
Infinity (19:55:05) :

Логики тут нет, есть факты и это катит ))

12 08 2012
Eolilie (04:40:25) :

Очень! Спасибо.

29 07 2013
Семён (11:16:47) :

Спасибо, уже 3 дня ищу данное решение, однако, самому на будущее, если у нас этот плавающий блок будет резиновым?! С мин и макс шириной, а основной в %? То решение с паддингом не подойдет…

Оставить комментарий

Вы можите использовать теги : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Реклама от партнеров: Что входит в группу безопасности котла. | Самая свежая информация купить одеяло бамбук киев здесь.