Розкладка в CSS: float

  1. Розкладка в CSS: float Довга епопея з написанням статті про властивості "float" завершена. Нехай...
  2. колонки
  3. пропорційна ширина
  4. Розтягування тільки однієї колонки
  5. фіксована ширина
  6. Висота колонок
  7. засада
  8. Навіщо така складність
  9. рішення
  10. Меню
  11. мораль
  12. Розкладка в CSS: float
  13. Принцип роботи
  14. колонки
  15. пропорційна ширина
  16. Розтягування тільки однієї колонки
  17. фіксована ширина
  18. Висота колонок
  19. засада
  20. Навіщо така складність
  21. рішення
  22. Розкладка в CSS: float
  23. Принцип роботи
  24. колонки
  25. пропорційна ширина
  26. Розтягування тільки однієї колонки
  27. фіксована ширина
  28. Висота колонок
  29. засада
  30. Навіщо така складність
  31. рішення
  32. Розкладка в CSS: float
  33. Принцип роботи
  34. колонки
  35. пропорційна ширина
  36. Розтягування тільки однієї колонки
  37. фіксована ширина
  38. Висота колонок
  39. засада
  40. Навіщо така складність
  41. рішення
  42. Розкладка в CSS: float
  43. Принцип роботи
  44. колонки
  45. пропорційна ширина
  46. Розтягування тільки однієї колонки
  47. фіксована ширина
  48. Висота колонок
  49. засада
  50. Навіщо така складність
  51. рішення
  52. Розкладка в CSS: float
  53. Принцип роботи
  54. колонки
  55. пропорційна ширина
  56. Розтягування тільки однієї колонки
  57. фіксована ширина
  58. Висота колонок
  59. засада
  60. Навіщо така складність
  61. рішення
  62. Розкладка в CSS: float
  63. Принцип роботи
  64. колонки
  65. пропорційна ширина
  66. Розтягування тільки однієї колонки
  67. фіксована ширина
  68. Висота колонок
  69. засада
  70. Навіщо така складність
  71. рішення
  72. Меню
  73. мораль

Розкладка в CSS: float

Довга епопея з написанням статті про властивості "float" завершена. Нехай часу пішло багато, але мені здається, що мені вдалося максимально дохідливо звести все різноманіття поводжень цього потужного і трохи дивного властивості в одну загальну систему.

Крім того, ця стаття містить рекордну кількість ілюстрацій серед всього " підручника ":-)

Доля властивості "float" в CSS злегка схожа на долю тега "table" в HTML: ні те, ні інше взагалі не замислювалося як засіб створення колонок і взагалі розкладки елементів. Однак через певні недосконалостей механізму позиціонування float використовується для цієї мети дуже широко. А то, що придумувався він для іншого, часто проявляється різними неочевидними ефектами. Однак перед тим, як їх показати, я все ж розповім, як float'и можна застосовувати для розкладки.

На самому початку - невелике зауваження про терміни. У російській мові не склалося жодного відомого терміна для цього інструменту (поки, принаймні). Тому я вважаю за краще писати його в вихідному написанні - "float". Читається це приблизно як "флоут" (ламати вилиці вимовою "флоат" не потрібно). Заодно тут же прошу пробачити мені такі вольності як "заfloat'іть", "пріfloat'нутий" і т.п. :-)

Принцип роботи

Як і позиціонування, float використовується для того, щоб рухати бокси. Але на відміну від позиціонування, яким можна рухати бокси практично довільно, все, що може float - це зрушити елемент до однієї зі сторін потоку , Правою чи лівою.

При цьому сам бокс і наступні за ним в потоці набувають цікаве поведінку:

При цьому сам бокс і наступні за ним в потоці набувають цікаве поведінку:

  1. Float'нутий бокс зміщується по горизонталі і прилипає до однієї зі сторін батька.
  2. Float'нутий бокс перестає лунати на всю ширину батьківського боксу-контейнера (як це відбувається з блоками в потоці). З його непріжатой до батькові чи матері вільної сторони з'являється вільне місце.
  3. Наступні за ним блокові бокси підтягуються вгору і займають його місце, як якщо б float'нутого боксу в потоці не було.
  4. Рядкові ж бокси всередині посунувши наверх блоків починають обтікати float'нутий бокс з вільною боку.

Хочу ще раз підкреслити очевидну відразу річ: сама коробка блоку, наступного за float'ом, підлазить під нього і займають всю ширину потоку, а ось текст всередині цього блоку зміщується в бік і обтікає float.

Далі цікаво, як себе ведуть float'нутие в одну сторону бокси, які йдуть один за іншим. В цьому випадку наступний бокс буде намагатися вміститися збоку від попереднього, з його вільної сторони. І тільки якщо йому там не буде достатньо місця, тоді він зміститься нижче і буде намагатися вміститися вже там.

Є ще один маленький технічний аспект, що не обов'язковий для розуміння всієї "механіки". Заfloat'іть можна як блокові бокси, так і малі. При цьому малі тут же автоматично стають блоковими. Тобто, писати display: block; для float'а зайве.

З двох описаних особливостей float'ов - притискання до краю і стикування збоку один одного - випливають два основних застосування їх в розкладці:

  • поділ сторінки на колонки
  • горизонтально розташовані меню

колонки

Колонки - це коли блоки тексту розташовані поруч один з одним і мають однакову висоту.

Все колоночного розкладки я буду розглядати на ось такому простому HTML'ном коді з двома блоками:

<Body> <div id = "sidebar"> ... </ div> <div id = "content"> ... </ div> </ body>

Відразу варто сказати, що робити колонки в розтяжному по ширині контейнері складніше, ніж із заданою шириною. Тут є два принципово різних підходи, які підходять для різних випадків.

пропорційна ширина

пропорційна ширина

Якщо потрібно, щоб ширина колонок змінювалася пропорційно, при зміні ширини сторінки, то підхід такий:

#content {float: right; width: 70%; } #Sidebar {float: left; width: 30%; }

Тобто два блоки float'ятся поруч в різні боки, а їх ширина ділиться в потрібному процентному співвідношенні. Цей спосіб дозволяє легко поміняти колонки місцями - просто помінявши значення right і left.

Розтягування тільки однієї колонки

Якщо потрібно, щоб змінювалася тільки ширина основної колонки, то попередній спосіб не підходить. Справа в тому, що в CSS, на жаль, не можна безпосередньо сформулювати таку річ як "вся доступна ширина мінус конкретне число".

Тепер звернемося до однієї з попередніх статей про блоки в потоці , Де я згадав про одну їх корисної особливості автоматично укладатися по ширині в розмір батьківського боксу. Тобто, якщо блоку в прямому потоці задати, скажімо, лівий margin, то його ширина відповідно скоротиться. А це саме те поведінка, якого ми хотіли добитися від однієї з колонок.

А це саме те поведінка, якого ми хотіли добитися від однієї з колонок

Отже, для потрібного нам ефекту ми дамо основного блоку лівий margin, щоб він стиснувся направо, а бічну панель заfloat'ім на це місце:

#sidebar {float: left; width: 200px; } #Content {margin-left: 200px; }

Але у другого способу є один дуже серйозний недолік. Зверніть увагу, що в початковому HTML блок "sidebar" йде до блоку "content" з основним вмістом. Не потрібно думати, що так зроблено випадково :-). Так зроблено спеціально, тому що інакше цей самий другий спосіб з накладенням колонки поверх margin'а не працював би.

Так зроблено спеціально, тому що інакше цей самий другий спосіб з накладенням колонки поверх margin'а не працював би

Як я написав на початку статті, float'и зсуваються тільки в сторону і дають місце наступним блоками, які з'їжджають наверх. Тому принципово, щоб "sidebar" був уже нагорі, і тоді основний блок під'їде до нього. Якщо "sidebar" йде після основного блоку, то він так і залишиться нижче, і ні на які колонки це схоже не буде.

Це дійсно погано, тому що перекреслює одну з основних ідей CSS: відділення оформлення від змісту. Виходить, що ми захотіли змінити тільки дизайн, а якщо блоки розташовані "не так", то доведеться лізти ще і в HTML-шаблони. Крім того, з точки зору структури можуть бути свої вагомі підстави розташовувати блоки так, а не інакше. Наприклад щоб користувач міг почати читати основний текст сторінки, не чекаючи завантаження навігації.

фіксована ширина

Все різко спрощується, коли колонки поміщаються в фіксовану ширину контейнера. В цьому випадку краще всього використовувати перший спосіб (float'іть все колонки), і ширину вже можна задавати не тільки у відсотках, а й у чому хочете, оскільки її можна точно обчислити.

Висота колонок

Знову-таки, я далеко не випадково "відрізав" на картинках нижню частину блоків :-). Інакше б вони як колонки зовсім не виглядали, тому що, як неважко переконатися, якщо застосувати ті фрагменти CSS, що я привів, і розфарбувати колонки різними кольорами, то їх висота виявляється різною. Вона залежить від кількості вмісту в цих блоках.

Цей негарний ефект можна обійти кількома способами.

Перший спосіб називається "Помилкові колонки" ( "Faux columns"), опублікований в авторитетному веб-журналі A List Apart у вересні 2004 року і з тих пір користується великою популярністю. Всім рекомендую прочитати або оригінал , або російський переклад . Однак якщо ви сьогодні не в настрої клікати, то ось коротко його суть.

Замість того, щоб призначати фон самим колонок, вони залишаються прозорими, а ось їх контейнеру призначається фонова картинка шириною у весь контейнер і повторювана по вертикалі. Частини цієї картинки, що знаходяться під різними колонками, фарбуються в різні кольори і при повторенні вниз це дає потрібний візуальний ефект.

Частини цієї картинки, що знаходяться під різними колонками, фарбуються в різні кольори і при повторенні вниз це дає потрібний візуальний ефект

Що в помилкових колонках чудово - так це те, що ви можете не обмежувати себе на фонової зображенні рівними квітами. На ній, наприклад можна намалювати ефект тіні між колонками, що повторюються горизонтальні смужки у вигляді фону, орнамент по краях.

Недолік же способу полягає в тому, що оскільки у фонової картинки є тільки один розмір, її не можна застосовувати для пропорційно розтягуються колонок, так як картинка тягти не буде (тут я помилився; все цілком можна застосувати, читайте коментар ). А ось для випадку, коли одна з колонок фіксована по ширині, фон пристосувати можна (цей випадок, до речі, в "Faux columns" не розглянутий).

Суть полягає в тому, щоб помістити фонову картинку тільки під ту колонку, ширина якої відома. Решта місце буде зайнято фоновим кольором контейнера, а не картинкою.

Візьмемо наш приклад і зробимо колонку "sidebar" справа шириною 200 пікселів, а "content" нехай розтягується. Для "sidebar" підготуємо картинку розмірами 200х1 наприклад рівного синього відтінку. А під "content" відведемо жовтуватий.

У стилях це виглядає так:

#sidebar {float: right; width: 200px; } #Content {margin-right: 200px; } Body {background: url (bg.png) #FFD right top repeat-y; }

Єдине правило для контейнера (body) задає всі поведінку фону:

  • вказується URL картинки (bg.png)
  • колір фону в тих місцях, де її не буде (#FFD)
  • становище картинки притиснутою до правого краю (right top)
  • повторення картинки вниз (repeat-y)

У реальному прикладі в CSS ще була пара правил для кольору букв і боротьби з межами, які зараз не істотні.

Інший спосіб зрівнювання колонок по висоті був описаний недавно і вже сильно відомий, оскільки зручний.

Інший спосіб зрівнювання колонок по висоті був   описаний недавно   і вже сильно відомий, оскільки зручний

Ідея його полягає в тому, щоб нерівність висот колонок заховати, неймовірно подовживши їх вниз, щоб їх кінці були за межами реального вмісту сторінки. Домагаються цього тим, що спочатку ставлять колонкам дуже великий відступ (padding) вниз, який зафарбовується кольором фону. А щоб все інше вміст теж не порушувався туди далеко, колонкам призначається негативна межа (margin) такого ж розміру:

#content, #sidebar {padding-bottom: 32767px; margin-bottom: -32767px; }

Дивне число обумовлено тим, що це максимум, який може дозволити браузер Safari. Насправді воно не настільки дивне. Кому цікаво, це максимальне знакове ціле число, якщо представляти його 16 бітами.

У підсумку все, що йде за колонками зміщується і знаходиться прямо під вмістом найдовшої з них, а колонки подовжуються вниз. Негарно одне - через довгих колонок сама сторінка стає такою ж довгою. Щоб з цим боротися, треба їх контейнеру проставити властивість overflow: hidden, яке змушує контейнер просто відрізати і не показувати те, що виходить за його межі.

У мого прикладу, який я взяв на самому початку, є, правда, одна заковика. Там колонки лежать прямо в body. А якщо body проставити overflow: hidden, то браузери скасовують скролінг у сторінки начисто. Навіть якщо реальний вміст вище вікна. Тому колонки треба загорнути в ще один елемент, наприклад div. Але справедливості заради треба сказати, що на практиці колонки і так бувають у що-небудь вже загорнуті.

засада

Куди ж без неї :-). Як я не особливо прозоро натякнув на самому початку, оскільки float'и не вигадували як засіб створення колонок, це обов'язково вилізе чимось потворним і відгукнеться збільшенням витрати анальгіну (деякі вважають за краще темпалгин або парацетамол).

Причому "вилізе" - в прямому сенсі. Давайте трохи посунемо наш "голий" приклад в сторону реальності, додавши над колонками шапку і внизу якийсь теж блок з текстом.

<Body> <div id = "header"> ... </ div> <div id = "main"> <div id = "content"> ... </ div> <div id = "sidebar">. .. </ div> </ div> <div id = "footer"> ... </ div> </ body>

Для простоти виберемо нехитрий стовпчик дизайн з фіксованою шириною. Шапку і нижній блок зробимо синіми з білими буквами, основний вміст білим, а додаткову колонку теж синьою, але трохи світліше. Кольори колонкам задамо способом "Faux columns".

/ * Розкладка в колонки * / body {width: 600px; margin: 0 auto; } #Content {float: left; width: 450px; } #Sidebar {float: right; width: 150px; } / * Кольори * / #main {background: url (bg.png) right top repeat-y; } #Header, #footer {background: # 238; color: white; }

Всякі відступи і шрифти я знову опустив для простоти сприйняття. Додамо тестового тексту і запускаємо:

Хм ... Ну, колонки, в загальному, навіть можна розгледіти! Чи не причепишся! Утім, як не крути, але виглядає все не так, як задумано, а навіть можна сказати, все перетворилося в якусь кашу з квітів і букв.

Щоб зрозуміти, чому так відбувається, треба згадати опис того, як працює float. А саме, що блоки, що йдуть за float'амі перестають ці float'и помічати і підтягуються вгору. Більш того, сам контейнер, в якому float'и знаходяться, теж перестає їх помічати і float'нутие блоки провалюються через низ контейнера, якщо він закінчуватися раніше.

Тепер подивимося на наш код. Обидва float'нутих блоку "content" і "sidebar" знаходяться всередині блоку "main". І більше нічого в "main" немає. А раз йому нічого більше утримувати, то його висота схлопивается в нуль! Тому й не видно на зображенні ні білого фону "content", ні світло-синього фону "sidebar", тому що ці кольори призначені у вигляді фону "main".

Далі - "footer". Він, підкоряючись все тим же правилом, теж не бачить float'нутих блоків і підтягується наверх прямо до самого заголовку (оскільки "main" - нульовий висоти). Але в "footer" є текст. Текст цей вже повинен обтікати float'и: справа "content" і зліва "sidebar". Між колонками місця не залишилося, тому текст може початися тільки під одним з колонок, яка перша скінчиться. Там він і є. Таким чином, "footer", підтягшись під заголовок, триває вниз, поки не закінчиться весь його текст. І весь цей синій фон, що нижче заголовка - це "footer" і є.

Навіщо така складність

Описане поведінка повинна вселяти подив. Навіщо треба було вигадувати такі складності: розділити поняття блоку так, щоб кольори і рамки наверх, а текст - на місці? Але сенс, звичайно, є. Це, поряд зі спаданням кордонів , Спроба змусити боксову модель CSS нормально вести себе в умовах простого потоку тексту. Детальний класичне пояснення цьому феномену є все у того ж Еріка Мейєра в статті " Containing Floats "(Англійською). Постараюся коротко передати суть.

Уявіть собі звичайний потік абзаців - блоків з текстом - без всякого позиціонування. В одному з абзаців зустрічається картинка, яку хочеться зрушити, скажімо, вліво, щоб текст її обтікав. Таке раніше в HTML досягалося властивістю align = "left", але в дусі винесення оформлення з HTML в стилі, для цієї функції як раз і придумали властивість float. Тобто замість align цій картинці приписується float: left.

Нехай зсувається картинка займає по висоті більше, ніж текст абзацу. Якщо вона буде розтягувати свій абзац і відсувати початок наступного нижче, то це буде виглядати непривабливо через збільшеного відстані між рядками сусідніх абзаців. Тому вона і провалюється через усі межі блоків, зберігаючи між ними гарні відступи, а текст її обтікає.

рішення

Отже, поведінка з проваленням зрозуміло, але воно зручно для непозіціонірованного тексту, а для розкладки - зовсім незручно. Існує два підходи усуває обидва прояви цієї властивості: підтягування наступних боксів наверх і провалювання через низ контейнера.

