Xiper

Смещение на 1px

Автор: Евгений Рыжков Дата публикации:

Проблема

В IE6 элемент с абсолютным позиционированием (position: absolute) смещается на 1px при использовании координат right: 0 и/или bottom: 0. Такой осяк наблюдается, когда высота(ширина) родителя имеет нечетное значение, например width: 101px.

В реальности с этим багом можно столкнуться когда нам нужно сделать блок со скругленными углами. Блок у нас резиновый. Поэтому правый нижний угол имеет такие стили:

.cornerRightBottom {
position: absolute;
right: 0;
bottom: 0
}
в нормальных браузерах все нормальнов нормальных браузерах
все нормально
в IE6 есть смещение на 1pxВ IE6 есть смещение на 1px

При разной ширине (высоте) родительского блока IE6 понимает right: 0 (bottom: 0) по разному —

  • при ширине (высоте) равной нечетному значению right: 0 (bottom: 0) = right: 1px (bottom: 1px)
  • при ширине (высоте) равной четному значению right: 0 (bottom: 0) = right: 0 (bottom: 0)

Решение

Для IE6 используем expression, котрое вычисляет ширину (высоту) родительского блока и в зависимости от четности значения подставляет координаты -1px или 0.

.cornerRightBottom {
position: absolute;
right: 0;
bottom: 0
}
* html .cornerRightBottom {

righty:expression(parentNode.offsetWidth % 2 ? style.right="-1px" : style.right="0px");
bottomy:expression(parentNode.offsetHeight % 2 ? style.bottom="-1px" : style.bottom="0px");
}

righty и bottomy — выдуманные свойства, т.к. при использовании right и bottom браузер может подвисать.

Недостатки:

  • использование expression замедляет работу браузера
  • не проходит валидацию

Данный прием имеет смысл применять только для резиновых блоков, когда нельзя заранее знать точные размеры родителя. При жестко фиксированных размерах разумнее будет прописать просто right (bottom) 0 или -1px в зависимости от заданных ширины и высоты родительского блока.

Вариант без expression

update:

На практике можно применить более элегантное решение, если вспомнить о возможности относительного позиционирования абсолютных (position: absolute) и относительных (position: relative) элементов. Этот прием более детально расписан в статье "Вычисляемые отступы". Например, у нас правый верхний уголок размером 5 на 5px. Ликвидируем expression, иcпользуя следующий код:

.corner {
	width: 5px;
	height: 5px;
	background: (path-to/corener.png);
	position: absolute;
	top: 0;
	margin-left: 100%;
	left: -4px;
	overflow: hidden;
}

margin правильно определяет ширину родителя, потому наш угол встанет на нужное место. Акцентирую внимание, что отступ слева в 100% нужно задавать именно margin-left, поправляя позицию с помощью left. Наоборот не сработает.

update by set Следует заметить, что аналогичный трюк для случая bottom: 0 при нечетных значениях высоты родителя не будет работать.

Материалы

  • Создание блоков со скругленными уголками