Отказ от js как оптимизация js, часть 1
Пагубное влияние jQuery уже приводит к тому, что разработчики потихоньку начинают забывать css и сталкиваются с ним исключительно в виде element.style . А зря! Ведь несложные, в общем-то, вещи могут сильно облегчить жизнь как разработчика, как и пользователя.
Сегодня в своих социально-эксгибиционистских мемуарах я поведаю про такие вот вещи. Как обычно, «из коробки» они Вам вряд ли пригодятся, но могут пригодиться как методы.
Начнем с основ, т.е., блочной модели.
Иллюстрация таковой для элемента с position:absolute или position:fixed будет выглядеть примерно так:
- Белой заливкой обозначена «рабочая» часть элемента, ее ширина и высота и задаются
height и width .
- Желтой — отбивка (
padding ).
- Синей — поля (
margin ).
- Зеленой —
top и bottom , т.е., расстояния от верхней границы поля до верхней границы offsetParent и от нижней до нижней.
- Фиолетовой —
left и right . То же самое, но для левой и правой границ.
(Кстати, Вы были когда-нибудь удивлены, когда абсолютно спозиционированный <h1> или <ul> оказывались ниже, чем Вам хотелось бы? )
Вместе эти размеры составляют неразрывную размерную цепь. Вот и выходит, что инструментария для точного позиционирования элементов у нас более, чем достаточно. Более того, top , right , bottom , left , margin-top , margin-right , margin-bottom и margin-left могут принимать еще и отрицательные значения и задаваться в процентах от размеров offsetParent .
Сразу оговорюсь, что если у родительского элемента height установлено в auto , W3C-браузеры должны считать, что высоты у него нет, и выражение высоты или отступа по высоте в процентах от него смысла не имеет и всегда равно нулю.
Но в случае элементов с position: fixed нам несказанно повезло, offsetParent 'ом для таких элементов служит окно браузера, которое всегда имеет как ширину так и высоту.
Воспользуемся этим: расположим лайтбокс фиксированных размеров ровно посередине экрана. Для этого при помощи top и left установим границу полей прямо посередине экрана, а сами поля сделаем отрицательными, так, что они «вытолкнут» элемент в центр.
Вот так. Дешево и сердито. И, заметьте, никаких onresize, нам нужно установить элемент в центр экрана (viewport'а, если точнее), мы берем его и устанавливаем. В замечательном браузере Microsoft Internet Explorer 6, правда, position: fixed нет как такового, но зато есть целая гора фиксов.
Ну и примерчик.
var createLightBox = (function (){
function insertCSS (){
if (arguments.callee.run) return;
var css = document.createElement("style");
css.type = "text/css";
css.appendChild(document.createTextNode("\
.js-my-lightbox {\
position: fixed;\
left: 50%;\
width: 336px;\
height: 76px;\
margin: -38px 0px 0px -168px;\
top: 50%;\
background: crimson url(/forum/images/ca_serenity/misc/logo.gif) 0px 0px no-repeat;\
cursor: pointer;\
}\
"));
document.getElementsByTagName("head")[0].appendChild(css);
arguments.callee.run = true;
};
function onclick(){
this.parentNode.removeChild(this);
};
return function(){
insertCSS();
var myLightBox = document.createElement("div");
myLightBox.className = "js-my-lightbox";
myLightBox.onclick = onclick;
document.body.appendChild(myLightBox);
};
})();
createLightBox();
И напоследок. Как Вы думаете, как будет расположен элемент?
.my-element {
position: fixed;
margin: 3px;
border: solid green 3px;
padding: 10px;
width: auto;
height: auto;
top: 0px;
right: 0px;
bottom: 0px;
left: 0px;
}
Эх, боюсь, за сегодня не напишу всего, что хотел. Ну, как-нибудь в другой раз.
|
После FD точку с запятой ставить не надо:
Точку с запятой ставят после FE, чтобы следующее выражение в скобках не привело к вызову функции:
Неудобно. Нужно знать ширину и высоту объекта. А если не знаем или она динамически изменяется?
А где вы увидели указание о том, что этот рецепт на все случаи жизни?
Не могу понять, почему left:-50% на схеме отступов... ))) видимо опечатка ? )
Да, разумеется, опечатка.
Можно сделать проще, если ввести ещё один div
Чтобы не распинаться, пишу всё в атрибут style. Думаю, кому надо, сам рассуёт всё по таблице стилей.
<div style="position:fixed;left:50%;top:50%">
<div style="position:relative;left:-50%;top:-50%">
</div>
</div>
Такой подход не требует вычисления величины отрицательных отступов.
Понятно, что я прописал не все параметры, необходимые для нормальной работы (требуется как минимум задать ширину и высоту внешнего div-a), но достаточно, чтобы показать суть идеи.
Метод не универсален, т.к. внешний div может своими невидимыми частями перекрывать расположенные на более низких слоях элементы, не позволяя осуществить по ним клик.