Для усунення підтягування блоків існує спеціальне властивість - clear. Воно змушує елемент зсуватися вниз, поки збоку від нього не залишиться float'ов. Причому можна управляти, з якого саме боку не повинно бути float'ов:

clear: left стежить, щоб float'ов не було зліва clear: right стежить, щоб float'ов не було справа clear: both стежить, щоб float'ов не було з обох сторін

Таким чином, якщо ми скажемо нашому "footer" у:

#footer {clear: both; }

... щоб зліва і праворуч від нього не було float'нутих колонок, то він зрушить вниз якраз туди, де вони обидві закінчуються.

Але це не вирішує іншої проблеми: того, що float'и провалюються через "main", і той схлопивается, в результаті чого не видно колоночного фону, який йому призначено. Провалювання можна перемогти двома способами.

Можна явно спозиционировать контейнер якимось чином. Наскільки я розумію логіку специфікації, поведінка провалювання вважається логічним тільки в простому потоці. В інших випадках воно тільки заважає. І так воно і є, як ми переконалися. Тобто досить призначити контейнеру наприклад position: absolute або float: left і нічого не буде провалюється, контейнер буде повністю укладати в себе і текст, і float'и. У нашому випадку (і в більшості випадків, до речі) це рішення цілком підійде.

Інший цікавий спосіб пов'язаний з побічним ефектом властивості overflow. Само по собі воно призначене для того, щоб визначати, як буде вести себе контейнер при переповненні, коли не може вмістити свій вміст. У нього є чотири значення:

visible вміст переходить через край і його нормально видно (це поведінка за умовчанням) hidden вміст відсікається за межами контейнера і його там ніяк не видно auto якщо вміст переповнює контейнер, у нього з'являється скроллбар, що дозволяє прокручувати вміст, якщо ні - не з'являється scroll схоже на auto, тільки скроллбар у контейнера є завжди, навіть коли вміст його не наповнюється

Так ось побічний ефект полягає в тому, що якщо контейнеру поставити будь-overflow, крім звичайного visible, він раптом розтягується і укладає в себе float'и, які в ньому сидять, усуваючи провалювання.

Який же overflow використовувати? Відразу відпадає scroll - завжди висять скроллбар явно не потрібні. Залишаються auto і hidden, які відрізняються тільки тим, з'являється скроллбар при переповненні чи ні. Але у нас ніякого переповнення немає, навпаки, цією властивістю ми змусили контейнер додатково розтягнутися, щоб він охоплював всі свої елементи. Тому використовувати можна будь-яке значення.

Я забобонно намагаюся використовувати hidden, щоб не з'являлося скроллбар, якщо через якихось глюків переповнення раптом виникне.

Я забобонно намагаюся використовувати hidden, щоб не з'являлося скроллбар, якщо через якихось глюків переповнення раптом виникне

У рішення з overflow є одна заковика, пов'язана з поведінкою Деякого Браузера ™. Воно працює тільки якщо контейнеру явно призначені ширина або висота. Через це їм іноді незручно користуватися, коли вам потрібні автоматичні розміри, а не жорсткі.

Отже, в підсумку, щоб виправити наш приклад з колонками, треба зробити так:

#main {width: 100%; overflow: hidden; }

До речі! Якби для малювання фону під колонками я використав не faux columns, а спосіб з довгим padding'ом, то він би зажадав використовувати overflow: hidden для "main", що заодно вирішує і проблему з проваленням. Але як би тоді я про це розповідав?

Все на цьому з колонками ... Час сходити налити собі смачного чаю (багато хто воліє кави) і, додавши до цього якусь смачну булочку, зробити паузу для укладання в голові всього цього місива. Далі нас чекає маленька добавка - про меню.

Меню

Нагадаю, що якщо кілька йдуть підряд блоків заfloat'іть в одну сторону, то кожен наступний буде намагатися розкластися з вільною боку від попереднього. Цей ефект широко використовується для того, щоб перетворювати списки розділів сайту в горизонтально розташовані меню.

Візьмемо такий список:

<Ul> <li> <a href="/"> Початок </a> </ li> <li> <a href="catalog/"> Каталог </a> </ li> <li> <a href = "basket /"> Кошик </a> </ li> <li> <a href="help/"> Довідка </a> </ li> </ ul>

Щоб це було схоже на меню, треба заfloat'іть все li вліво, прибрати у них атрибутику списку (відступи і буліти) і ще додати для краси відступи, фон і рамку:

/ * Розкладка * / ul, li {float: left; list-style: none; margin: 0; padding: 0; } / * Вид * / li {padding: 2px 10px; font: Bold Small Tahoma; background: # 35C; color: white; border: solid 1px; border-color: # 46F # 238 # 238 # 46F; } A {color: white; text-decoration: none; }

Зверніть увагу, що для розкладки все властивості призначаються і для елементів ul, і для li. Це зручно звести в одне правило, тому що:

  • float: left потрібен елементам списку, щоб вони розклалися горизонтально, а самому списку - щоб елементи через нього не провалювалися;
  • нульові margin і padding усувають відступи, які браузери роблять для списків за замовчуванням, але вони це роблять дуже по-різному, тому простіше сказати "всім все по нулях", ніж пам'ятати що окремо для якого елементу проставляти.

мораль

Механізм float - ще один засіб розкладки поряд з абсолютним позиціонуванням.

Він відрізняються в кращу сторону, дозволяючи залишити елемент в потоці, що дуже зручно для колоночной розкладки.

Однак його мінусами є менша гнучкість через те, що елементи не можна рухати довільно, і тому що можливість його застосовувати може залежати від порядку елементів в HTML-розмітці.

Ця стаття - частина знаходиться в процесі написання циклу під робочою назвою "Підручник". Я рекомендую ознайомитися і з іншими статтями, які можна знайти в категорії " Підручник ", Де вони зараз зібрані в зворотному хронологічному порядку.

Розкладка в CSS: float

Довга епопея з написанням статті про властивості "float" завершена. Нехай часу пішло багато, але мені здається, що мені вдалося максимально дохідливо звести все різноманіття поводжень цього потужного і трохи дивного властивості в одну загальну систему.

Крім того, ця стаття містить рекордну кількість ілюстрацій серед всього " підручника ":-)

Доля властивості "float" в CSS злегка схожа на долю тега "table" в HTML: ні те, ні інше взагалі не замислювалося як засіб створення колонок і взагалі розкладки елементів. Однак через певні недосконалостей механізму позиціонування float використовується для цієї мети дуже широко. А то, що придумувався він для іншого, часто проявляється різними неочевидними ефектами. Однак перед тим, як їх показати, я все ж розповім, як float'и можна застосовувати для розкладки.

На самому початку - невелике зауваження про терміни. У російській мові не склалося жодного відомого терміна для цього інструменту (поки, принаймні). Тому я вважаю за краще писати його в вихідному написанні - "float". Читається це приблизно як "флоут" (ламати вилиці вимовою "флоат" не потрібно). Заодно тут же прошу пробачити мені такі вольності як "заfloat'іть", "пріfloat'нутий" і т.п. :-)

Принцип роботи

Як і позиціонування, float використовується для того, щоб рухати бокси. Але на відміну від позиціонування, яким можна рухати бокси практично довільно, все, що може float - це зрушити елемент до однієї зі сторін потоку , Правою чи лівою.

При цьому сам бокс і наступні за ним в потоці набувають цікаве поведінку:

При цьому сам бокс і наступні за ним в потоці набувають цікаве поведінку:

  1. Float'нутий бокс зміщується по горизонталі і прилипає до однієї зі сторін батька.
  2. Float'нутий бокс перестає лунати на всю ширину батьківського боксу-контейнера (як це відбувається з блоками в потоці). З його непріжатой до батькові чи матері вільної сторони з'являється вільне місце.
  3. Наступні за ним блокові бокси підтягуються вгору і займають його місце, як якщо б float'нутого боксу в потоці не було.
  4. Рядкові ж бокси всередині посунувши наверх блоків починають обтікати float'нутий бокс з вільною боку.

Хочу ще раз підкреслити очевидну відразу річ: сама коробка блоку, наступного за float'ом, підлазить під нього і займають всю ширину потоку, а ось текст всередині цього блоку зміщується в бік і обтікає float.

Далі цікаво, як себе ведуть float'нутие в одну сторону бокси, які йдуть один за іншим. В цьому випадку наступний бокс буде намагатися вміститися збоку від попереднього, з його вільної сторони. І тільки якщо йому там не буде достатньо місця, тоді він зміститься нижче і буде намагатися вміститися вже там.

Є ще один маленький технічний аспект, що не обов'язковий для розуміння всієї "механіки". Заfloat'іть можна як блокові бокси, так і малі. При цьому малі тут же автоматично стають блоковими. Тобто, писати display: block; для float'а зайве.

З двох описаних особливостей float'ов - притискання до краю і стикування збоку один одного - випливають два основних застосування їх в розкладці:

  • поділ сторінки на колонки
  • горизонтально розташовані меню

колонки

Колонки - це коли блоки тексту розташовані поруч один з одним і мають однакову висоту.

Все колоночного розкладки я буду розглядати на ось такому простому HTML'ном коді з двома блоками:

<Body> <div id = "sidebar"> ... </ div> <div id = "content"> ... </ div> </ body>

Відразу варто сказати, що робити колонки в розтяжному по ширині контейнері складніше, ніж із заданою шириною. Тут є два принципово різних підходи, які підходять для різних випадків.

пропорційна ширина

пропорційна ширина

Якщо потрібно, щоб ширина колонок змінювалася пропорційно, при зміні ширини сторінки, то підхід такий:

#content {float: right; width: 70%; } #Sidebar {float: left; width: 30%; }

Тобто два блоки float'ятся поруч в різні боки, а їх ширина ділиться в потрібному процентному співвідношенні. Цей спосіб дозволяє легко поміняти колонки місцями - просто помінявши значення right і left.

Розтягування тільки однієї колонки

Якщо потрібно, щоб змінювалася тільки ширина основної колонки, то попередній спосіб не підходить. Справа в тому, що в CSS, на жаль, не можна безпосередньо сформулювати таку річ як "вся доступна ширина мінус конкретне число".

Тепер звернемося до однієї з попередніх статей про блоки в потоці , Де я згадав про одну їх корисної особливості автоматично укладатися по ширині в розмір батьківського боксу. Тобто, якщо блоку в прямому потоці задати, скажімо, лівий margin, то його ширина відповідно скоротиться. А це саме те поведінка, якого ми хотіли добитися від однієї з колонок.

А це саме те поведінка, якого ми хотіли добитися від однієї з колонок

Отже, для потрібного нам ефекту ми дамо основного блоку лівий margin, щоб він стиснувся направо, а бічну панель заfloat'ім на це місце:

#sidebar {float: left; width: 200px; } #Content {margin-left: 200px; }

Але у другого способу є один дуже серйозний недолік. Зверніть увагу, що в початковому HTML блок "sidebar" йде до блоку "content" з основним вмістом. Не потрібно думати, що так зроблено випадково :-). Так зроблено спеціально, тому що інакше цей самий другий спосіб з накладенням колонки поверх margin'а не працював би.

Так зроблено спеціально, тому що інакше цей самий другий спосіб з накладенням колонки поверх margin'а не працював би

Як я написав на початку статті, float'и зсуваються тільки в сторону і дають місце наступним блоками, які з'їжджають наверх. Тому принципово, щоб "sidebar" був уже нагорі, і тоді основний блок під'їде до нього. Якщо "sidebar" йде після основного блоку, то він так і залишиться нижче, і ні на які колонки це схоже не буде.

Це дійсно погано, тому що перекреслює одну з основних ідей CSS: відділення оформлення від змісту. Виходить, що ми захотіли змінити тільки дизайн, а якщо блоки розташовані "не так", то доведеться лізти ще і в HTML-шаблони. Крім того, з точки зору структури можуть бути свої вагомі підстави розташовувати блоки так, а не інакше. Наприклад щоб користувач міг почати читати основний текст сторінки, не чекаючи завантаження навігації.

фіксована ширина

Все різко спрощується, коли колонки поміщаються в фіксовану ширину контейнера. В цьому випадку краще всього використовувати перший спосіб (float'іть все колонки), і ширину вже можна задавати не тільки у відсотках, а й у чому хочете, оскільки її можна точно обчислити.

Висота колонок

Знову-таки, я далеко не випадково "відрізав" на картинках нижню частину блоків :-). Інакше б вони як колонки зовсім не виглядали, тому що, як неважко переконатися, якщо застосувати ті фрагменти CSS, що я привів, і розфарбувати колонки різними кольорами, то їх висота виявляється різною. Вона залежить від кількості вмісту в цих блоках.

Цей негарний ефект можна обійти кількома способами.

Перший спосіб називається "Помилкові колонки" ( "Faux columns"), опублікований в авторитетному веб-журналі A List Apart у вересні 2004 року і з тих пір користується великою популярністю. Всім рекомендую прочитати або оригінал , або російський переклад . Однак якщо ви сьогодні не в настрої клікати, то ось коротко його суть.

Замість того, щоб призначати фон самим колонок, вони залишаються прозорими, а ось їх контейнеру призначається фонова картинка шириною у весь контейнер і повторювана по вертикалі. Частини цієї картинки, що знаходяться під різними колонками, фарбуються в різні кольори і при повторенні вниз це дає потрібний візуальний ефект.

Частини цієї картинки, що знаходяться під різними колонками, фарбуються в різні кольори і при повторенні вниз це дає потрібний візуальний ефект

Що в помилкових колонках чудово - так це те, що ви можете не обмежувати себе на фонової зображенні рівними квітами. На ній, наприклад можна намалювати ефект тіні між колонками, що повторюються горизонтальні смужки у вигляді фону, орнамент по краях.

Недолік же способу полягає в тому, що оскільки у фонової картинки є тільки один розмір, її не можна застосовувати для пропорційно розтягуються колонок, так як картинка тягти не буде (тут я помилився; все цілком можна застосувати, читайте коментар ). А ось для випадку, коли одна з колонок фіксована по ширині, фон пристосувати можна (цей випадок, до речі, в "Faux columns" не розглянутий).

Суть полягає в тому, щоб помістити фонову картинку тільки під ту колонку, ширина якої відома. Решта місце буде зайнято фоновим кольором контейнера, а не картинкою.

Візьмемо наш приклад і зробимо колонку "sidebar" справа шириною 200 пікселів, а "content" нехай розтягується. Для "sidebar" підготуємо картинку розмірами 200х1 наприклад рівного синього відтінку. А під "content" відведемо жовтуватий.

У стилях це виглядає так:

#sidebar {float: right; width: 200px; } #Content {margin-right: 200px; } Body {background: url (bg.png) #FFD right top repeat-y; }

Єдине правило для контейнера (body) задає всі поведінку фону:

  • вказується URL картинки (bg.png)
  • колір фону в тих місцях, де її не буде (#FFD)
  • становище картинки притиснутою до правого краю (right top)
  • повторення картинки вниз (repeat-y)

У реальному прикладі в CSS ще була пара правил для кольору букв і боротьби з межами, які зараз не істотні.

Інший спосіб зрівнювання колонок по висоті був описаний недавно і вже сильно відомий, оскільки зручний.

Інший спосіб зрівнювання колонок по висоті був   описаний недавно   і вже сильно відомий, оскільки зручний

Ідея його полягає в тому, щоб нерівність висот колонок заховати, неймовірно подовживши їх вниз, щоб їх кінці були за межами реального вмісту сторінки. Домагаються цього тим, що спочатку ставлять колонкам дуже великий відступ (padding) вниз, який зафарбовується кольором фону. А щоб все інше вміст теж не порушувався туди далеко, колонкам призначається негативна межа (margin) такого ж розміру:

#content, #sidebar {padding-bottom: 32767px; margin-bottom: -32767px; }

Дивне число обумовлено тим, що це максимум, який може дозволити браузер Safari. Насправді воно не настільки дивне. Кому цікаво, це максимальне знакове ціле число, якщо представляти його 16 бітами.

У підсумку все, що йде за колонками зміщується і знаходиться прямо під вмістом найдовшої з них, а колонки подовжуються вниз. Негарно одне - через довгих колонок сама сторінка стає такою ж довгою. Щоб з цим боротися, треба їх контейнеру проставити властивість overflow: hidden, яке змушує контейнер просто відрізати і не показувати те, що виходить за його межі.

У мого прикладу, який я взяв на самому початку, є, правда, одна заковика. Там колонки лежать прямо в body. А якщо body проставити overflow: hidden, то браузери скасовують скролінг у сторінки начисто. Навіть якщо реальний вміст вище вікна. Тому колонки треба загорнути в ще один елемент, наприклад div. Але справедливості заради треба сказати, що на практиці колонки і так бувають у що-небудь вже загорнуті.

засада

Куди ж без неї :-). Як я не особливо прозоро натякнув на самому початку, оскільки float'и не вигадували як засіб створення колонок, це обов'язково вилізе чимось потворним і відгукнеться збільшенням витрати анальгіну (деякі вважають за краще темпалгин або парацетамол).

Причому "вилізе" - в прямому сенсі. Давайте трохи посунемо наш "голий" приклад в сторону реальності, додавши над колонками шапку і внизу якийсь теж блок з текстом.

