Зміна ширини елемента з кроком у декілька пікселів
Заздалегідь зазначу, що чистим CSS тут, на жаль, обійтися не вийде: Firefox і IE8+ надто точно (так-так, в даному випадку це погано) роблять обчислення ширини блоків. Однак для цих браузерів дописується нехитрий скриптик у пару рядків, якщо таки треба досягти ідеалу, хоч це і псує всю красу.
В чому суть?
Суть у тому, що іноді необхідно відобразити на сторінці гумовий блок з декількома дочірніми елементами, причому нащадок має бути або цілком видно, або не видно взагалі. Найпростіший приклад — стрічка якихось картинок із прокруткою та стрілочками з боків. Дуже некрасиво виглядає зображення, що виглядає з-під «overflow: hidden», обрізане збоку. Вихід - змусити ширину обгортки завжди бути кратною скільки пікселям. Зрозуміло, якщо ширина нащадків відрізняється від елемента до елемента, цей спосіб немає сенсу.
Як це працює?
Принцип роботи полягає в тому, що більшість браузерів обчислюють ширину нащадка, якщо вона задана у відсотках, виходячи із ширини батька. Таким чином, якщо елемент має ширину 1000%, то при зміні ширини його батька на піксель сам елемент розтягнеться або стиснеться на 10 пікселів. Власне, все.
Цю штуку описував у лебедівському скринкасті Сергій Чікуйонок ще в 2008 році, у контексті виправлення бага з «стрибаючими» блоками в IE6. Однак я, на свій подив, так і не знайшов опису цієї забавної технології на Хабрі.
Як написати?
Я розглядатиму сферичний елемент у вакуумі, що спочатку складається виключно з блоку з overflow: hidden і дуже широкого елемента з купкою нащадків, сумарна ширина яких перевищуватиме ширину обгортки:
Отже, у нас є список елементів, ширина кожного (включаючи margin) – 150px.Очевидно, що останній елемент списку буде видно повністю в одному випадку зі 150. Добре, в 11 випадках: можна залишити поза видимістю п'ятипіксельний правий margin і прийняти, що лівий маргін є частиною попереднього елемента. :-)
З опису вище зрозуміло, що треба додати обгортку блоку ". wrapper", а самому ". wrapper" задати ширину в 150 разів більшу, ніж ширина цієї обгортки. Так само ясно, що якщо написати "width: 15000%" без додаткових маніпуляцій, то результат буде дещо не тим, що потрібно. Необхідно, щоб у .wrapper збереглася ширина в 60% від ширини екрана. Це компенсується невеликою шириною обгортки, обчислюється за пропорцією. 15000 / 100 = 60 / x x = 0.4 Пишемо так:
Але все не так гладко
Проблема полягає в тому, що в частині випадків, як і в даному прикладі, доводиться задавати ширину обгортки менше одного відсотка - коли крок має бути більше 100px. Більшість браузерів це ковтають і вважають все правильно. Навіть IE6. А ось з Оперою, зокрема останніх версій, — біда. Опера не розуміє значення менше 1%.
Рішення досить просте, але потребує більшої кількості HTML. Замість того, щоб робити один блок із шириною 0.4%, зробимо два. Ширина першого - 1%, ширина другого, вкладеного в перший, - 40%. Тут і Опера стає в ряди приголосних.
Цілком можливо, що використання значення менше 1% туманно боком і в інших браузерах, проте я цього не зустрічав. Виправте мене, якщо я помиляюся. Втім, у будь-якому випадку, дробове відсоткове значення — це не дуже добре.
Тепер все працює скрізь, крім Firefox і IE останніх версій. Виправимо і це.
Скрипт для надмірно точних браузерів
Для простоти я використовуватиму jQuery. Функція, як і розмітка, такождля лабораторних умов
У наближених до життя прикладах присутні всілякі стрілки, рамки тощо. Їх позиціонування (зокрема, позиціонування елементів з того боку, куди розтягується блок) робиться таким самим способом.
Перевіряв працездатність у Firefox, Opera, Chrome, IE6-9 та Safari під Windows. Було б чудово подивитися на це все під різноманітними Safari під Макосью, Konqueror тощо. Також буду радий зауваженням/виправленням.
В основі написаного лежить згаданий вище скринкаст і наступні самостійні дослідження та експерименти на цю тему.
А у нас тут можна отримати грант на тестовий період Яндекс.Хмари. Варто лише у полі «секретний пароль» запровадити «Хабр»