<Body> <div id = "header"> ... </ div> <div id = "main"> <div id = "content"> ... </ div> <div id = "sidebar">. .. </ div> </ div> <div id = "footer"> ... </ div> </ body>

Для простоти виберемо нехитрий стовпчик дизайн з фіксованою шириною. Шапку і нижній блок зробимо синіми з білими буквами, основний вміст білим, а додаткову колонку теж синьою, але трохи світліше. Кольори колонкам задамо способом "Faux columns".

/ * Розкладка в колонки * / body {width: 600px; margin: 0 auto; } #Content {float: left; width: 450px; } #Sidebar {float: right; width: 150px; } / * Кольори * / #main {background: url (bg.png) right top repeat-y; } #Header, #footer {background: # 238; color: white; }

Всякі відступи і шрифти я знову опустив для простоти сприйняття. Додамо тестового тексту і запускаємо:

Хм ... Ну, колонки, в загальному, навіть можна розгледіти! Чи не причепишся! Утім, як не крути, але виглядає все не так, як задумано, а навіть можна сказати, все перетворилося в якусь кашу з квітів і букв.

Щоб зрозуміти, чому так відбувається, треба згадати опис того, як працює float. А саме, що блоки, що йдуть за float'амі перестають ці float'и помічати і підтягуються вгору. Більш того, сам контейнер, в якому float'и знаходяться, теж перестає їх помічати і float'нутие блоки провалюються через низ контейнера, якщо він закінчуватися раніше.

Тепер подивимося на наш код. Обидва float'нутих блоку "content" і "sidebar" знаходяться всередині блоку "main". І більше нічого в "main" немає. А раз йому нічого більше утримувати, то його висота схлопивается в нуль! Тому й не видно на зображенні ні білого фону "content", ні світло-синього фону "sidebar", тому що ці кольори призначені у вигляді фону "main".

Далі - "footer". Він, підкоряючись все тим же правилом, теж не бачить float'нутих блоків і підтягується наверх прямо до самого заголовку (оскільки "main" - нульовий висоти). Але в "footer" є текст. Текст цей вже повинен обтікати float'и: справа "content" і зліва "sidebar". Між колонками місця не залишилося, тому текст може початися тільки під одним з колонок, яка перша скінчиться. Там він і є. Таким чином, "footer", підтягшись під заголовок, триває вниз, поки не закінчиться весь його текст. І весь цей синій фон, що нижче заголовка - це "footer" і є.

Навіщо така складність

Описане поведінка повинна вселяти подив. Навіщо треба було вигадувати такі складності: розділити поняття блоку так, щоб кольори і рамки наверх, а текст - на місці? Але сенс, звичайно, є. Це, поряд зі спаданням кордонів , Спроба змусити боксову модель CSS нормально вести себе в умовах простого потоку тексту. Детальний класичне пояснення цьому феномену є все у того ж Еріка Мейєра в статті " Containing Floats "(Англійською). Постараюся коротко передати суть.

Уявіть собі звичайний потік абзаців - блоків з текстом - без всякого позиціонування. В одному з абзаців зустрічається картинка, яку хочеться зрушити, скажімо, вліво, щоб текст її обтікав. Таке раніше в HTML досягалося властивістю align = "left", але в дусі винесення оформлення з HTML в стилі, для цієї функції як раз і придумали властивість float. Тобто замість align цій картинці приписується float: left.

Нехай зсувається картинка займає по висоті більше, ніж текст абзацу. Якщо вона буде розтягувати свій абзац і відсувати початок наступного нижче, то це буде виглядати непривабливо через збільшеного відстані між рядками сусідніх абзаців. Тому вона і провалюється через усі межі блоків, зберігаючи між ними гарні відступи, а текст її обтікає.

рішення

Отже, поведінка з проваленням зрозуміло, але воно зручно для непозіціонірованного тексту, а для розкладки - зовсім незручно. Існує два підходи усуває обидва прояви цієї властивості: підтягування наступних боксів наверх і провалювання через низ контейнера.

Для усунення підтягування блоків існує спеціальне властивість - clear. Воно змушує елемент зсуватися вниз, поки збоку від нього не залишиться float'ов. Причому можна управляти, з якого саме боку не повинно бути float'ов:

clear: left стежить, щоб float'ов не було зліва clear: right стежить, щоб float'ов не було справа clear: both стежить, щоб float'ов не було з обох сторін

Таким чином, якщо ми скажемо нашому "footer" у:

#footer {clear: both; }

... щоб зліва і праворуч від нього не було float'нутих колонок, то він зрушить вниз якраз туди, де вони обидві закінчуються.

Але це не вирішує іншої проблеми: того, що float'и провалюються через "main", і той схлопивается, в результаті чого не видно колоночного фону, який йому призначено. Провалювання можна перемогти двома способами.

Можна явно спозиционировать контейнер якимось чином. Наскільки я розумію логіку специфікації, поведінка провалювання вважається логічним тільки в простому потоці. В інших випадках воно тільки заважає. І так воно і є, як ми переконалися. Тобто досить призначити контейнеру наприклад position: absolute або float: left і нічого не буде провалюється, контейнер буде повністю укладати в себе і текст, і float'и. У нашому випадку (і в більшості випадків, до речі) це рішення цілком підійде.

Інший цікавий спосіб пов'язаний з побічним ефектом властивості overflow. Само по собі воно призначене для того, щоб визначати, як буде вести себе контейнер при переповненні, коли не може вмістити свій вміст. У нього є чотири значення:

visible вміст переходить через край і його нормально видно (це поведінка за умовчанням) hidden вміст відсікається за межами контейнера і його там ніяк не видно auto якщо вміст переповнює контейнер, у нього з'являється скроллбар, що дозволяє прокручувати вміст, якщо ні - не з'являється scroll схоже на auto, тільки скроллбар у контейнера є завжди, навіть коли вміст його не наповнюється

Так ось побічний ефект полягає в тому, що якщо контейнеру поставити будь-overflow, крім звичайного visible, він раптом розтягується і укладає в себе float'и, які в ньому сидять, усуваючи провалювання.

Який же overflow використовувати? Відразу відпадає scroll - завжди висять скроллбар явно не потрібні. Залишаються auto і hidden, які відрізняються тільки тим, з'являється скроллбар при переповненні чи ні. Але у нас ніякого переповнення немає, навпаки, цією властивістю ми змусили контейнер додатково розтягнутися, щоб він охоплював всі свої елементи. Тому використовувати можна будь-яке значення.

Я забобонно намагаюся використовувати hidden, щоб не з'являлося скроллбар, якщо через якихось глюків переповнення раптом виникне.

Я забобонно намагаюся використовувати hidden, щоб не з'являлося скроллбар, якщо через якихось глюків переповнення раптом виникне

У рішення з overflow є одна заковика, пов'язана з поведінкою Деякого Браузера ™. Воно працює тільки якщо контейнеру явно призначені ширина або висота. Через це їм іноді незручно користуватися, коли вам потрібні автоматичні розміри, а не жорсткі.

Отже, в підсумку, щоб виправити наш приклад з колонками, треба зробити так:

#main {width: 100%; overflow: hidden; }

До речі! Якби для малювання фону під колонками я використав не faux columns, а спосіб з довгим padding'ом, то він би зажадав використовувати overflow: hidden для "main", що заодно вирішує і проблему з проваленням. Але як би тоді я про це розповідав?

Розкладка в CSS: float

Довга епопея з написанням статті про властивості "float" завершена. Нехай часу пішло багато, але мені здається, що мені вдалося максимально дохідливо звести все різноманіття поводжень цього потужного і трохи дивного властивості в одну загальну систему.

Крім того, ця стаття містить рекордну кількість ілюстрацій серед всього " підручника ":-)

Доля властивості "float" в CSS злегка схожа на долю тега "table" в HTML: ні те, ні інше взагалі не замислювалося як засіб створення колонок і взагалі розкладки елементів. Однак через певні недосконалостей механізму позиціонування float використовується для цієї мети дуже широко. А то, що придумувався він для іншого, часто проявляється різними неочевидними ефектами. Однак перед тим, як їх показати, я все ж розповім, як float'и можна застосовувати для розкладки.

На самому початку - невелике зауваження про терміни. У російській мові не склалося жодного відомого терміна для цього інструменту (поки, принаймні). Тому я вважаю за краще писати його в вихідному написанні - "float". Читається це приблизно як "флоут" (ламати вилиці вимовою "флоат" не потрібно). Заодно тут же прошу пробачити мені такі вольності як "заfloat'іть", "пріfloat'нутий" і т.п. :-)

Принцип роботи

Як і позиціонування, float використовується для того, щоб рухати бокси. Але на відміну від позиціонування, яким можна рухати бокси практично довільно, все, що може float - це зрушити елемент до однієї зі сторін потоку , Правою чи лівою.

При цьому сам бокс і наступні за ним в потоці набувають цікаве поведінку:

При цьому сам бокс і наступні за ним в потоці набувають цікаве поведінку:

  1. Float'нутий бокс зміщується по горизонталі і прилипає до однієї зі сторін батька.
  2. Float'нутий бокс перестає лунати на всю ширину батьківського боксу-контейнера (як це відбувається з блоками в потоці). З його непріжатой до батькові чи матері вільної сторони з'являється вільне місце.
  3. Наступні за ним блокові бокси підтягуються вгору і займають його місце, як якщо б float'нутого боксу в потоці не було.
  4. Рядкові ж бокси всередині посунувши наверх блоків починають обтікати float'нутий бокс з вільною боку.

Хочу ще раз підкреслити очевидну відразу річ: сама коробка блоку, наступного за float'ом, підлазить під нього і займають всю ширину потоку, а ось текст всередині цього блоку зміщується в бік і обтікає float.

Далі цікаво, як себе ведуть float'нутие в одну сторону бокси, які йдуть один за іншим. В цьому випадку наступний бокс буде намагатися вміститися збоку від попереднього, з його вільної сторони. І тільки якщо йому там не буде достатньо місця, тоді він зміститься нижче і буде намагатися вміститися вже там.

Є ще один маленький технічний аспект, що не обов'язковий для розуміння всієї "механіки". Заfloat'іть можна як блокові бокси, так і малі. При цьому малі тут же автоматично стають блоковими. Тобто, писати display: block; для float'а зайве.

З двох описаних особливостей float'ов - притискання до краю і стикування збоку один одного - випливають два основних застосування їх в розкладці:

  • поділ сторінки на колонки
  • горизонтально розташовані меню

колонки

Колонки - це коли блоки тексту розташовані поруч один з одним і мають однакову висоту.

Все колоночного розкладки я буду розглядати на ось такому простому HTML'ном коді з двома блоками:

<Body> <div id = "sidebar"> ... </ div> <div id = "content"> ... </ div> </ body>

Відразу варто сказати, що робити колонки в розтяжному по ширині контейнері складніше, ніж із заданою шириною. Тут є два принципово різних підходи, які підходять для різних випадків.

пропорційна ширина

пропорційна ширина

Якщо потрібно, щоб ширина колонок змінювалася пропорційно, при зміні ширини сторінки, то підхід такий:

#content {float: right; width: 70%; } #Sidebar {float: left; width: 30%; }

Тобто два блоки float'ятся поруч в різні боки, а їх ширина ділиться в потрібному процентному співвідношенні. Цей спосіб дозволяє легко поміняти колонки місцями - просто помінявши значення right і left.

Розтягування тільки однієї колонки

Якщо потрібно, щоб змінювалася тільки ширина основної колонки, то попередній спосіб не підходить. Справа в тому, що в CSS, на жаль, не можна безпосередньо сформулювати таку річ як "вся доступна ширина мінус конкретне число".

Тепер звернемося до однієї з попередніх статей про блоки в потоці , Де я згадав про одну їх корисної особливості автоматично укладатися по ширині в розмір батьківського боксу. Тобто, якщо блоку в прямому потоці задати, скажімо, лівий margin, то його ширина відповідно скоротиться. А це саме те поведінка, якого ми хотіли добитися від однієї з колонок.

А це саме те поведінка, якого ми хотіли добитися від однієї з колонок

Отже, для потрібного нам ефекту ми дамо основного блоку лівий margin, щоб він стиснувся направо, а бічну панель заfloat'ім на це місце:

#sidebar {float: left; width: 200px; } #Content {margin-left: 200px; }

Але у другого способу є один дуже серйозний недолік. Зверніть увагу, що в початковому HTML блок "sidebar" йде до блоку "content" з основним вмістом. Не потрібно думати, що так зроблено випадково :-). Так зроблено спеціально, тому що інакше цей самий другий спосіб з накладенням колонки поверх margin'а не працював би.

Так зроблено спеціально, тому що інакше цей самий другий спосіб з накладенням колонки поверх margin'а не працював би

Як я написав на початку статті, float'и зсуваються тільки в сторону і дають місце наступним блоками, які з'їжджають наверх. Тому принципово, щоб "sidebar" був уже нагорі, і тоді основний блок під'їде до нього. Якщо "sidebar" йде після основного блоку, то він так і залишиться нижче, і ні на які колонки це схоже не буде.

Це дійсно погано, тому що перекреслює одну з основних ідей CSS: відділення оформлення від змісту. Виходить, що ми захотіли змінити тільки дизайн, а якщо блоки розташовані "не так", то доведеться лізти ще і в HTML-шаблони. Крім того, з точки зору структури можуть бути свої вагомі підстави розташовувати блоки так, а не інакше. Наприклад щоб користувач міг почати читати основний текст сторінки, не чекаючи завантаження навігації.

фіксована ширина

Все різко спрощується, коли колонки поміщаються в фіксовану ширину контейнера. В цьому випадку краще всього використовувати перший спосіб (float'іть все колонки), і ширину вже можна задавати не тільки у відсотках, а й у чому хочете, оскільки її можна точно обчислити.

Висота колонок

Знову-таки, я далеко не випадково "відрізав" на картинках нижню частину блоків :-). Інакше б вони як колонки зовсім не виглядали, тому що, як неважко переконатися, якщо застосувати ті фрагменти CSS, що я привів, і розфарбувати колонки різними кольорами, то їх висота виявляється різною. Вона залежить від кількості вмісту в цих блоках.

Цей негарний ефект можна обійти кількома способами.

Перший спосіб називається "Помилкові колонки" ( "Faux columns"), опублікований в авторитетному веб-журналі A List Apart у вересні 2004 року і з тих пір користується великою популярністю. Всім рекомендую прочитати або оригінал , або російський переклад . Однак якщо ви сьогодні не в настрої клікати, то ось коротко його суть.

Замість того, щоб призначати фон самим колонок, вони залишаються прозорими, а ось їх контейнеру призначається фонова картинка шириною у весь контейнер і повторювана по вертикалі. Частини цієї картинки, що знаходяться під різними колонками, фарбуються в різні кольори і при повторенні вниз це дає потрібний візуальний ефект.

Частини цієї картинки, що знаходяться під різними колонками, фарбуються в різні кольори і при повторенні вниз це дає потрібний візуальний ефект

Що в помилкових колонках чудово - так це те, що ви можете не обмежувати себе на фонової зображенні рівними квітами. На ній, наприклад можна намалювати ефект тіні між колонками, що повторюються горизонтальні смужки у вигляді фону, орнамент по краях.

Недолік же способу полягає в тому, що оскільки у фонової картинки є тільки один розмір, її не можна застосовувати для пропорційно розтягуються колонок, так як картинка тягти не буде (тут я помилився; все цілком можна застосувати, читайте коментар ). А ось для випадку, коли одна з колонок фіксована по ширині, фон пристосувати можна (цей випадок, до речі, в "Faux columns" не розглянутий).

Суть полягає в тому, щоб помістити фонову картинку тільки під ту колонку, ширина якої відома. Решта місце буде зайнято фоновим кольором контейнера, а не картинкою.

Візьмемо наш приклад і зробимо колонку "sidebar" справа шириною 200 пікселів, а "content" нехай розтягується. Для "sidebar" підготуємо картинку розмірами 200х1 наприклад рівного синього відтінку. А під "content" відведемо жовтуватий.

У стилях це виглядає так:

#sidebar {float: right; width: 200px; } #Content {margin-right: 200px; } Body {background: url (bg.png) #FFD right top repeat-y; }

Єдине правило для контейнера (body) задає всі поведінку фону:

  • вказується URL картинки (bg.png)
  • колір фону в тих місцях, де її не буде (#FFD)
  • становище картинки притиснутою до правого краю (right top)
  • повторення картинки вниз (repeat-y)

У реальному прикладі в CSS ще була пара правил для кольору букв і боротьби з межами, які зараз не істотні.

Інший спосіб зрівнювання колонок по висоті був описаний недавно і вже сильно відомий, оскільки зручний.

Інший спосіб зрівнювання колонок по висоті був   описаний недавно   і вже сильно відомий, оскільки зручний

Ідея його полягає в тому, щоб нерівність висот колонок заховати, неймовірно подовживши їх вниз, щоб їх кінці були за межами реального вмісту сторінки. Домагаються цього тим, що спочатку ставлять колонкам дуже великий відступ (padding) вниз, який зафарбовується кольором фону. А щоб все інше вміст теж не порушувався туди далеко, колонкам призначається негативна межа (margin) такого ж розміру:

#content, #sidebar {padding-bottom: 32767px; margin-bottom: -32767px; }

Дивне число обумовлено тим, що це максимум, який може дозволити браузер Safari. Насправді воно не настільки дивне. Кому цікаво, це максимальне знакове ціле число, якщо представляти його 16 бітами.

У підсумку все, що йде за колонками зміщується і знаходиться прямо під вмістом найдовшої з них, а колонки подовжуються вниз. Негарно одне - через довгих колонок сама сторінка стає такою ж довгою. Щоб з цим боротися, треба їх контейнеру проставити властивість overflow: hidden, яке змушує контейнер просто відрізати і не показувати те, що виходить за його межі.

У мого прикладу, який я взяв на самому початку, є, правда, одна заковика. Там колонки лежать прямо в body. А якщо body проставити overflow: hidden, то браузери скасовують скролінг у сторінки начисто. Навіть якщо реальний вміст вище вікна. Тому колонки треба загорнути в ще один елемент, наприклад div. Але справедливості заради треба сказати, що на практиці колонки і так бувають у що-небудь вже загорнуті.

засада

Куди ж без неї :-). Як я не особливо прозоро натякнув на самому початку, оскільки float'и не вигадували як засіб створення колонок, це обов'язково вилізе чимось потворним і відгукнеться збільшенням витрати анальгіну (деякі вважають за краще темпалгин або парацетамол).

Причому "вилізе" - в прямому сенсі. Давайте трохи посунемо наш "голий" приклад в сторону реальності, додавши над колонками шапку і внизу якийсь теж блок з текстом.

<Body> <div id = "header"> ... </ div> <div id = "main"> <div id = "content"> ... </ div> <div id = "sidebar">. .. </ div> </ div> <div id = "footer"> ... </ div> </ body>

Для простоти виберемо нехитрий стовпчик дизайн з фіксованою шириною. Шапку і нижній блок зробимо синіми з білими буквами, основний вміст білим, а додаткову колонку теж синьою, але трохи світліше. Кольори колонкам задамо способом "Faux columns".

/ * Розкладка в колонки * / body {width: 600px; margin: 0 auto; } #Content {float: left; width: 450px; } #Sidebar {float: right; width: 150px; } / * Кольори * / #main {background: url (bg.png) right top repeat-y; } #Header, #footer {background: # 238; color: white; }

Всякі відступи і шрифти я знову опустив для простоти сприйняття. Додамо тестового тексту і запускаємо:

Хм ... Ну, колонки, в загальному, навіть можна розгледіти! Чи не причепишся! Утім, як не крути, але виглядає все не так, як задумано, а навіть можна сказати, все перетворилося в якусь кашу з квітів і букв.

Щоб зрозуміти, чому так відбувається, треба згадати опис того, як працює float. А саме, що блоки, що йдуть за float'амі перестають ці float'и помічати і підтягуються вгору. Більш того, сам контейнер, в якому float'и знаходяться, теж перестає їх помічати і float'нутие блоки провалюються через низ контейнера, якщо він закінчуватися раніше.

Тепер подивимося на наш код. Обидва float'нутих блоку "content" і "sidebar" знаходяться всередині блоку "main". І більше нічого в "main" немає. А раз йому нічого більше утримувати, то його висота схлопивается в нуль! Тому й не видно на зображенні ні білого фону "content", ні світло-синього фону "sidebar", тому що ці кольори призначені у вигляді фону "main".

Далі - "footer". Він, підкоряючись все тим же правилом, теж не бачить float'нутих блоків і підтягується наверх прямо до самого заголовку (оскільки "main" - нульовий висоти). Але в "footer" є текст. Текст цей вже повинен обтікати float'и: справа "content" і зліва "sidebar". Між колонками місця не залишилося, тому текст може початися тільки під одним з колонок, яка перша скінчиться. Там він і є. Таким чином, "footer", підтягшись під заголовок, триває вниз, поки не закінчиться весь його текст. І весь цей синій фон, що нижче заголовка - це "footer" і є.

Навіщо така складність

Описане поведінка повинна вселяти подив. Навіщо треба було вигадувати такі складності: розділити поняття блоку так, щоб кольори і рамки наверх, а текст - на місці? Але сенс, звичайно, є. Це, поряд зі спаданням кордонів , Спроба змусити боксову модель CSS нормально вести себе в умовах простого потоку тексту. Детальний класичне пояснення цьому феномену є все у того ж Еріка Мейєра в статті " Containing Floats "(Англійською). Постараюся коротко передати суть.

Уявіть собі звичайний потік абзаців - блоків з текстом - без всякого позиціонування. В одному з абзаців зустрічається картинка, яку хочеться зрушити, скажімо, вліво, щоб текст її обтікав. Таке раніше в HTML досягалося властивістю align = "left", але в дусі винесення оформлення з HTML в стилі, для цієї функції як раз і придумали властивість float. Тобто замість align цій картинці приписується float: left.

Нехай зсувається картинка займає по висоті більше, ніж текст абзацу. Якщо вона буде розтягувати свій абзац і відсувати початок наступного нижче, то це буде виглядати непривабливо через збільшеного відстані між рядками сусідніх абзаців. Тому вона і провалюється через усі межі блоків, зберігаючи між ними гарні відступи, а текст її обтікає.

рішення

Отже, поведінка з проваленням зрозуміло, але воно зручно для непозіціонірованного тексту, а для розкладки - зовсім незручно. Існує два підходи усуває обидва прояви цієї властивості: підтягування наступних боксів наверх і провалювання через низ контейнера.

Для усунення підтягування блоків існує спеціальне властивість - clear. Воно змушує елемент зсуватися вниз, поки збоку від нього не залишиться float'ов. Причому можна управляти, з якого саме боку не повинно бути float'ов:

clear: left стежить, щоб float'ов не було зліва clear: right стежить, щоб float'ов не було справа clear: both стежить, щоб float'ов не було з обох сторін

Таким чином, якщо ми скажемо нашому "footer" у:

#footer {clear: both; }

... щоб зліва і праворуч від нього не було float'нутих колонок, то він зрушить вниз якраз туди, де вони обидві закінчуються.

Але це не вирішує іншої проблеми: того, що float'и провалюються через "main", і той схлопивается, в результаті чого не видно колоночного фону, який йому призначено. Провалювання можна перемогти двома способами.

Можна явно спозиционировать контейнер якимось чином. Наскільки я розумію логіку специфікації, поведінка провалювання вважається логічним тільки в простому потоці. В інших випадках воно тільки заважає. І так воно і є, як ми переконалися. Тобто досить призначити контейнеру наприклад position: absolute або float: left і нічого не буде провалюється, контейнер буде повністю укладати в себе і текст, і float'и. У нашому випадку (і в більшості випадків, до речі) це рішення цілком підійде.

Інший цікавий спосіб пов'язаний з побічним ефектом властивості overflow. Само по собі воно призначене для того, щоб визначати, як буде вести себе контейнер при переповненні, коли не може вмістити свій вміст. У нього є чотири значення:

visible вміст переходить через край і його нормально видно (це поведінка за умовчанням) hidden вміст відсікається за межами контейнера і його там ніяк не видно auto якщо вміст переповнює контейнер, у нього з'являється скроллбар, що дозволяє прокручувати вміст, якщо ні - не з'являється scroll схоже на auto, тільки скроллбар у контейнера є завжди, навіть коли вміст його не наповнюється

Так ось побічний ефект полягає в тому, що якщо контейнеру поставити будь-overflow, крім звичайного visible, він раптом розтягується і укладає в себе float'и, які в ньому сидять, усуваючи провалювання.

Який же overflow використовувати? Відразу відпадає scroll - завжди висять скроллбар явно не потрібні. Залишаються auto і hidden, які відрізняються тільки тим, з'являється скроллбар при переповненні чи ні. Але у нас ніякого переповнення немає, навпаки, цією властивістю ми змусили контейнер додатково розтягнутися, щоб він охоплював всі свої елементи. Тому використовувати можна будь-яке значення.

Я забобонно намагаюся використовувати hidden, щоб не з'являлося скроллбар, якщо через якихось глюків переповнення раптом виникне.

Я забобонно намагаюся використовувати hidden, щоб не з'являлося скроллбар, якщо через якихось глюків переповнення раптом виникне

У рішення з overflow є одна заковика, пов'язана з поведінкою Деякого Браузера ™. Воно працює тільки якщо контейнеру явно призначені ширина або висота. Через це їм іноді незручно користуватися, коли вам потрібні автоматичні розміри, а не жорсткі.

Отже, в підсумку, щоб виправити наш приклад з колонками, треба зробити так:

#main {width: 100%; overflow: hidden; }

До речі! Якби для малювання фону під колонками я використав не faux columns, а спосіб з довгим padding'ом, то він би зажадав використовувати overflow: hidden для "main", що заодно вирішує і проблему з проваленням. Але як би тоді я про це розповідав?

Розкладка в CSS: float

Довга епопея з написанням статті про властивості "float" завершена. Нехай часу пішло багато, але мені здається, що мені вдалося максимально дохідливо звести все різноманіття поводжень цього потужного і трохи дивного властивості в одну загальну систему.

Крім того, ця стаття містить рекордну кількість ілюстрацій серед всього " підручника ":-)

Доля властивості "float" в CSS злегка схожа на долю тега "table" в HTML: ні те, ні інше взагалі не замислювалося як засіб створення колонок і взагалі розкладки елементів. Однак через певні недосконалостей механізму позиціонування float використовується для цієї мети дуже широко. А то, що придумувався він для іншого, часто проявляється різними неочевидними ефектами. Однак перед тим, як їх показати, я все ж розповім, як float'и можна застосовувати для розкладки.

На самому початку - невелике зауваження про терміни. У російській мові не склалося жодного відомого терміна для цього інструменту (поки, принаймні). Тому я вважаю за краще писати його в вихідному написанні - "float". Читається це приблизно як "флоут" (ламати вилиці вимовою "флоат" не потрібно). Заодно тут же прошу пробачити мені такі вольності як "заfloat'іть", "пріfloat'нутий" і т.п. :-)

Принцип роботи

Як і позиціонування, float використовується для того, щоб рухати бокси. Але на відміну від позиціонування, яким можна рухати бокси практично довільно, все, що може float - це зрушити елемент до однієї зі сторін потоку , Правою чи лівою.

При цьому сам бокс і наступні за ним в потоці набувають цікаве поведінку:

При цьому сам бокс і наступні за ним в потоці набувають цікаве поведінку:

  1. Float'нутий бокс зміщується по горизонталі і прилипає до однієї зі сторін батька.
  2. Float'нутий бокс перестає лунати на всю ширину батьківського боксу-контейнера (як це відбувається з блоками в потоці). З його непріжатой до батькові чи матері вільної сторони з'являється вільне місце.
  3. Наступні за ним блокові бокси підтягуються вгору і займають його місце, як якщо б float'нутого боксу в потоці не було.
  4. Рядкові ж бокси всередині посунувши наверх блоків починають обтікати float'нутий бокс з вільною боку.

Хочу ще раз підкреслити очевидну відразу річ: сама коробка блоку, наступного за float'ом, підлазить під нього і займають всю ширину потоку, а ось текст всередині цього блоку зміщується в бік і обтікає float.

Далі цікаво, як себе ведуть float'нутие в одну сторону бокси, які йдуть один за іншим. В цьому випадку наступний бокс буде намагатися вміститися збоку від попереднього, з його вільної сторони. І тільки якщо йому там не буде достатньо місця, тоді він зміститься нижче і буде намагатися вміститися вже там.

Є ще один маленький технічний аспект, що не обов'язковий для розуміння всієї "механіки". Заfloat'іть можна як блокові бокси, так і малі. При цьому малі тут же автоматично стають блоковими. Тобто, писати display: block; для float'а зайве.

З двох описаних особливостей float'ов - притискання до краю і стикування збоку один одного - випливають два основних застосування їх в розкладці:

  • поділ сторінки на колонки
  • горизонтально розташовані меню

колонки

Колонки - це коли блоки тексту розташовані поруч один з одним і мають однакову висоту.

Все колоночного розкладки я буду розглядати на ось такому простому HTML'ном коді з двома блоками:

<Body> <div id = "sidebar"> ... </ div> <div id = "content"> ... </ div> </ body>

Відразу варто сказати, що робити колонки в розтяжному по ширині контейнері складніше, ніж із заданою шириною. Тут є два принципово різних підходи, які підходять для різних випадків.

пропорційна ширина

пропорційна ширина

Якщо потрібно, щоб ширина колонок змінювалася пропорційно, при зміні ширини сторінки, то підхід такий:

#content {float: right; width: 70%; } #Sidebar {float: left; width: 30%; }

Тобто два блоки float'ятся поруч в різні боки, а їх ширина ділиться в потрібному процентному співвідношенні. Цей спосіб дозволяє легко поміняти колонки місцями - просто помінявши значення right і left.

Розтягування тільки однієї колонки

Якщо потрібно, щоб змінювалася тільки ширина основної колонки, то попередній спосіб не підходить. Справа в тому, що в CSS, на жаль, не можна безпосередньо сформулювати таку річ як "вся доступна ширина мінус конкретне число".

Тепер звернемося до однієї з попередніх статей про блоки в потоці , Де я згадав про одну їх корисної особливості автоматично укладатися по ширині в розмір батьківського боксу. Тобто, якщо блоку в прямому потоці задати, скажімо, лівий margin, то його ширина відповідно скоротиться. А це саме те поведінка, якого ми хотіли добитися від однієї з колонок.

А це саме те поведінка, якого ми хотіли добитися від однієї з колонок

Отже, для потрібного нам ефекту ми дамо основного блоку лівий margin, щоб він стиснувся направо, а бічну панель заfloat'ім на це місце:

#sidebar {float: left; width: 200px; } #Content {margin-left: 200px; }

Але у другого способу є один дуже серйозний недолік. Зверніть увагу, що в початковому HTML блок "sidebar" йде до блоку "content" з основним вмістом. Не потрібно думати, що так зроблено випадково :-). Так зроблено спеціально, тому що інакше цей самий другий спосіб з накладенням колонки поверх margin'а не працював би.

Так зроблено спеціально, тому що інакше цей самий другий спосіб з накладенням колонки поверх margin'а не працював би

Як я написав на початку статті, float'и зсуваються тільки в сторону і дають місце наступним блоками, які з'їжджають наверх. Тому принципово, щоб "sidebar" був уже нагорі, і тоді основний блок під'їде до нього. Якщо "sidebar" йде після основного блоку, то він так і залишиться нижче, і ні на які колонки це схоже не буде.

Це дійсно погано, тому що перекреслює одну з основних ідей CSS: відділення оформлення від змісту. Виходить, що ми захотіли змінити тільки дизайн, а якщо блоки розташовані "не так", то доведеться лізти ще і в HTML-шаблони. Крім того, з точки зору структури можуть бути свої вагомі підстави розташовувати блоки так, а не інакше. Наприклад щоб користувач міг почати читати основний текст сторінки, не чекаючи завантаження навігації.

фіксована ширина

Все різко спрощується, коли колонки поміщаються в фіксовану ширину контейнера. В цьому випадку краще всього використовувати перший спосіб (float'іть все колонки), і ширину вже можна задавати не тільки у відсотках, а й у чому хочете, оскільки її можна точно обчислити.

Висота колонок

Знову-таки, я далеко не випадково "відрізав" на картинках нижню частину блоків :-). Інакше б вони як колонки зовсім не виглядали, тому що, як неважко переконатися, якщо застосувати ті фрагменти CSS, що я привів, і розфарбувати колонки різними кольорами, то їх висота виявляється різною. Вона залежить від кількості вмісту в цих блоках.

Цей негарний ефект можна обійти кількома способами.

Перший спосіб називається "Помилкові колонки" ( "Faux columns"), опублікований в авторитетному веб-журналі A List Apart у вересні 2004 року і з тих пір користується великою популярністю. Всім рекомендую прочитати або оригінал , або російський переклад . Однак якщо ви сьогодні не в настрої клікати, то ось коротко його суть.

Замість того, щоб призначати фон самим колонок, вони залишаються прозорими, а ось їх контейнеру призначається фонова картинка шириною у весь контейнер і повторювана по вертикалі. Частини цієї картинки, що знаходяться під різними колонками, фарбуються в різні кольори і при повторенні вниз це дає потрібний візуальний ефект.

Частини цієї картинки, що знаходяться під різними колонками, фарбуються в різні кольори і при повторенні вниз це дає потрібний візуальний ефект

Що в помилкових колонках чудово - так це те, що ви можете не обмежувати себе на фонової зображенні рівними квітами. На ній, наприклад можна намалювати ефект тіні між колонками, що повторюються горизонтальні смужки у вигляді фону, орнамент по краях.

Недолік же способу полягає в тому, що оскільки у фонової картинки є тільки один розмір, її не можна застосовувати для пропорційно розтягуються колонок, так як картинка тягти не буде (тут я помилився; все цілком можна застосувати, читайте коментар ). А ось для випадку, коли одна з колонок фіксована по ширині, фон пристосувати можна (цей випадок, до речі, в "Faux columns" не розглянутий).

Суть полягає в тому, щоб помістити фонову картинку тільки під ту колонку, ширина якої відома. Решта місце буде зайнято фоновим кольором контейнера, а не картинкою.

Візьмемо наш приклад і зробимо колонку "sidebar" справа шириною 200 пікселів, а "content" нехай розтягується. Для "sidebar" підготуємо картинку розмірами 200х1 наприклад рівного синього відтінку. А під "content" відведемо жовтуватий.

У стилях це виглядає так:

#sidebar {float: right; width: 200px; } #Content {margin-right: 200px; } Body {background: url (bg.png) #FFD right top repeat-y; }

Єдине правило для контейнера (body) задає всі поведінку фону:

  • вказується URL картинки (bg.png)
  • колір фону в тих місцях, де її не буде (#FFD)
  • становище картинки притиснутою до правого краю (right top)
  • повторення картинки вниз (repeat-y)

У реальному прикладі в CSS ще була пара правил для кольору букв і боротьби з межами, які зараз не істотні.

Інший спосіб зрівнювання колонок по висоті був описаний недавно і вже сильно відомий, оскільки зручний.

Інший спосіб зрівнювання колонок по висоті був   описаний недавно   і вже сильно відомий, оскільки зручний

Ідея його полягає в тому, щоб нерівність висот колонок заховати, неймовірно подовживши їх вниз, щоб їх кінці були за межами реального вмісту сторінки. Домагаються цього тим, що спочатку ставлять колонкам дуже великий відступ (padding) вниз, який зафарбовується кольором фону. А щоб все інше вміст теж не порушувався туди далеко, колонкам призначається негативна межа (margin) такого ж розміру:

#content, #sidebar {padding-bottom: 32767px; margin-bottom: -32767px; }

Дивне число обумовлено тим, що це максимум, який може дозволити браузер Safari. Насправді воно не настільки дивне. Кому цікаво, це максимальне знакове ціле число, якщо представляти його 16 бітами.

У підсумку все, що йде за колонками зміщується і знаходиться прямо під вмістом найдовшої з них, а колонки подовжуються вниз. Негарно одне - через довгих колонок сама сторінка стає такою ж довгою. Щоб з цим боротися, треба їх контейнеру проставити властивість overflow: hidden, яке змушує контейнер просто відрізати і не показувати те, що виходить за його межі.

У мого прикладу, який я взяв на самому початку, є, правда, одна заковика. Там колонки лежать прямо в body. А якщо body проставити overflow: hidden, то браузери скасовують скролінг у сторінки начисто. Навіть якщо реальний вміст вище вікна. Тому колонки треба загорнути в ще один елемент, наприклад div. Але справедливості заради треба сказати, що на практиці колонки і так бувають у що-небудь вже загорнуті.

засада

Куди ж без неї :-). Як я не особливо прозоро натякнув на самому початку, оскільки float'и не вигадували як засіб створення колонок, це обов'язково вилізе чимось потворним і відгукнеться збільшенням витрати анальгіну (деякі вважають за краще темпалгин або парацетамол).

Причому "вилізе" - в прямому сенсі. Давайте трохи посунемо наш "голий" приклад в сторону реальності, додавши над колонками шапку і внизу якийсь теж блок з текстом.

<Body> <div id = "header"> ... </ div> <div id = "main"> <div id = "content"> ... </ div> <div id = "sidebar">. .. </ div> </ div> <div id = "footer"> ... </ div> </ body>

Для простоти виберемо нехитрий стовпчик дизайн з фіксованою шириною. Шапку і нижній блок зробимо синіми з білими буквами, основний вміст білим, а додаткову колонку теж синьою, але трохи світліше. Кольори колонкам задамо способом "Faux columns".

/ * Розкладка в колонки * / body {width: 600px; margin: 0 auto; } #Content {float: left; width: 450px; } #Sidebar {float: right; width: 150px; } / * Кольори * / #main {background: url (bg.png) right top repeat-y; } #Header, #footer {background: # 238; color: white; }

Всякі відступи і шрифти я знову опустив для простоти сприйняття. Додамо тестового тексту і запускаємо:

Хм ... Ну, колонки, в загальному, навіть можна розгледіти! Чи не причепишся! Утім, як не крути, але виглядає все не так, як задумано, а навіть можна сказати, все перетворилося в якусь кашу з квітів і букв.

Щоб зрозуміти, чому так відбувається, треба згадати опис того, як працює float. А саме, що блоки, що йдуть за float'амі перестають ці float'и помічати і підтягуються вгору. Більш того, сам контейнер, в якому float'и знаходяться, теж перестає їх помічати і float'нутие блоки провалюються через низ контейнера, якщо він закінчуватися раніше.

Тепер подивимося на наш код. Обидва float'нутих блоку "content" і "sidebar" знаходяться всередині блоку "main". І більше нічого в "main" немає. А раз йому нічого більше утримувати, то його висота схлопивается в нуль! Тому й не видно на зображенні ні білого фону "content", ні світло-синього фону "sidebar", тому що ці кольори призначені у вигляді фону "main".

Далі - "footer". Він, підкоряючись все тим же правилом, теж не бачить float'нутих блоків і підтягується наверх прямо до самого заголовку (оскільки "main" - нульовий висоти). Але в "footer" є текст. Текст цей вже повинен обтікати float'и: справа "content" і зліва "sidebar". Між колонками місця не залишилося, тому текст може початися тільки під одним з колонок, яка перша скінчиться. Там він і є. Таким чином, "footer", підтягшись під заголовок, триває вниз, поки не закінчиться весь його текст. І весь цей синій фон, що нижче заголовка - це "footer" і є.

Навіщо така складність

Описане поведінка повинна вселяти подив. Навіщо треба було вигадувати такі складності: розділити поняття блоку так, щоб кольори і рамки наверх, а текст - на місці? Але сенс, звичайно, є. Це, поряд зі спаданням кордонів , Спроба змусити боксову модель CSS нормально вести себе в умовах простого потоку тексту. Детальний класичне пояснення цьому феномену є все у того ж Еріка Мейєра в статті " Containing Floats "(Англійською). Постараюся коротко передати суть.

Уявіть собі звичайний потік абзаців - блоків з текстом - без всякого позиціонування. В одному з абзаців зустрічається картинка, яку хочеться зрушити, скажімо, вліво, щоб текст її обтікав. Таке раніше в HTML досягалося властивістю align = "left", але в дусі винесення оформлення з HTML в стилі, для цієї функції як раз і придумали властивість float. Тобто замість align цій картинці приписується float: left.

Нехай зсувається картинка займає по висоті більше, ніж текст абзацу. Якщо вона буде розтягувати свій абзац і відсувати початок наступного нижче, то це буде виглядати непривабливо через збільшеного відстані між рядками сусідніх абзаців. Тому вона і провалюється через усі межі блоків, зберігаючи між ними гарні відступи, а текст її обтікає.

рішення

Отже, поведінка з проваленням зрозуміло, але воно зручно для непозіціонірованного тексту, а для розкладки - зовсім незручно. Існує два підходи усуває обидва прояви цієї властивості: підтягування наступних боксів наверх і провалювання через низ контейнера.

Для усунення підтягування блоків існує спеціальне властивість - clear. Воно змушує елемент зсуватися вниз, поки збоку від нього не залишиться float'ов. Причому можна управляти, з якого саме боку не повинно бути float'ов:

clear: left стежить, щоб float'ов не було зліва clear: right стежить, щоб float'ов не було справа clear: both стежить, щоб float'ов не було з обох сторін

Таким чином, якщо ми скажемо нашому "footer" у:

#footer {clear: both; }

... щоб зліва і праворуч від нього не було float'нутих колонок, то він зрушить вниз якраз туди, де вони обидві закінчуються.

Але це не вирішує іншої проблеми: того, що float'и провалюються через "main", і той схлопивается, в результаті чого не видно колоночного фону, який йому призначено. Провалювання можна перемогти двома способами.

Можна явно спозиционировать контейнер якимось чином. Наскільки я розумію логіку специфікації, поведінка провалювання вважається логічним тільки в простому потоці. В інших випадках воно тільки заважає. І так воно і є, як ми переконалися. Тобто досить призначити контейнеру наприклад position: absolute або float: left і нічого не буде провалюється, контейнер буде повністю укладати в себе і текст, і float'и. У нашому випадку (і в більшості випадків, до речі) це рішення цілком підійде.

Інший цікавий спосіб пов'язаний з побічним ефектом властивості overflow. Само по собі воно призначене для того, щоб визначати, як буде вести себе контейнер при переповненні, коли не може вмістити свій вміст. У нього є чотири значення:

visible вміст переходить через край і його нормально видно (це поведінка за умовчанням) hidden вміст відсікається за межами контейнера і його там ніяк не видно auto якщо вміст переповнює контейнер, у нього з'являється скроллбар, що дозволяє прокручувати вміст, якщо ні - не з'являється scroll схоже на auto, тільки скроллбар у контейнера є завжди, навіть коли вміст його не наповнюється

Так ось побічний ефект полягає в тому, що якщо контейнеру поставити будь-overflow, крім звичайного visible, він раптом розтягується і укладає в себе float'и, які в ньому сидять, усуваючи провалювання.

Який же overflow використовувати? Відразу відпадає scroll - завжди висять скроллбар явно не потрібні. Залишаються auto і hidden, які відрізняються тільки тим, з'являється скроллбар при переповненні чи ні. Але у нас ніякого переповнення немає, навпаки, цією властивістю ми змусили контейнер додатково розтягнутися, щоб він охоплював всі свої елементи. Тому використовувати можна будь-яке значення.

Я забобонно намагаюся використовувати hidden, щоб не з'являлося скроллбар, якщо через якихось глюків переповнення раптом виникне.

Я забобонно намагаюся використовувати hidden, щоб не з'являлося скроллбар, якщо через якихось глюків переповнення раптом виникне

У рішення з overflow є одна заковика, пов'язана з поведінкою Деякого Браузера ™. Воно працює тільки якщо контейнеру явно призначені ширина або висота. Через це їм іноді незручно користуватися, коли вам потрібні автоматичні розміри, а не жорсткі.

Отже, в підсумку, щоб виправити наш приклад з колонками, треба зробити так:

#main {width: 100%; overflow: hidden; }

До речі! Якби для малювання фону під колонками я використав не faux columns, а спосіб з довгим padding'ом, то він би зажадав використовувати overflow: hidden для "main", що заодно вирішує і проблему з проваленням. Але як би тоді я про це розповідав?

Розкладка в CSS: float

Довга епопея з написанням статті про властивості "float" завершена. Нехай часу пішло багато, але мені здається, що мені вдалося максимально дохідливо звести все різноманіття поводжень цього потужного і трохи дивного властивості в одну загальну систему.

Крім того, ця стаття містить рекордну кількість ілюстрацій серед всього " підручника ":-)

Доля властивості "float" в CSS злегка схожа на долю тега "table" в HTML: ні те, ні інше взагалі не замислювалося як засіб створення колонок і взагалі розкладки елементів. Однак через певні недосконалостей механізму позиціонування float використовується для цієї мети дуже широко. А то, що придумувався він для іншого, часто проявляється різними неочевидними ефектами. Однак перед тим, як їх показати, я все ж розповім, як float'и можна застосовувати для розкладки.

На самому початку - невелике зауваження про терміни. У російській мові не склалося жодного відомого терміна для цього інструменту (поки, принаймні). Тому я вважаю за краще писати його в вихідному написанні - "float". Читається це приблизно як "флоут" (ламати вилиці вимовою "флоат" не потрібно). Заодно тут же прошу пробачити мені такі вольності як "заfloat'іть", "пріfloat'нутий" і т.п. :-)

Принцип роботи

Як і позиціонування, float використовується для того, щоб рухати бокси. Але на відміну від позиціонування, яким можна рухати бокси практично довільно, все, що може float - це зрушити елемент до однієї зі сторін потоку , Правою чи лівою.

При цьому сам бокс і наступні за ним в потоці набувають цікаве поведінку:

При цьому сам бокс і наступні за ним в потоці набувають цікаве поведінку:

  1. Float'нутий бокс зміщується по горизонталі і прилипає до однієї зі сторін батька.
  2. Float'нутий бокс перестає лунати на всю ширину батьківського боксу-контейнера (як це відбувається з блоками в потоці). З його непріжатой до батькові чи матері вільної сторони з'являється вільне місце.
  3. Наступні за ним блокові бокси підтягуються вгору і займають його місце, як якщо б float'нутого боксу в потоці не було.
  4. Рядкові ж бокси всередині посунувши наверх блоків починають обтікати float'нутий бокс з вільною боку.

Хочу ще раз підкреслити очевидну відразу річ: сама коробка блоку, наступного за float'ом, підлазить під нього і займають всю ширину потоку, а ось текст всередині цього блоку зміщується в бік і обтікає float.

Далі цікаво, як себе ведуть float'нутие в одну сторону бокси, які йдуть один за іншим. В цьому випадку наступний бокс буде намагатися вміститися збоку від попереднього, з його вільної сторони. І тільки якщо йому там не буде достатньо місця, тоді він зміститься нижче і буде намагатися вміститися вже там.

Є ще один маленький технічний аспект, що не обов'язковий для розуміння всієї "механіки". Заfloat'іть можна як блокові бокси, так і малі. При цьому малі тут же автоматично стають блоковими. Тобто, писати display: block; для float'а зайве.

З двох описаних особливостей float'ов - притискання до краю і стикування збоку один одного - випливають два основних застосування їх в розкладці:

  • поділ сторінки на колонки
  • горизонтально розташовані меню

колонки

Колонки - це коли блоки тексту розташовані поруч один з одним і мають однакову висоту.

Все колоночного розкладки я буду розглядати на ось такому простому HTML'ном коді з двома блоками:

<Body> <div id = "sidebar"> ... </ div> <div id = "content"> ... </ div> </ body>

Відразу варто сказати, що робити колонки в розтяжному по ширині контейнері складніше, ніж із заданою шириною. Тут є два принципово різних підходи, які підходять для різних випадків.

пропорційна ширина

пропорційна ширина

Якщо потрібно, щоб ширина колонок змінювалася пропорційно, при зміні ширини сторінки, то підхід такий:

#content {float: right; width: 70%; } #Sidebar {float: left; width: 30%; }

Тобто два блоки float'ятся поруч в різні боки, а їх ширина ділиться в потрібному процентному співвідношенні. Цей спосіб дозволяє легко поміняти колонки місцями - просто помінявши значення right і left.

Розтягування тільки однієї колонки

Якщо потрібно, щоб змінювалася тільки ширина основної колонки, то попередній спосіб не підходить. Справа в тому, що в CSS, на жаль, не можна безпосередньо сформулювати таку річ як "вся доступна ширина мінус конкретне число".

Тепер звернемося до однієї з попередніх статей про блоки в потоці , Де я згадав про одну їх корисної особливості автоматично укладатися по ширині в розмір батьківського боксу. Тобто, якщо блоку в прямому потоці задати, скажімо, лівий margin, то його ширина відповідно скоротиться. А це саме те поведінка, якого ми хотіли добитися від однієї з колонок.

А це саме те поведінка, якого ми хотіли добитися від однієї з колонок

Отже, для потрібного нам ефекту ми дамо основного блоку лівий margin, щоб він стиснувся направо, а бічну панель заfloat'ім на це місце:

#sidebar {float: left; width: 200px; } #Content {margin-left: 200px; }

Але у другого способу є один дуже серйозний недолік. Зверніть увагу, що в початковому HTML блок "sidebar" йде до блоку "content" з основним вмістом. Не потрібно думати, що так зроблено випадково :-). Так зроблено спеціально, тому що інакше цей самий другий спосіб з накладенням колонки поверх margin'а не працював би.

Так зроблено спеціально, тому що інакше цей самий другий спосіб з накладенням колонки поверх margin'а не працював би

Як я написав на початку статті, float'и зсуваються тільки в сторону і дають місце наступним блоками, які з'їжджають наверх. Тому принципово, щоб "sidebar" був уже нагорі, і тоді основний блок під'їде до нього. Якщо "sidebar" йде після основного блоку, то він так і залишиться нижче, і ні на які колонки це схоже не буде.

Це дійсно погано, тому що перекреслює одну з основних ідей CSS: відділення оформлення від змісту. Виходить, що ми захотіли змінити тільки дизайн, а якщо блоки розташовані "не так", то доведеться лізти ще і в HTML-шаблони. Крім того, з точки зору структури можуть бути свої вагомі підстави розташовувати блоки так, а не інакше. Наприклад щоб користувач міг почати читати основний текст сторінки, не чекаючи завантаження навігації.

фіксована ширина

Все різко спрощується, коли колонки поміщаються в фіксовану ширину контейнера. В цьому випадку краще всього використовувати перший спосіб (float'іть все колонки), і ширину вже можна задавати не тільки у відсотках, а й у чому хочете, оскільки її можна точно обчислити.

Висота колонок

Знову-таки, я далеко не випадково "відрізав" на картинках нижню частину блоків :-). Інакше б вони як колонки зовсім не виглядали, тому що, як неважко переконатися, якщо застосувати ті фрагменти CSS, що я привів, і розфарбувати колонки різними кольорами, то їх висота виявляється різною. Вона залежить від кількості вмісту в цих блоках.

Цей негарний ефект можна обійти кількома способами.

Перший спосіб називається "Помилкові колонки" ( "Faux columns"), опублікований в авторитетному веб-журналі A List Apart у вересні 2004 року і з тих пір користується великою популярністю. Всім рекомендую прочитати або оригінал , або російський переклад . Однак якщо ви сьогодні не в настрої клікати, то ось коротко його суть.

Замість того, щоб призначати фон самим колонок, вони залишаються прозорими, а ось їх контейнеру призначається фонова картинка шириною у весь контейнер і повторювана по вертикалі. Частини цієї картинки, що знаходяться під різними колонками, фарбуються в різні кольори і при повторенні вниз це дає потрібний візуальний ефект.

Частини цієї картинки, що знаходяться під різними колонками, фарбуються в різні кольори і при повторенні вниз це дає потрібний візуальний ефект

Що в помилкових колонках чудово - так це те, що ви можете не обмежувати себе на фонової зображенні рівними квітами. На ній, наприклад можна намалювати ефект тіні між колонками, що повторюються горизонтальні смужки у вигляді фону, орнамент по краях.

Недолік же способу полягає в тому, що оскільки у фонової картинки є тільки один розмір, її не можна застосовувати для пропорційно розтягуються колонок, так як картинка тягти не буде (тут я помилився; все цілком можна застосувати, читайте коментар ). А ось для випадку, коли одна з колонок фіксована по ширині, фон пристосувати можна (цей випадок, до речі, в "Faux columns" не розглянутий).

Суть полягає в тому, щоб помістити фонову картинку тільки під ту колонку, ширина якої відома. Решта місце буде зайнято фоновим кольором контейнера, а не картинкою.

Візьмемо наш приклад і зробимо колонку "sidebar" справа шириною 200 пікселів, а "content" нехай розтягується. Для "sidebar" підготуємо картинку розмірами 200х1 наприклад рівного синього відтінку. А під "content" відведемо жовтуватий.

У стилях це виглядає так:

#sidebar {float: right; width: 200px; } #Content {margin-right: 200px; } Body {background: url (bg.png) #FFD right top repeat-y; }

Єдине правило для контейнера (body) задає всі поведінку фону:

  • вказується URL картинки (bg.png)
  • колір фону в тих місцях, де її не буде (#FFD)
  • становище картинки притиснутою до правого краю (right top)
  • повторення картинки вниз (repeat-y)

У реальному прикладі в CSS ще була пара правил для кольору букв і боротьби з межами, які зараз не істотні.

Інший спосіб зрівнювання колонок по висоті був описаний недавно і вже сильно відомий, оскільки зручний.

Інший спосіб зрівнювання колонок по висоті був   описаний недавно   і вже сильно відомий, оскільки зручний

Ідея його полягає в тому, щоб нерівність висот колонок заховати, неймовірно подовживши їх вниз, щоб їх кінці були за межами реального вмісту сторінки. Домагаються цього тим, що спочатку ставлять колонкам дуже великий відступ (padding) вниз, який зафарбовується кольором фону. А щоб все інше вміст теж не порушувався туди далеко, колонкам призначається негативна межа (margin) такого ж розміру:

#content, #sidebar {padding-bottom: 32767px; margin-bottom: -32767px; }

Дивне число обумовлено тим, що це максимум, який може дозволити браузер Safari. Насправді воно не настільки дивне. Кому цікаво, це максимальне знакове ціле число, якщо представляти його 16 бітами.

У підсумку все, що йде за колонками зміщується і знаходиться прямо під вмістом найдовшої з них, а колонки подовжуються вниз. Негарно одне - через довгих колонок сама сторінка стає такою ж довгою. Щоб з цим боротися, треба їх контейнеру проставити властивість overflow: hidden, яке змушує контейнер просто відрізати і не показувати те, що виходить за його межі.

У мого прикладу, який я взяв на самому початку, є, правда, одна заковика. Там колонки лежать прямо в body. А якщо body проставити overflow: hidden, то браузери скасовують скролінг у сторінки начисто. Навіть якщо реальний вміст вище вікна. Тому колонки треба загорнути в ще один елемент, наприклад div. Але справедливості заради треба сказати, що на практиці колонки і так бувають у що-небудь вже загорнуті.

засада

Куди ж без неї :-). Як я не особливо прозоро натякнув на самому початку, оскільки float'и не вигадували як засіб створення колонок, це обов'язково вилізе чимось потворним і відгукнеться збільшенням витрати анальгіну (деякі вважають за краще темпалгин або парацетамол).

Причому "вилізе" - в прямому сенсі. Давайте трохи посунемо наш "голий" приклад в сторону реальності, додавши над колонками шапку і внизу якийсь теж блок з текстом.

<Body> <div id = "header"> ... </ div> <div id = "main"> <div id = "content"> ... </ div> <div id = "sidebar">. .. </ div> </ div> <div id = "footer"> ... </ div> </ body>

Для простоти виберемо нехитрий стовпчик дизайн з фіксованою шириною. Шапку і нижній блок зробимо синіми з білими буквами, основний вміст білим, а додаткову колонку теж синьою, але трохи світліше. Кольори колонкам задамо способом "Faux columns".

/ * Розкладка в колонки * / body {width: 600px; margin: 0 auto; } #Content {float: left; width: 450px; } #Sidebar {float: right; width: 150px; } / * Кольори * / #main {background: url (bg.png) right top repeat-y; } #Header, #footer {background: # 238; color: white; }

Всякі відступи і шрифти я знову опустив для простоти сприйняття. Додамо тестового тексту і запускаємо:

Хм ... Ну, колонки, в загальному, навіть можна розгледіти! Чи не причепишся! Утім, як не крути, але виглядає все не так, як задумано, а навіть можна сказати, все перетворилося в якусь кашу з квітів і букв.

Щоб зрозуміти, чому так відбувається, треба згадати опис того, як працює float. А саме, що блоки, що йдуть за float'амі перестають ці float'и помічати і підтягуються вгору. Більш того, сам контейнер, в якому float'и знаходяться, теж перестає їх помічати і float'нутие блоки провалюються через низ контейнера, якщо він закінчуватися раніше.

Тепер подивимося на наш код. Обидва float'нутих блоку "content" і "sidebar" знаходяться всередині блоку "main". І більше нічого в "main" немає. А раз йому нічого більше утримувати, то його висота схлопивается в нуль! Тому й не видно на зображенні ні білого фону "content", ні світло-синього фону "sidebar", тому що ці кольори призначені у вигляді фону "main".

Далі - "footer". Він, підкоряючись все тим же правилом, теж не бачить float'нутих блоків і підтягується наверх прямо до самого заголовку (оскільки "main" - нульовий висоти). Але в "footer" є текст. Текст цей вже повинен обтікати float'и: справа "content" і зліва "sidebar". Між колонками місця не залишилося, тому текст може початися тільки під одним з колонок, яка перша скінчиться. Там він і є. Таким чином, "footer", підтягшись під заголовок, триває вниз, поки не закінчиться весь його текст. І весь цей синій фон, що нижче заголовка - це "footer" і є.

Навіщо така складність

Описане поведінка повинна вселяти подив. Навіщо треба було вигадувати такі складності: розділити поняття блоку так, щоб кольори і рамки наверх, а текст - на місці? Але сенс, звичайно, є. Це, поряд зі спаданням кордонів , Спроба змусити боксову модель CSS нормально вести себе в умовах простого потоку тексту. Детальний класичне пояснення цьому феномену є все у того ж Еріка Мейєра в статті " Containing Floats "(Англійською). Постараюся коротко передати суть.

Уявіть собі звичайний потік абзаців - блоків з текстом - без всякого позиціонування. В одному з абзаців зустрічається картинка, яку хочеться зрушити, скажімо, вліво, щоб текст її обтікав. Таке раніше в HTML досягалося властивістю align = "left", але в дусі винесення оформлення з HTML в стилі, для цієї функції як раз і придумали властивість float. Тобто замість align цій картинці приписується float: left.

Нехай зсувається картинка займає по висоті більше, ніж текст абзацу. Якщо вона буде розтягувати свій абзац і відсувати початок наступного нижче, то це буде виглядати непривабливо через збільшеного відстані між рядками сусідніх абзаців. Тому вона і провалюється через усі межі блоків, зберігаючи між ними гарні відступи, а текст її обтікає.

рішення

Отже, поведінка з проваленням зрозуміло, але воно зручно для непозіціонірованного тексту, а для розкладки - зовсім незручно. Існує два підходи усуває обидва прояви цієї властивості: підтягування наступних боксів наверх і провалювання через низ контейнера.

Для усунення підтягування блоків існує спеціальне властивість - clear. Воно змушує елемент зсуватися вниз, поки збоку від нього не залишиться float'ов. Причому можна управляти, з якого саме боку не повинно бути float'ов:

clear: left стежить, щоб float'ов не було зліва clear: right стежить, щоб float'ов не було справа clear: both стежить, щоб float'ов не було з обох сторін

Таким чином, якщо ми скажемо нашому "footer" у:

#footer {clear: both; }

... щоб зліва і праворуч від нього не було float'нутих колонок, то він зрушить вниз якраз туди, де вони обидві закінчуються.

Але це не вирішує іншої проблеми: того, що float'и провалюються через "main", і той схлопивается, в результаті чого не видно колоночного фону, який йому призначено. Провалювання можна перемогти двома способами.

Можна явно спозиционировать контейнер якимось чином. Наскільки я розумію логіку специфікації, поведінка провалювання вважається логічним тільки в простому потоці. В інших випадках воно тільки заважає. І так воно і є, як ми переконалися. Тобто досить призначити контейнеру наприклад position: absolute або float: left і нічого не буде провалюється, контейнер буде повністю укладати в себе і текст, і float'и. У нашому випадку (і в більшості випадків, до речі) це рішення цілком підійде.

Інший цікавий спосіб пов'язаний з побічним ефектом властивості overflow. Само по собі воно призначене для того, щоб визначати, як буде вести себе контейнер при переповненні, коли не може вмістити свій вміст. У нього є чотири значення:

visible вміст переходить через край і його нормально видно (це поведінка за умовчанням) hidden вміст відсікається за межами контейнера і його там ніяк не видно auto якщо вміст переповнює контейнер, у нього з'являється скроллбар, що дозволяє прокручувати вміст, якщо ні - не з'являється scroll схоже на auto, тільки скроллбар у контейнера є завжди, навіть коли вміст його не наповнюється

Так ось побічний ефект полягає в тому, що якщо контейнеру поставити будь-overflow, крім звичайного visible, він раптом розтягується і укладає в себе float'и, які в ньому сидять, усуваючи провалювання.

Який же overflow використовувати? Відразу відпадає scroll - завжди висять скроллбар явно не потрібні. Залишаються auto і hidden, які відрізняються тільки тим, з'являється скроллбар при переповненні чи ні. Але у нас ніякого переповнення немає, навпаки, цією властивістю ми змусили контейнер додатково розтягнутися, щоб він охоплював всі свої елементи. Тому використовувати можна будь-яке значення.

Я забобонно намагаюся використовувати hidden, щоб не з'являлося скроллбар, якщо через якихось глюків переповнення раптом виникне.

Я забобонно намагаюся використовувати hidden, щоб не з'являлося скроллбар, якщо через якихось глюків переповнення раптом виникне

У рішення з overflow є одна заковика, пов'язана з поведінкою Деякого Браузера ™. Воно працює тільки якщо контейнеру явно призначені ширина або висота. Через це їм іноді незручно користуватися, коли вам потрібні автоматичні розміри, а не жорсткі.

Отже, в підсумку, щоб виправити наш приклад з колонками, треба зробити так:

#main {width: 100%; overflow: hidden; }

До речі! Якби для малювання фону під колонками я використав не faux columns, а спосіб з довгим padding'ом, то він би зажадав використовувати overflow: hidden для "main", що заодно вирішує і проблему з проваленням. Але як би тоді я про це розповідав?

Розкладка в CSS: float

Довга епопея з написанням статті про властивості "float" завершена. Нехай часу пішло багато, але мені здається, що мені вдалося максимально дохідливо звести все різноманіття поводжень цього потужного і трохи дивного властивості в одну загальну систему.

Крім того, ця стаття містить рекордну кількість ілюстрацій серед всього " підручника ":-)

Доля властивості "float" в CSS злегка схожа на долю тега "table" в HTML: ні те, ні інше взагалі не замислювалося як засіб створення колонок і взагалі розкладки елементів. Однак через певні недосконалостей механізму позиціонування float використовується для цієї мети дуже широко. А то, що придумувався він для іншого, часто проявляється різними неочевидними ефектами. Однак перед тим, як їх показати, я все ж розповім, як float'и можна застосовувати для розкладки.

На самому початку - невелике зауваження про терміни. У російській мові не склалося жодного відомого терміна для цього інструменту (поки, принаймні). Тому я вважаю за краще писати його в вихідному написанні - "float". Читається це приблизно як "флоут" (ламати вилиці вимовою "флоат" не потрібно). Заодно тут же прошу пробачити мені такі вольності як "заfloat'іть", "пріfloat'нутий" і т.п. :-)

Принцип роботи

Як і позиціонування, float використовується для того, щоб рухати бокси. Але на відміну від позиціонування, яким можна рухати бокси практично довільно, все, що може float - це зрушити елемент до однієї зі сторін потоку , Правою чи лівою.

При цьому сам бокс і наступні за ним в потоці набувають цікаве поведінку:

При цьому сам бокс і наступні за ним в потоці набувають цікаве поведінку:

  1. Float'нутий бокс зміщується по горизонталі і прилипає до однієї зі сторін батька.
  2. Float'нутий бокс перестає лунати на всю ширину батьківського боксу-контейнера (як це відбувається з блоками в потоці). З його непріжатой до батькові чи матері вільної сторони з'являється вільне місце.
  3. Наступні за ним блокові бокси підтягуються вгору і займають його місце, як якщо б float'нутого боксу в потоці не було.
  4. Рядкові ж бокси всередині посунувши наверх блоків починають обтікати float'нутий бокс з вільною боку.

Хочу ще раз підкреслити очевидну відразу річ: сама коробка блоку, наступного за float'ом, підлазить під нього і займають всю ширину потоку, а ось текст всередині цього блоку зміщується в бік і обтікає float.

Далі цікаво, як себе ведуть float'нутие в одну сторону бокси, які йдуть один за іншим. В цьому випадку наступний бокс буде намагатися вміститися збоку від попереднього, з його вільної сторони. І тільки якщо йому там не буде достатньо місця, тоді він зміститься нижче і буде намагатися вміститися вже там.

Є ще один маленький технічний аспект, що не обов'язковий для розуміння всієї "механіки". Заfloat'іть можна як блокові бокси, так і малі. При цьому малі тут же автоматично стають блоковими. Тобто, писати display: block; для float'а зайве.

З двох описаних особливостей float'ов - притискання до краю і стикування збоку один одного - випливають два основних застосування їх в розкладці:

  • поділ сторінки на колонки
  • горизонтально розташовані меню

колонки

Колонки - це коли блоки тексту розташовані поруч один з одним і мають однакову висоту.

Все колоночного розкладки я буду розглядати на ось такому простому HTML'ном коді з двома блоками:

<Body> <div id = "sidebar"> ... </ div> <div id = "content"> ... </ div> </ body>

Відразу варто сказати, що робити колонки в розтяжному по ширині контейнері складніше, ніж із заданою шириною. Тут є два принципово різних підходи, які підходять для різних випадків.

пропорційна ширина

пропорційна ширина

Якщо потрібно, щоб ширина колонок змінювалася пропорційно, при зміні ширини сторінки, то підхід такий:

#content {float: right; width: 70%; } #Sidebar {float: left; width: 30%; }

Тобто два блоки float'ятся поруч в різні боки, а їх ширина ділиться в потрібному процентному співвідношенні. Цей спосіб дозволяє легко поміняти колонки місцями - просто помінявши значення right і left.

Розтягування тільки однієї колонки

Якщо потрібно, щоб змінювалася тільки ширина основної колонки, то попередній спосіб не підходить. Справа в тому, що в CSS, на жаль, не можна безпосередньо сформулювати таку річ як "вся доступна ширина мінус конкретне число".

Тепер звернемося до однієї з попередніх статей про блоки в потоці , Де я згадав про одну їх корисної особливості автоматично укладатися по ширині в розмір батьківського боксу. Тобто, якщо блоку в прямому потоці задати, скажімо, лівий margin, то його ширина відповідно скоротиться. А це саме те поведінка, якого ми хотіли добитися від однієї з колонок.

А це саме те поведінка, якого ми хотіли добитися від однієї з колонок

Отже, для потрібного нам ефекту ми дамо основного блоку лівий margin, щоб він стиснувся направо, а бічну панель заfloat'ім на це місце:

#sidebar {float: left; width: 200px; } #Content {margin-left: 200px; }

Але у другого способу є один дуже серйозний недолік. Зверніть увагу, що в початковому HTML блок "sidebar" йде до блоку "content" з основним вмістом. Не потрібно думати, що так зроблено випадково :-). Так зроблено спеціально, тому що інакше цей самий другий спосіб з накладенням колонки поверх margin'а не працював би.

Так зроблено спеціально, тому що інакше цей самий другий спосіб з накладенням колонки поверх margin'а не працював би

Як я написав на початку статті, float'и зсуваються тільки в сторону і дають місце наступним блоками, які з'їжджають наверх. Тому принципово, щоб "sidebar" був уже нагорі, і тоді основний блок під'їде до нього. Якщо "sidebar" йде після основного блоку, то він так і залишиться нижче, і ні на які колонки це схоже не буде.

Це дійсно погано, тому що перекреслює одну з основних ідей CSS: відділення оформлення від змісту. Виходить, що ми захотіли змінити тільки дизайн, а якщо блоки розташовані "не так", то доведеться лізти ще і в HTML-шаблони. Крім того, з точки зору структури можуть бути свої вагомі підстави розташовувати блоки так, а не інакше. Наприклад щоб користувач міг почати читати основний текст сторінки, не чекаючи завантаження навігації.

фіксована ширина

Все різко спрощується, коли колонки поміщаються в фіксовану ширину контейнера. В цьому випадку краще всього використовувати перший спосіб (float'іть все колонки), і ширину вже можна задавати не тільки у відсотках, а й у чому хочете, оскільки її можна точно обчислити.

Висота колонок

Знову-таки, я далеко не випадково "відрізав" на картинках нижню частину блоків :-). Інакше б вони як колонки зовсім не виглядали, тому що, як неважко переконатися, якщо застосувати ті фрагменти CSS, що я привів, і розфарбувати колонки різними кольорами, то їх висота виявляється різною. Вона залежить від кількості вмісту в цих блоках.

Цей негарний ефект можна обійти кількома способами.

Перший спосіб називається "Помилкові колонки" ( "Faux columns"), опублікований в авторитетному веб-журналі A List Apart у вересні 2004 року і з тих пір користується великою популярністю. Всім рекомендую прочитати або оригінал , або російський переклад . Однак якщо ви сьогодні не в настрої клікати, то ось коротко його суть.

Замість того, щоб призначати фон самим колонок, вони залишаються прозорими, а ось їх контейнеру призначається фонова картинка шириною у весь контейнер і повторювана по вертикалі. Частини цієї картинки, що знаходяться під різними колонками, фарбуються в різні кольори і при повторенні вниз це дає потрібний візуальний ефект.

Частини цієї картинки, що знаходяться під різними колонками, фарбуються в різні кольори і при повторенні вниз це дає потрібний візуальний ефект

Що в помилкових колонках чудово - так це те, що ви можете не обмежувати себе на фонової зображенні рівними квітами. На ній, наприклад можна намалювати ефект тіні між колонками, що повторюються горизонтальні смужки у вигляді фону, орнамент по краях.

Недолік же способу полягає в тому, що оскільки у фонової картинки є тільки один розмір, її не можна застосовувати для пропорційно розтягуються колонок, так як картинка тягти не буде (тут я помилився; все цілком можна застосувати, читайте коментар ). А ось для випадку, коли одна з колонок фіксована по ширині, фон пристосувати можна (цей випадок, до речі, в "Faux columns" не розглянутий).

Суть полягає в тому, щоб помістити фонову картинку тільки під ту колонку, ширина якої відома. Решта місце буде зайнято фоновим кольором контейнера, а не картинкою.

Візьмемо наш приклад і зробимо колонку "sidebar" справа шириною 200 пікселів, а "content" нехай розтягується. Для "sidebar" підготуємо картинку розмірами 200х1 наприклад рівного синього відтінку. А під "content" відведемо жовтуватий.

У стилях це виглядає так:

#sidebar {float: right; width: 200px; } #Content {margin-right: 200px; } Body {background: url (bg.png) #FFD right top repeat-y; }

Єдине правило для контейнера (body) задає всі поведінку фону:

  • вказується URL картинки (bg.png)
  • колір фону в тих місцях, де її не буде (#FFD)
  • становище картинки притиснутою до правого краю (right top)
  • повторення картинки вниз (repeat-y)

У реальному прикладі в CSS ще була пара правил для кольору букв і боротьби з межами, які зараз не істотні.

Інший спосіб зрівнювання колонок по висоті був описаний недавно і вже сильно відомий, оскільки зручний.

Інший спосіб зрівнювання колонок по висоті був   описаний недавно   і вже сильно відомий, оскільки зручний

Ідея його полягає в тому, щоб нерівність висот колонок заховати, неймовірно подовживши їх вниз, щоб їх кінці були за межами реального вмісту сторінки. Домагаються цього тим, що спочатку ставлять колонкам дуже великий відступ (padding) вниз, який зафарбовується кольором фону. А щоб все інше вміст теж не порушувався туди далеко, колонкам призначається негативна межа (margin) такого ж розміру:

#content, #sidebar {padding-bottom: 32767px; margin-bottom: -32767px; }

Дивне число обумовлено тим, що це максимум, який може дозволити браузер Safari. Насправді воно не настільки дивне. Кому цікаво, це максимальне знакове ціле число, якщо представляти його 16 бітами.

У підсумку все, що йде за колонками зміщується і знаходиться прямо під вмістом найдовшої з них, а колонки подовжуються вниз. Негарно одне - через довгих колонок сама сторінка стає такою ж довгою. Щоб з цим боротися, треба їх контейнеру проставити властивість overflow: hidden, яке змушує контейнер просто відрізати і не показувати те, що виходить за його межі.

У мого прикладу, який я взяв на самому початку, є, правда, одна заковика. Там колонки лежать прямо в body. А якщо body проставити overflow: hidden, то браузери скасовують скролінг у сторінки начисто. Навіть якщо реальний вміст вище вікна. Тому колонки треба загорнути в ще один елемент, наприклад div. Але справедливості заради треба сказати, що на практиці колонки і так бувають у що-небудь вже загорнуті.

засада

Куди ж без неї :-). Як я не особливо прозоро натякнув на самому початку, оскільки float'и не вигадували як засіб створення колонок, це обов'язково вилізе чимось потворним і відгукнеться збільшенням витрати анальгіну (деякі вважають за краще темпалгин або парацетамол).

Причому "вилізе" - в прямому сенсі. Давайте трохи посунемо наш "голий" приклад в сторону реальності, додавши над колонками шапку і внизу якийсь теж блок з текстом.

<Body> <div id = "header"> ... </ div> <div id = "main"> <div id = "content"> ... </ div> <div id = "sidebar">. .. </ div> </ div> <div id = "footer"> ... </ div> </ body>

Для простоти виберемо нехитрий стовпчик дизайн з фіксованою шириною. Шапку і нижній блок зробимо синіми з білими буквами, основний вміст білим, а додаткову колонку теж синьою, але трохи світліше. Кольори колонкам задамо способом "Faux columns".

/ * Розкладка в колонки * / body {width: 600px; margin: 0 auto; } #Content {float: left; width: 450px; } #Sidebar {float: right; width: 150px; } / * Кольори * / #main {background: url (bg.png) right top repeat-y; } #Header, #footer {background: # 238; color: white; }

Всякі відступи і шрифти я знову опустив для простоти сприйняття. Додамо тестового тексту і запускаємо:

Хм ... Ну, колонки, в загальному, навіть можна розгледіти! Чи не причепишся! Утім, як не крути, але виглядає все не так, як задумано, а навіть можна сказати, все перетворилося в якусь кашу з квітів і букв.

Щоб зрозуміти, чому так відбувається, треба згадати опис того, як працює float. А саме, що блоки, що йдуть за float'амі перестають ці float'и помічати і підтягуються вгору. Більш того, сам контейнер, в якому float'и знаходяться, теж перестає їх помічати і float'нутие блоки провалюються через низ контейнера, якщо він закінчуватися раніше.

Тепер подивимося на наш код. Обидва float'нутих блоку "content" і "sidebar" знаходяться всередині блоку "main". І більше нічого в "main" немає. А раз йому нічого більше утримувати, то його висота схлопивается в нуль! Тому й не видно на зображенні ні білого фону "content", ні світло-синього фону "sidebar", тому що ці кольори призначені у вигляді фону "main".

Далі - "footer". Він, підкоряючись все тим же правилом, теж не бачить float'нутих блоків і підтягується наверх прямо до самого заголовку (оскільки "main" - нульовий висоти). Але в "footer" є текст. Текст цей вже повинен обтікати float'и: справа "content" і зліва "sidebar". Між колонками місця не залишилося, тому текст може початися тільки під одним з колонок, яка перша скінчиться. Там він і є. Таким чином, "footer", підтягшись під заголовок, триває вниз, поки не закінчиться весь його текст. І весь цей синій фон, що нижче заголовка - це "footer" і є.

Навіщо така складність

Описане поведінка повинна вселяти подив. Навіщо треба було вигадувати такі складності: розділити поняття блоку так, щоб кольори і рамки наверх, а текст - на місці? Але сенс, звичайно, є. Це, поряд зі спаданням кордонів , Спроба змусити боксову модель CSS нормально вести себе в умовах простого потоку тексту. Детальний класичне пояснення цьому феномену є все у того ж Еріка Мейєра в статті " Containing Floats "(Англійською). Постараюся коротко передати суть.

Уявіть собі звичайний потік абзаців - блоків з текстом - без всякого позиціонування. В одному з абзаців зустрічається картинка, яку хочеться зрушити, скажімо, вліво, щоб текст її обтікав. Таке раніше в HTML досягалося властивістю align = "left", але в дусі винесення оформлення з HTML в стилі, для цієї функції як раз і придумали властивість float. Тобто замість align цій картинці приписується float: left.

Нехай зсувається картинка займає по висоті більше, ніж текст абзацу. Якщо вона буде розтягувати свій абзац і відсувати початок наступного нижче, то це буде виглядати непривабливо через збільшеного відстані між рядками сусідніх абзаців. Тому вона і провалюється через усі межі блоків, зберігаючи між ними гарні відступи, а текст її обтікає.

рішення

Отже, поведінка з проваленням зрозуміло, але воно зручно для непозіціонірованного тексту, а для розкладки - зовсім незручно. Існує два підходи усуває обидва прояви цієї властивості: підтягування наступних боксів наверх і провалювання через низ контейнера.

Для усунення підтягування блоків існує спеціальне властивість - clear. Воно змушує елемент зсуватися вниз, поки збоку від нього не залишиться float'ов. Причому можна управляти, з якого саме боку не повинно бути float'ов:

clear: left стежить, щоб float'ов не було зліва clear: right стежить, щоб float'ов не було справа clear: both стежить, щоб float'ов не було з обох сторін

Таким чином, якщо ми скажемо нашому "footer" у:

#footer {clear: both; }

... щоб зліва і праворуч від нього не було float'нутих колонок, то він зрушить вниз якраз туди, де вони обидві закінчуються.

Але це не вирішує іншої проблеми: того, що float'и провалюються через "main", і той схлопивается, в результаті чого не видно колоночного фону, який йому призначено. Провалювання можна перемогти двома способами.

Можна явно спозиционировать контейнер якимось чином. Наскільки я розумію логіку специфікації, поведінка провалювання вважається логічним тільки в простому потоці. В інших випадках воно тільки заважає. І так воно і є, як ми переконалися. Тобто досить призначити контейнеру наприклад position: absolute або float: left і нічого не буде провалюється, контейнер буде повністю укладати в себе і текст, і float'и. У нашому випадку (і в більшості випадків, до речі) це рішення цілком підійде.

Інший цікавий спосіб пов'язаний з побічним ефектом властивості overflow. Само по собі воно призначене для того, щоб визначати, як буде вести себе контейнер при переповненні, коли не може вмістити свій вміст. У нього є чотири значення:

visible вміст переходить через край і його нормально видно (це поведінка за умовчанням) hidden вміст відсікається за межами контейнера і його там ніяк не видно auto якщо вміст переповнює контейнер, у нього з'являється скроллбар, що дозволяє прокручувати вміст, якщо ні - не з'являється scroll схоже на auto, тільки скроллбар у контейнера є завжди, навіть коли вміст його не наповнюється

Так ось побічний ефект полягає в тому, що якщо контейнеру поставити будь-overflow, крім звичайного visible, він раптом розтягується і укладає в себе float'и, які в ньому сидять, усуваючи провалювання.

Який же overflow використовувати? Відразу відпадає scroll - завжди висять скроллбар явно не потрібні. Залишаються auto і hidden, які відрізняються тільки тим, з'являється скроллбар при переповненні чи ні. Але у нас ніякого переповнення немає, навпаки, цією властивістю ми змусили контейнер додатково розтягнутися, щоб він охоплював всі свої елементи. Тому використовувати можна будь-яке значення.

Я забобонно намагаюся використовувати hidden, щоб не з'являлося скроллбар, якщо через якихось глюків переповнення раптом виникне.

Я забобонно намагаюся використовувати hidden, щоб не з'являлося скроллбар, якщо через якихось глюків переповнення раптом виникне

У рішення з overflow є одна заковика, пов'язана з поведінкою Деякого Браузера ™. Воно працює тільки якщо контейнеру явно призначені ширина або висота. Через це їм іноді незручно користуватися, коли вам потрібні автоматичні розміри, а не жорсткі.

Отже, в підсумку, щоб виправити наш приклад з колонками, треба зробити так:

#main {width: 100%; overflow: hidden; }

До речі! Якби для малювання фону під колонками я використав не faux columns, а спосіб з довгим padding'ом, то він би зажадав використовувати overflow: hidden для "main", що заодно вирішує і проблему з проваленням. Але як би тоді я про це розповідав?

Розкладка в CSS: float

Довга епопея з написанням статті про властивості "float" завершена. Нехай часу пішло багато, але мені здається, що мені вдалося максимально дохідливо звести все різноманіття поводжень цього потужного і трохи дивного властивості в одну загальну систему.

Крім того, ця стаття містить рекордну кількість ілюстрацій серед всього " підручника ":-)

Доля властивості "float" в CSS злегка схожа на долю тега "table" в HTML: ні те, ні інше взагалі не замислювалося як засіб створення колонок і взагалі розкладки елементів. Однак через певні недосконалостей механізму позиціонування float використовується для цієї мети дуже широко. А то, що придумувався він для іншого, часто проявляється різними неочевидними ефектами. Однак перед тим, як їх показати, я все ж розповім, як float'и можна застосовувати для розкладки.

На самому початку - невелике зауваження про терміни. У російській мові не склалося жодного відомого терміна для цього інструменту (поки, принаймні). Тому я вважаю за краще писати його в вихідному написанні - "float". Читається це приблизно як "флоут" (ламати вилиці вимовою "флоат" не потрібно). Заодно тут же прошу пробачити мені такі вольності як "заfloat'іть", "пріfloat'нутий" і т.п. :-)

Принцип роботи

Як і позиціонування, float використовується для того, щоб рухати бокси. Але на відміну від позиціонування, яким можна рухати бокси практично довільно, все, що може float - це зрушити елемент до однієї зі сторін потоку , Правою чи лівою.

При цьому сам бокс і наступні за ним в потоці набувають цікаве поведінку:

При цьому сам бокс і наступні за ним в потоці набувають цікаве поведінку:

  1. Float'нутий бокс зміщується по горизонталі і прилипає до однієї зі сторін батька.
  2. Float'нутий бокс перестає лунати на всю ширину батьківського боксу-контейнера (як це відбувається з блоками в потоці). З його непріжатой до батькові чи матері вільної сторони з'являється вільне місце.
  3. Наступні за ним блокові бокси підтягуються вгору і займають його місце, як якщо б float'нутого боксу в потоці не було.
  4. Рядкові ж бокси всередині посунувши наверх блоків починають обтікати float'нутий бокс з вільною боку.

Хочу ще раз підкреслити очевидну відразу річ: сама коробка блоку, наступного за float'ом, підлазить під нього і займають всю ширину потоку, а ось текст всередині цього блоку зміщується в бік і обтікає float.

Далі цікаво, як себе ведуть float'нутие в одну сторону бокси, які йдуть один за іншим. В цьому випадку наступний бокс буде намагатися вміститися збоку від попереднього, з його вільної сторони. І тільки якщо йому там не буде достатньо місця, тоді він зміститься нижче і буде намагатися вміститися вже там.

Є ще один маленький технічний аспект, що не обов'язковий для розуміння всієї "механіки". Заfloat'іть можна як блокові бокси, так і малі. При цьому малі тут же автоматично стають блоковими. Тобто, писати display: block; для float'а зайве.

З двох описаних особливостей float'ов - притискання до краю і стикування збоку один одного - випливають два основних застосування їх в розкладці:

  • поділ сторінки на колонки
  • горизонтально розташовані меню

колонки

Колонки - це коли блоки тексту розташовані поруч один з одним і мають однакову висоту.

Все колоночного розкладки я буду розглядати на ось такому простому HTML'ном коді з двома блоками:

<Body> <div id = "sidebar"> ... </ div> <div id = "content"> ... </ div> </ body>

Відразу варто сказати, що робити колонки в розтяжному по ширині контейнері складніше, ніж із заданою шириною. Тут є два принципово різних підходи, які підходять для різних випадків.

пропорційна ширина

пропорційна ширина

Якщо потрібно, щоб ширина колонок змінювалася пропорційно, при зміні ширини сторінки, то підхід такий:

#content {float: right; width: 70%; } #Sidebar {float: left; width: 30%; }

Тобто два блоки float'ятся поруч в різні боки, а їх ширина ділиться в потрібному процентному співвідношенні. Цей спосіб дозволяє легко поміняти колонки місцями - просто помінявши значення right і left.

Розтягування тільки однієї колонки

Якщо потрібно, щоб змінювалася тільки ширина основної колонки, то попередній спосіб не підходить. Справа в тому, що в CSS, на жаль, не можна безпосередньо сформулювати таку річ як "вся доступна ширина мінус конкретне число".

Тепер звернемося до однієї з попередніх статей про блоки в потоці , Де я згадав про одну їх корисної особливості автоматично укладатися по ширині в розмір батьківського боксу. Тобто, якщо блоку в прямому потоці задати, скажімо, лівий margin, то його ширина відповідно скоротиться. А це саме те поведінка, якого ми хотіли добитися від однієї з колонок.

А це саме те поведінка, якого ми хотіли добитися від однієї з колонок

Отже, для потрібного нам ефекту ми дамо основного блоку лівий margin, щоб він стиснувся направо, а бічну панель заfloat'ім на це місце:

#sidebar {float: left; width: 200px; } #Content {margin-left: 200px; }

Але у другого способу є один дуже серйозний недолік. Зверніть увагу, що в початковому HTML блок "sidebar" йде до блоку "content" з основним вмістом. Не потрібно думати, що так зроблено випадково :-). Так зроблено спеціально, тому що інакше цей самий другий спосіб з накладенням колонки поверх margin'а не працював би.

Так зроблено спеціально, тому що інакше цей самий другий спосіб з накладенням колонки поверх margin'а не працював би

Як я написав на початку статті, float'и зсуваються тільки в сторону і дають місце наступним блоками, які з'їжджають наверх. Тому принципово, щоб "sidebar" був уже нагорі, і тоді основний блок під'їде до нього. Якщо "sidebar" йде після основного блоку, то він так і залишиться нижче, і ні на які колонки це схоже не буде.

Це дійсно погано, тому що перекреслює одну з основних ідей CSS: відділення оформлення від змісту. Виходить, що ми захотіли змінити тільки дизайн, а якщо блоки розташовані "не так", то доведеться лізти ще і в HTML-шаблони. Крім того, з точки зору структури можуть бути свої вагомі підстави розташовувати блоки так, а не інакше. Наприклад щоб користувач міг почати читати основний текст сторінки, не чекаючи завантаження навігації.

фіксована ширина

Все різко спрощується, коли колонки поміщаються в фіксовану ширину контейнера. В цьому випадку краще всього використовувати перший спосіб (float'іть все колонки), і ширину вже можна задавати не тільки у відсотках, а й у чому хочете, оскільки її можна точно обчислити.

Висота колонок

Знову-таки, я далеко не випадково "відрізав" на картинках нижню частину блоків :-). Інакше б вони як колонки зовсім не виглядали, тому що, як неважко переконатися, якщо застосувати ті фрагменти CSS, що я привів, і розфарбувати колонки різними кольорами, то їх висота виявляється різною. Вона залежить від кількості вмісту в цих блоках.

Цей негарний ефект можна обійти кількома способами.

Перший спосіб називається "Помилкові колонки" ( "Faux columns"), опублікований в авторитетному веб-журналі A List Apart у вересні 2004 року і з тих пір користується великою популярністю. Всім рекомендую прочитати або оригінал , або російський переклад . Однак якщо ви сьогодні не в настрої клікати, то ось коротко його суть.

Замість того, щоб призначати фон самим колонок, вони залишаються прозорими, а ось їх контейнеру призначається фонова картинка шириною у весь контейнер і повторювана по вертикалі. Частини цієї картинки, що знаходяться під різними колонками, фарбуються в різні кольори і при повторенні вниз це дає потрібний візуальний ефект.

Частини цієї картинки, що знаходяться під різними колонками, фарбуються в різні кольори і при повторенні вниз це дає потрібний візуальний ефект

Що в помилкових колонках чудово - так це те, що ви можете не обмежувати себе на фонової зображенні рівними квітами. На ній, наприклад можна намалювати ефект тіні між колонками, що повторюються горизонтальні смужки у вигляді фону, орнамент по краях.

Недолік же способу полягає в тому, що оскільки у фонової картинки є тільки один розмір, її не можна застосовувати для пропорційно розтягуються колонок, так як картинка тягти не буде (тут я помилився; все цілком можна застосувати, читайте коментар ). А ось для випадку, коли одна з колонок фіксована по ширині, фон пристосувати можна (цей випадок, до речі, в "Faux columns" не розглянутий).

Суть полягає в тому, щоб помістити фонову картинку тільки під ту колонку, ширина якої відома. Решта місце буде зайнято фоновим кольором контейнера, а не картинкою.

Візьмемо наш приклад і зробимо колонку "sidebar" справа шириною 200 пікселів, а "content" нехай розтягується. Для "sidebar" підготуємо картинку розмірами 200х1 наприклад рівного синього відтінку. А під "content" відведемо жовтуватий.

У стилях це виглядає так:

#sidebar {float: right; width: 200px; } #Content {margin-right: 200px; } Body {background: url (bg.png) #FFD right top repeat-y; }

Єдине правило для контейнера (body) задає всі поведінку фону:

  • вказується URL картинки (bg.png)
  • колір фону в тих місцях, де її не буде (#FFD)
  • становище картинки притиснутою до правого краю (right top)
  • повторення картинки вниз (repeat-y)

У реальному прикладі в CSS ще була пара правил для кольору букв і боротьби з межами, які зараз не істотні.

Інший спосіб зрівнювання колонок по висоті був описаний недавно і вже сильно відомий, оскільки зручний.

Інший спосіб зрівнювання колонок по висоті був   описаний недавно   і вже сильно відомий, оскільки зручний

Ідея його полягає в тому, щоб нерівність висот колонок заховати, неймовірно подовживши їх вниз, щоб їх кінці були за межами реального вмісту сторінки. Домагаються цього тим, що спочатку ставлять колонкам дуже великий відступ (padding) вниз, який зафарбовується кольором фону. А щоб все інше вміст теж не порушувався туди далеко, колонкам призначається негативна межа (margin) такого ж розміру:

#content, #sidebar {padding-bottom: 32767px; margin-bottom: -32767px; }

Дивне число обумовлено тим, що це максимум, який може дозволити браузер Safari. Насправді воно не настільки дивне. Кому цікаво, це максимальне знакове ціле число, якщо представляти його 16 бітами.

У підсумку все, що йде за колонками зміщується і знаходиться прямо під вмістом найдовшої з них, а колонки подовжуються вниз. Негарно одне - через довгих колонок сама сторінка стає такою ж довгою. Щоб з цим боротися, треба їх контейнеру проставити властивість overflow: hidden, яке змушує контейнер просто відрізати і не показувати те, що виходить за його межі.

У мого прикладу, який я взяв на самому початку, є, правда, одна заковика. Там колонки лежать прямо в body. А якщо body проставити overflow: hidden, то браузери скасовують скролінг у сторінки начисто. Навіть якщо реальний вміст вище вікна. Тому колонки треба загорнути в ще один елемент, наприклад div. Але справедливості заради треба сказати, що на практиці колонки і так бувають у що-небудь вже загорнуті.

засада

Куди ж без неї :-). Як я не особливо прозоро натякнув на самому початку, оскільки float'и не вигадували як засіб створення колонок, це обов'язково вилізе чимось потворним і відгукнеться збільшенням витрати анальгіну (деякі вважають за краще темпалгин або парацетамол).

Причому "вилізе" - в прямому сенсі. Давайте трохи посунемо наш "голий" приклад в сторону реальності, додавши над колонками шапку і внизу якийсь теж блок з текстом.

<Body> <div id = "header"> ... </ div> <div id = "main"> <div id = "content"> ... </ div> <div id = "sidebar">. .. </ div> </ div> <div id = "footer"> ... </ div> </ body>

Для простоти виберемо нехитрий стовпчик дизайн з фіксованою шириною. Шапку і нижній блок зробимо синіми з білими буквами, основний вміст білим, а додаткову колонку теж синьою, але трохи світліше. Кольори колонкам задамо способом "Faux columns".

/ * Розкладка в колонки * / body {width: 600px; margin: 0 auto; } #Content {float: left; width: 450px; } #Sidebar {float: right; width: 150px; } / * Кольори * / #main {background: url (bg.png) right top repeat-y; } #Header, #footer {background: # 238; color: white; }

Всякі відступи і шрифти я знову опустив для простоти сприйняття. Додамо тестового тексту і запускаємо:

Хм ... Ну, колонки, в загальному, навіть можна розгледіти! Чи не причепишся! Утім, як не крути, але виглядає все не так, як задумано, а навіть можна сказати, все перетворилося в якусь кашу з квітів і букв.

Щоб зрозуміти, чому так відбувається, треба згадати опис того, як працює float. А саме, що блоки, що йдуть за float'амі перестають ці float'и помічати і підтягуються вгору. Більш того, сам контейнер, в якому float'и знаходяться, теж перестає їх помічати і float'нутие блоки провалюються через низ контейнера, якщо він закінчуватися раніше.

Тепер подивимося на наш код. Обидва float'нутих блоку "content" і "sidebar" знаходяться всередині блоку "main". І більше нічого в "main" немає. А раз йому нічого більше утримувати, то його висота схлопивается в нуль! Тому й не видно на зображенні ні білого фону "content", ні світло-синього фону "sidebar", тому що ці кольори призначені у вигляді фону "main".

Далі - "footer". Він, підкоряючись все тим же правилом, теж не бачить float'нутих блоків і підтягується наверх прямо до самого заголовку (оскільки "main" - нульовий висоти). Але в "footer" є текст. Текст цей вже повинен обтікати float'и: справа "content" і зліва "sidebar". Між колонками місця не залишилося, тому текст може початися тільки під одним з колонок, яка перша скінчиться. Там він і є. Таким чином, "footer", підтягшись під заголовок, триває вниз, поки не закінчиться весь його текст. І весь цей синій фон, що нижче заголовка - це "footer" і є.

Навіщо така складність

Описане поведінка повинна вселяти подив. Навіщо треба було вигадувати такі складності: розділити поняття блоку так, щоб кольори і рамки наверх, а текст - на місці? Але сенс, звичайно, є. Це, поряд зі спаданням кордонів , Спроба змусити боксову модель CSS нормально вести себе в умовах простого потоку тексту. Детальний класичне пояснення цьому феномену є все у того ж Еріка Мейєра в статті " Containing Floats "(Англійською). Постараюся коротко передати суть.

Уявіть собі звичайний потік абзаців - блоків з текстом - без всякого позиціонування. В одному з абзаців зустрічається картинка, яку хочеться зрушити, скажімо, вліво, щоб текст її обтікав. Таке раніше в HTML досягалося властивістю align = "left", але в дусі винесення оформлення з HTML в стилі, для цієї функції як раз і придумали властивість float. Тобто замість align цій картинці приписується float: left.

Нехай зсувається картинка займає по висоті більше, ніж текст абзацу. Якщо вона буде розтягувати свій абзац і відсувати початок наступного нижче, то це буде виглядати непривабливо через збільшеного відстані між рядками сусідніх абзаців. Тому вона і провалюється через усі межі блоків, зберігаючи між ними гарні відступи, а текст її обтікає.

рішення

Отже, поведінка з проваленням зрозуміло, але воно зручно для непозіціонірованного тексту, а для розкладки - зовсім незручно. Існує два підходи усуває обидва прояви цієї властивості: підтягування наступних боксів наверх і провалювання через низ контейнера.

Для усунення підтягування блоків існує спеціальне властивість - clear. Воно змушує елемент зсуватися вниз, поки збоку від нього не залишиться float'ов. Причому можна управляти, з якого саме боку не повинно бути float'ов:

clear: left стежить, щоб float'ов не було зліва clear: right стежить, щоб float'ов не було справа clear: both стежить, щоб float'ов не було з обох сторін

Таким чином, якщо ми скажемо нашому "footer" у:

#footer {clear: both; }

... щоб зліва і праворуч від нього не було float'нутих колонок, то він зрушить вниз якраз туди, де вони обидві закінчуються.

Але це не вирішує іншої проблеми: того, що float'и провалюються через "main", і той схлопивается, в результаті чого не видно колоночного фону, який йому призначено. Провалювання можна перемогти двома способами.

Можна явно спозиционировать контейнер якимось чином. Наскільки я розумію логіку специфікації, поведінка провалювання вважається логічним тільки в простому потоці. В інших випадках воно тільки заважає. І так воно і є, як ми переконалися. Тобто досить призначити контейнеру наприклад position: absolute або float: left і нічого не буде провалюється, контейнер буде повністю укладати в себе і текст, і float'и. У нашому випадку (і в більшості випадків, до речі) це рішення цілком підійде.

Інший цікавий спосіб пов'язаний з побічним ефектом властивості overflow. Само по собі воно призначене для того, щоб визначати, як буде вести себе контейнер при переповненні, коли не може вмістити свій вміст. У нього є чотири значення:

visible вміст переходить через край і його нормально видно (це поведінка за умовчанням) hidden вміст відсікається за межами контейнера і його там ніяк не видно auto якщо вміст переповнює контейнер, у нього з'являється скроллбар, що дозволяє прокручувати вміст, якщо ні - не з'являється scroll схоже на auto, тільки скроллбар у контейнера є завжди, навіть коли вміст його не наповнюється

Так ось побічний ефект полягає в тому, що якщо контейнеру поставити будь-overflow, крім звичайного visible, він раптом розтягується і укладає в себе float'и, які в ньому сидять, усуваючи провалювання.

Який же overflow використовувати? Відразу відпадає scroll - завжди висять скроллбар явно не потрібні. Залишаються auto і hidden, які відрізняються тільки тим, з'являється скроллбар при переповненні чи ні. Але у нас ніякого переповнення немає, навпаки, цією властивістю ми змусили контейнер додатково розтягнутися, щоб він охоплював всі свої елементи. Тому використовувати можна будь-яке значення.

Я забобонно намагаюся використовувати hidden, щоб не з'являлося скроллбар, якщо через якихось глюків переповнення раптом виникне.

Я забобонно намагаюся використовувати hidden, щоб не з'являлося скроллбар, якщо через якихось глюків переповнення раптом виникне

У рішення з overflow є одна заковика, пов'язана з поведінкою Деякого Браузера ™. Воно працює тільки якщо контейнеру явно призначені ширина або висота. Через це їм іноді незручно користуватися, коли вам потрібні автоматичні розміри, а не жорсткі.

Отже, в підсумку, щоб виправити наш приклад з колонками, треба зробити так:

#main {width: 100%; overflow: hidden; }

До речі! Якби для малювання фону під колонками я використав не faux columns, а спосіб з довгим padding'ом, то він би зажадав використовувати overflow: hidden для "main", що заодно вирішує і проблему з проваленням. Але як би тоді я про це розповідав?

Все на цьому з колонками ... Час сходити налити собі смачного чаю (багато хто воліє кави) і, додавши до цього якусь смачну булочку, зробити паузу для укладання в голові всього цього місива. Далі нас чекає маленька добавка - про меню.

Меню

Нагадаю, що якщо кілька йдуть підряд блоків заfloat'іть в одну сторону, то кожен наступний буде намагатися розкластися з вільною боку від попереднього. Цей ефект широко використовується для того, щоб перетворювати списки розділів сайту в горизонтально розташовані меню.

Візьмемо такий список:

<Ul> <li> <a href="/"> Початок </a> </ li> <li> <a href="catalog/"> Каталог </a> </ li> <li> <a href = "basket /"> Кошик </a> </ li> <li> <a href="help/"> Довідка </a> </ li> </ ul>

Щоб це було схоже на меню, треба заfloat'іть все li вліво, прибрати у них атрибутику списку (відступи і буліти) і ще додати для краси відступи, фон і рамку:

/ * Розкладка * / ul, li {float: left; list-style: none; margin: 0; padding: 0; } / * Вид * / li {padding: 2px 10px; font: Bold Small Tahoma; background: # 35C; color: white; border: solid 1px; border-color: # 46F # 238 # 238 # 46F; } A {color: white; text-decoration: none; }

Зверніть увагу, що для розкладки все властивості призначаються і для елементів ul, і для li. Це зручно звести в одне правило, тому що:

  • float: left потрібен елементам списку, щоб вони розклалися горизонтально, а самому списку - щоб елементи через нього не провалювалися;
  • нульові margin і padding усувають відступи, які браузери роблять для списків за замовчуванням, але вони це роблять дуже по-різному, тому простіше сказати "всім все по нулях", ніж пам'ятати що окремо для якого елементу проставляти.

мораль

Механізм float - ще один засіб розкладки поряд з абсолютним позиціонуванням.

Він відрізняються в кращу сторону, дозволяючи залишити елемент в потоці, що дуже зручно для колоночной розкладки.

Однак його мінусами є менша гнучкість через те, що елементи не можна рухати довільно, і тому що можливість його застосовувати може залежати від порядку елементів в HTML-розмітці.

Ця стаття - частина знаходиться в процесі написання циклу під РОбочий назв "Підручник". Я рекомендую ознайомітіся и з іншімі статтей, Які можна найти в категорії " підручник ", Де вони зараз Зібрані в зворотнього хронологічному порядку.

Навіщо треба було вигадувати такі складності: розділити поняття блоку так, щоб кольори і рамки наверх, а текст - на місці?
Який же overflow використовувати?
Але як би тоді я про це розповідав?
Навіщо треба було вигадувати такі складності: розділити поняття блоку так, щоб кольори і рамки наверх, а текст - на місці?
Який же overflow використовувати?
Але як би тоді я про це розповідав?
Навіщо треба було вигадувати такі складності: розділити поняття блоку так, щоб кольори і рамки наверх, а текст - на місці?
Який же overflow використовувати?
Але як би тоді я про це розповідав?
Навіщо треба було вигадувати такі складності: розділити поняття блоку так, щоб кольори і рамки наверх, а текст - на місці?