This commit is contained in:
Ilya Kantor 2014-11-16 01:40:20 +03:00
parent 962caebbb7
commit 87bf53d076
1825 changed files with 94929 additions and 0 deletions

View file

@ -0,0 +1,73 @@
# О чём пойдёт речь
Неужели мы сейчас будем учить CSS? Ничего подобного. Предполагается, что вы *уже* знаете CSS, во всяком случае понимаете его на таком уровне, который позволяет делать Web-страницы.
[cut]
Особенность квалификации JavaScript-разработчика заключается в том, что он не обязан выбирать цвета, рисовать иконки, "делать красиво". Он также не обязан верстать макет в HTML, разве что если является по совместительству специалистом-верстальщиком.
**Вот что он должен уметь абсолютно точно -- так это и разработать такую структуру HTML/CSS для элементов управления, которая не сломается, и с которой ему же потом удобно будет взаимодействовать**.
Это требует **отличного знания CSS в области позиционирования** элементов, включая тонкости работы `display`, `margin`, `border`, `outline`, `position`, `float`, `border-box` и остальных свойств, а также подходы к построению структуры компонент (CSS layouts).
Многое можно сделать при помощи JavaScript. И зачастую, не зная CSS, так и делают. Но мы на это ловиться не будем.
[summary]
Если что-то можно сделать через CSS -- лучше делать это через CSS.
[/summary]
Причина проста -- как бы ни был сложен CSS, JavaScript ещё сложнее. С этим можно поспорить, особенно если достать из нафталина IE 6,7 (IE5.5 не завалялся?) и показать, что CSS там ну совсем никакой. Да и в IE8 тоже есть забавные баги.
**Как правило, даже если CSS на вид сложнее -- поддерживать и развивать его проще, чем JS**. Поэтому овчинка стоит выделки.
Кроме того, есть ещё одно наблюдение.
[summary]
Знание JavaScript не может заменить знание CSS.
[/summary]
Жить становится приятнее и проще, если есть хорошее знание и CSS и JavaScript.
## Чек-лист
Ниже находится "чек-лист". Если хоть одно свойство незнакомо -- это стоп-сигнал для дальнейшего чтения этого раздела.
<ul>
<li>Блочная модель, включая:
<ul>
<li>`margin`, `padding`, `border`, `overflow`</li>
<li>а также `height/width` и `min-height/min-width`.</li>
</ul>
</li>
<li>Текст:
<ul>
<li>`font`</li><li>`line-height`.</li>
</ul></li>
<li>Различные курсоры `cursor`.</li>
<li>Позиционирование:
<ul><li>`position`, `float`, `clear`, `display`, `visibility`</li>
<li>Центрирование при помощи CSS</li>
<li>Перекрытие `z-index` и прозрачность `opacity`</li>
</ul>
</li>
<li>Cелекторы:
<ul><li>Приоритет селекторов</li>
<li>Селекторы `#id`, `.class`, `a > b`</li>
</ul>
</li>
<li>Сброс браузерных стилей, <a href="http://meyerweb.com/eric/tools/css/reset/">reset.css</a>
</li>
</ul>
## Почитать
Книжек много, но хороших -- как всегда, мало.
С уверенностью могу рекомендовать следующие:
<ul>
<li><a href="http://www.ozon.ru/context/detail/id/3881079/?partner=iliakan">CSS. Каскадные таблицы стилей. Подробное руководство. Эрик Мейер.</a>
<li><a href="http://www.ozon.ru/context/detail/id/5647176/?partner=iliakan">Большая книга CSS, Дэвид Макфарланд</a></li>
<li><a href="http://www.ozon.ru/context/detail/id/5510936/?partner=iliakan">CSS ручной работы, Дэн Седерхольм</a></li>
</ul>
Дальнейшие статьи раздела не являются *учебником* CSS, поэтому пожалуйста, изучите эту технологию до них. Это *очерки для лучшей систематизации и дополнения* уже существующих знаний.

View file

@ -0,0 +1,178 @@
# Свойство "box-sizing"
Свойство `box-sizing` может принимать одно из двух значений -- `border-box` или `content-box`. В зависимости от выбранного значения браузер по-разному трактует значение свойств `width/height`.
[cut]
## Значения box-sizing
<dl>
<dt>`content-box`</dt>
<dd>Это значение по умолчанию. В этом случае свойства `width/height` обозначают то, что находится *внутри `padding`*.</dd>
<dt>`border-box`</dt>
<dd>Значения `width/height` задают высоту/ширину *всего элемента*.</dd>
</dl>
Для большей наглядности посмотрим на картинку этого `div` в зависимости от `box-sizing`:
```css
div {
width: 200px;
height: 100px;
*!*
box-sizing: border-box (вверху) | content-box (внизу);
*/!*
padding: 20px;
border:5px solid brown;
}
```
<img src="border-box.png">
В верхнем случае браузер нарисовал весь элемент размером в `width x height`, в нижнем -- интерпретировал `width/height` как размеры внутренней области.
Исторически сложилось так, что по умолчанию принят `content-box`, а `border-box` некоторые браузеры используют если не указан `DOCTYPE`, в режиме совместимости.
Но есть как минимум один случай, когда явное указание `border-box` может быть полезно: растягивание элемента до ширины родителя.
## Пример: подстроить ширину к родителю
Задача: подогнать элемент по ширине внешнего элемента, чтобы он заполнял всё его пространство. Без привязки к конкретному размеру элемента в пикселях.
Например, мы хотим, чтобы элементы формы ниже были одинакового размера:
```html
<!--+ autorun -->
<style>
form {
width: 200px;
border: 2px solid green;
}
form input, form select {
display: block;
padding-left: 5px; /* padding для красоты */
}
</style>
<form>
*!*
<input>
<input>
<select><option>опции</option></select>
*/!*
</form>
```
Как сделать, чтобы элементы растянулись чётко по ширине `FORM`? Попробуйте добиться этого самостоятельно, перед тем как читать дальше.
### Попытка width:100%
Первое, что приходит в голову -- поставить всем `INPUT'ам` ширину `width: 100%`.
Попробуем:
```html
<!--+ autorun height=100 -->
<style>
form {
width: 200px;
border: 2px solid green;
}
form input, form select {
display: block;
padding-left: 5px;
*!*
width: 100%;
*/!*
}
</style>
<form>
<input>
<input>
<select><option>опции</option></select>
</form>
```
Как видно, не получается. **Элементы вылезают за пределы родителя.**
**Причина -- ширина элемента 100% по умолчанию относится к внутренней области, не включающей `padding` и `border`.** То есть, внутренняя область растягивается до `100%` родителя, и к ней снаружи прибавляются `padding/border`, которые и вылезают.
Есть два решения этой проблемы.
### Решение: дополнительный элемент
Можно убрать `padding/border` у элементов `INPUT/SELECT` и завернуть каждый из них в дополнительный `DIV`, который будет обеспечивать дизайн:
```html
<!--+ autorun height=100 -->
<style>
form {
width: 200px;
border: 2px solid green;
}
/* убрать padding/border */
form input, form select {
padding: 0;
border: 0;
width: 100%;
}
/* внешний div даст дизайн */
form div {
padding-left: 5px;
border: 1px solid black;
}
</style>
<form>
<div><input></div>
<div><input></div>
<div><select><option>опции</option></select></div>
</form>
```
В принципе, это работает. Но нужны дополнительные элементы. А если мы делаем дерево или большую редактируемую таблицу, да и вообще -- любой интерфейс, где элементов и так много, то лишние нам точно не нужны.
Кроме того, такое решение заставляет пожертвовать встроенным в браузер дизайном элементов `INPUT/SELECT`.
### Решение: box-sizing
Существует другой способ, гораздо более естественный, чем предыдущий.
**При помощи `box-sizing: border-box` мы можем сказать браузеру, что ширина, которую мы ставим, относится к элементу полностью, включая `border` и `padding`**:
```html
<!--+ autorun height=100 -->
<style>
form {
width: 200px;
border: 2px solid green;
}
form input, form select {
display: block;
padding-left: 5px;
*!*
-moz-box-sizing: border-box; /* в Firefox нужен префикс */
box-sizing: border-box;
width: 100%;
*/!*
}
</style>
<form>
<input>
<input>
<select><option>опции</option></select>
</form>
```
Мы сохранили "родную" рамку вокруг `INPUT/SELECT` и не добавили лишних элементов. Всё замечательно.
Свойство `box-sizing` поддерживается в IE начиная с версии 8.

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View file

@ -0,0 +1,5 @@
Ошибка заключается в том, что `margin` при задании в процентах высчитавается *относительно ширины*. Так написано [в стандарте](http://www.w3.org/TR/CSS2/box.html#margin-properties).
При этом не важно, какой отступ: левый, правый. верхний или нижний. Все они в процентах отсчитываются от ширины. Из-за этого и ошибка.
Ситуацию можно исправить, например, заданием `margin-top/margin-bottom` в пикселях, если это возможно или, в качестве альтернативы, использовать другие средства, в частности, `position` или `padding-top/padding-bottom` на родителе.

View file

@ -0,0 +1,43 @@
# Нерабочие margin?
[importance 3]
В примере ниже находится блок `.block` фиксированной высоты, а в нём -- прямоугольник `.spacer`.
При помощи `margin-left: 20%` и `margin-right: 20%`, прямоугольник центрирован в родителе по горизонтали. Это работает.
Далее делается попытка при помощи свойств `height: 80%`, `margin-top: 10%` и `margin-bottom: 10%` расположить прямоугольник в центре по вертикали, чтобы сам элемент занимал `80%` высоты родителя, а сверху и снизу был одинаковый отступ.
Однако, как видите, это не получается. Почему? Как поправить?
```html
<!--+ autorun run -->
<style>
.block {
height: 150px;
border: 1px solid #CCC;
background: #eee;
}
.spacer {
margin-left: 20%;
margin-right: 20%;
*!*
height: 80%;
margin-top: 10%;
margin-bottom: 10%;
*/!*
border: 1px solid black;
background: #FFF;
}
</style>
<div class="block">
<div class="spacer"></div>
</div>
```

View file

@ -0,0 +1,30 @@
# Подсказка
Надвиньте элемент с текстом на `INPUT` при помощи отрицательного `margin`.
# Решение
Надвинем текст на `INPUT` при помощи отрицательного `margin-top`. Поднять следует на одну строку, т.е. на `1.25em`, можно для красоты чуть больше -- `1.3em`:
Также нам понадобится обнулить "родной" `margin` у `INPUT`, чтобы не сбивал вычисления.
```html
<!--+ run -->
<style>
input {
*!*margin: 0;*/!*
width: 12em;
}
#placeholder {
color: red;
*!*
margin: -1.3em 0 0 0.2em;
*/!*
}
</style>
<input type="password" id="input">
<div id="placeholder">Скажи пароль, друг</div>
```
[edit src="solution"]Полный код решения[/edit]

View file

@ -0,0 +1,27 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
input {
margin: 0;
width: 12em;
}
#placeholder {
color: red;
margin: -1.3em 0 0 0.2em;
}
</style>
</head>
<body>
<div>Добро пожаловать</div>
<input type="password" id="input">
<div id="placeholder">Скажи пароль, друг</div>
<div>.. и заходи</div>
</body>
</html>

View file

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<div>Добро пожаловать</div>
<input type="password" id="input">
<div id="placeholder">Скажи пароль, друг</div>
<div>.. и заходи</div>
</body>
</html>

View file

@ -0,0 +1,15 @@
# Расположить текст внутри INPUT
[importance 5]
Создайте `<input type="password">` с цветной подсказкой внутри (должен правильно выглядеть, не обязан работать):
[iframe src="solution" height=90 border="1"]
В дальнейшем мы сможем при помощи JavaScript сделать, чтобы текст при клике пропадал. Получится красивая подсказка.
[edit src="source" task/]
P.S. Обратите внимание: `type="password"`! То есть, просто `value` использовать нельзя, будут звёздочки. Кроме того, подсказка, которую вы реализуете, может быть как угодно стилизована.
P.P.S. Вокруг `INPUT` с подсказкой не должно быть лишних отступов, блоки до и после продолжают идти в обычном потоке.

View file

@ -0,0 +1,170 @@
# Свойство "margin"
Свойство `margin` задаёт отступы вокруг элемента. У него есть несколько особенностей, которые мы здесь рассмотрим.
[cut]
## Объединение отступов
Вертикальные отступы поглощают друг друга, горизонтальные -- нет.
Например, вот документ с вертикальными и горизонтальными отступами:
```html
<!--+ autorun height=100 -->
<body style="background: #aef">
<p style="*!*margin:20px;*/!* background:white">
<span style="*!*margin:20px;*/!* background:orange">Горизонтальный 20px</span>
← 40px →
<span style="*!*margin:20px;*/!* background:orange">20px Отступ </span>
</p>
<p style="*!*margin:15px;*/!* background:white">Вертикальный 20px</p>
</body>
```
Расстояние по горизонтали между элементами `SPAN` равно `40px`, так как горизонтальные отступы по `20px` сложились.
А вот по вертикали расстояние от `SPAN` до `P` равно `20px`: из двух вертикальных отступов выбирается больший `max(20px, 15px) = 20px` и применяется.
## Отрицательные margin-top/left
Отрицательные значения `margin-top/margin-left` смещают элемент со своего обычного места.
В CSS есть другой способ добиться похожего эффекта -- а именно, `position:relative`. Но между ними есть одно принципиальное различие.
**При сдвиге через `margin` соседние элементы занимают освободившееся пространство, в отличие от `position: relative`, при котором элемент визуально сдвигается, но место, где он был, остается "занятым".**
То есть, элемент продолжает полноценно участвовать в потоке.
## Пример: вынос заголовка
Например, есть документ с информационными блоками:
```html
<!--+ autorun height=400 -->
<style>
div {
border: 1px solid blue;
margin: 2em;
font: .8em/1.25 Arial, sans-serif;
}
h2 {
background: #aef;
margin: 0 0 0.8em 0;
}
</style>
<div>
<h2>Общие положения</h2>
<p>Настоящие Правила дорожного движения устанавливают единый порядок дорожного движения на всей территории Российской Федерации. Другие нормативные акты, касающиеся дорожного движения, должны основываться на требованиях Правил и не противоречить им.</p>
</div>
<div>
<h2>Общие обязанности водителей</h2>
<p>Водитель механического транспортного средства обязан иметь при себе и по требованию сотрудников милиции передавать им для проверки:</p>
<ul>
<li>водительское удостоверение на право управления транспортным средством соответствующей категории;</li>
<li>...и так далее...</li>
</ul>
</div>
```
**Использование отрицательного `margin-top` позволяет вынести заголовки над блоком**.
```css
/* вверх чуть больше, чем на высоту строки (1.25em) */
h2 {
margin-top: -1.3em;
}
```
Результат:
[iframe src="h2-margin-top" height=330 border=1 link]
А вот, что бы было при использовании `position`:
```css
h2 {
position: relative;
top: -1.3em;
}
```
Результат:
[iframe src="h2-margin-top-position" height=330 border=1 link]
**При использовании `position`, в отличие от `margin`, на месте заголовков, внутри блоков, осталось пустое пространство.**
## Пример: вынос отчерка
Организуем информацию чуть по-другому. Пусть после каждого заголовка будет отчерк:
```html
<div>
<h2>Заголовок</h2>
<hr>
<p>Текст Текст Текст.</p>
</div>
```
Пример документа с такими отчерками:
[iframe src="hr-margin-left-src" height=320 border=1 link]
Для красоты мы хотим, чтобы отчерк `HR` начинался левее, чем основной текст. Отрицательный `margin-left` нам поможет:
```css
hr.margin { margin-left: -2em; }
/* для сравнения */
hr.position { position: relative; left: -2em; }
```
Результат:
[iframe src="hr-margin-left" height=320 border=1 link]
Обратите внимание на разницу между методами сдвига!
<ul>
<li>`hr.margin` сначала сдвинулся, а потом нарисовался до конца блока.</li>
<li>`hr.position` сначала нарисовался, а потом сдвинулся -- в результате справа осталось пустое пространство.</li>
</ul>
Уже отсюда видно, что отрицательные `margin` -- исключительно полезное средство позиционирования!
## Отрицательные margin-right/bottom
Отрицательные `margin-right/bottom` ведут себя по-другому, чем `margin-left/top`. Они не сдвигают элемент, а "укорачивают" его.
То есть, хотя сам размер блока не уменьшается, но следующий элемент будет думать, что он меньше на указанное в `margin-right/bottom` значение.
Например, в примере ниже вторая строка налезает на первую:
```html
<!--+ autorun height=80 -->
<div style="border: 1px solid blue; *!*margin-bottom: -0.5em*/!*">
Первый
</div>
<div style="border: 1px solid red">
Второй div думает, что высота первого на 0.5em меньше
</div>
```
Это используют, в частности для красивых вносок, с приданием иллюзии глубины.
Например:
[iframe src="negative-margin-bottom" border=1 height=200 link="Посмотреть в отдельном окне" edit]
## Итого
<ul>
<li>Отрицательные `margin-left/top` сдвигают элемент влево-вверх. Остальные элементы это учитывают, в отличие от сдвига через `position`.</li>
<li>Отрицательные `margin-right/bottom` заставляют другие элементы думать, что блок меньше по размеру справа-внизу, чем он на самом деле.</li>
<li>
Отличная статья на тему отрицательных `margin`: [The Definitive Guide to Using Negative Margins](http://coding.smashingmagazine.com/2009/07/27/the-definitive-guide-to-using-negative-margins/)

View file

@ -0,0 +1,41 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
div {
border: 1px solid blue;
margin: 2em;
font: .8em/1.25 Arial, sans-serif;
}
h2 {
margin: 0 0 0.8em 0;
background: #aef;
position: relative;
top: -1.3em;
}
</style>
</head>
<body>
<div>
<h2>Общие положения</h2>
<p>Настоящие Правила дорожного движения устанавливают единый порядок дорожного движения на всей территории Российской Федерации. Другие нормативные акты, касающиеся дорожного движения, должны основываться на требованиях Правил и не противоречить им.</p>
</div>
<div>
<h2>Общие обязанности водителей</h2>
<p>Водитель механического транспортного средства обязан иметь при себе и по требованию сотрудников милиции передавать им для проверки:</p>
<ul>
<li>водительское удостоверение на право управления транспортным средством соответствующей категории;</li>
<li>...и так далее...</li>
</ul>
</div>
</body>
</html>

View file

@ -0,0 +1,40 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
div {
border: 1px solid blue;
margin: 2em;
font: .8em/1.25 Arial, sans-serif;
}
h2 {
margin: 0 0 0.8em 0;
background: #aef;
margin-top: -1.3em; /* или изменить margin выше */
}
</style>
</head>
<body>
<div>
<h2>Общие положения</h2>
<p>Настоящие Правила дорожного движения устанавливают единый порядок дорожного движения на всей территории Российской Федерации. Другие нормативные акты, касающиеся дорожного движения, должны основываться на требованиях Правил и не противоречить им.</p>
</div>
<div>
<h2>Общие обязанности водителей</h2>
<p>Водитель механического транспортного средства обязан иметь при себе и по требованию сотрудников милиции передавать им для проверки:</p>
<ul>
<li>водительское удостоверение на право управления транспортным средством соответствующей категории;</li>
<li>...и так далее...</li>
</ul>
</div>
</body>
</html>

View file

@ -0,0 +1,38 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
div {
margin: 2em;
font: .8em/1.25 Arial, sans-serif;
}
h2 { margin-bottom: 0; }
</style>
</head>
<body>
<div>
<h2>Общие положения</h2>
<hr class="margin">
<p>Настоящие Правила дорожного движения устанавливают единый порядок дорожного движения на всей территории Российской Федерации. Другие нормативные акты, касающиеся дорожного движения, должны основываться на требованиях Правил и не противоречить им.</p>
</div>
<div>
<h2>Общие обязанности водителей</h2>
<hr class="position">
<p>Водитель механического транспортного средства обязан иметь при себе и по требованию сотрудников милиции передавать им для проверки:</p>
<ul>
<li>водительское удостоверение на право управления транспортным средством соответствующей категории;</li>
<li>...и так далее...</li>
</ul>
</div>
</body>
</html>

View file

@ -0,0 +1,40 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
div {
margin: 2em;
font: .8em/1.25 Arial, sans-serif;
}
h2 { margin-bottom: 0; }
hr.margin { margin-left: -2em; }
hr.position { position: relative; left: -2em; }
</style>
</head>
<body>
<div>
<h2>Общие положения (hr.margin)</h2>
<hr class="margin">
<p>Настоящие Правила дорожного движения устанавливают единый порядок дорожного движения на всей территории Российской Федерации. Другие нормативные акты, касающиеся дорожного движения, должны основываться на требованиях Правил и не противоречить им.</p>
</div>
<div>
<h2>Общие обязанности водителей (hr.position)</h2>
<hr class="position">
<p>Водитель механического транспортного средства обязан иметь при себе и по требованию сотрудников милиции передавать им для проверки:</p>
<ul>
<li>водительское удостоверение на право управления транспортным средством соответствующей категории;</li>
<li>...и так далее...</li>
</ul>
</div>
</body>
</html>

View file

@ -0,0 +1,41 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
.content {
background: #aef;
padding: 1em 2em 2em 2em;
margin-bottom: -1em;
}
.comment {
margin: 0 1em;
padding: .2em;
text-align: center;
background: black;
color: white;
}
</style>
</head>
<body>
<div>У DIV'а с холодильниками стоит margin-bottom: -1em</div>
<div class="content">
Наши холодильники - самые лучшие холодильники в мире!
Наши холодильники - самые лучшие холодильники в мире!
Наши холодильники - самые лучшие холодильники в мире!
Наши холодильники - самые лучшие холодильники в мире!
</div>
<span class="comment">
Так считают: 5 человек
</span>
<span class="comment">
Оставьте <u>свой</u> отзыв!
</span>
</body>
</html>

View file

@ -0,0 +1,119 @@
# Лишнее место под IMG
Иногда под `IMG` "вдруг" появляется лишнее место. Посмотрим на эти грабли внимательнее, почему такое бывает и как этого избежать.
[cut]
## Демонстрация проблемы
Например:
```html
<style> * { margin: 0; padding: 0; } </style>
<table>
<tr>
<td style="border:1px red solid">
<img src="square.png">
</td>
</tr>
</table>
```
[iframe src="inline"]
Посмотрите внимательно! Вы видите расстояние между рамками снизу? Это потому, что **браузер резервирует дополнительное место под инлайновым элементом, чтобы туда выносить "хвосты" букв**.
Вот так выглядит та же картинка с выступающим вниз символом рядом:
[iframe src="inline-p"]
В примере картинка обёрнута в красный `TD`. Таблица подстраивается под размер содержимого, так что проблема явно видна. Но она касается не только таблицы. Аналогичная ситуация возникнет, если вокруг `IMG` будет другой элемент с явно указанным размером, "облегающий" картинку по высоте. Браузер постарается зарезервировать место под `IMG`, хотя оно там не нужно.
## Решение: сделать элемент блочным
Самый лучший способ избежать этого -- поставить `display: block` таким картинкам:
```html
<style>
* { margin: 0; padding: 0; }
*!*
img { display: block }
*/!*
</style>
<table>
<tr>
<td style="border:1px red solid">
<img src="square.png">
</td>
</tr>
</table>
```
[iframe src="block"]
Под блочным элементом ничего не резервируется. Проблема исчезла.
## Решение: задать vertical-align
А что, если мы, по каким-то причинам, *не хотим* делать элемент блочным?
Существует ещё один способ избежать проблемы -- использовать свойство [vertical-align](http://www.w3.org/TR/CSS2/visudet.html#propdef-vertical-align).
**Если установить `vertical-align` в `top`, то инлайн-элемент будет отпозиционирован по верхней границе текущей строки.**
При этом браузер не будет оставлять место под изображением, так как запланирует продолжение строки сверху, а не снизу:
```html
<style>
* { margin: 0; padding: 0; }
*!*
img { vertical-align: top}
*/!*
</style>
<table>
<tr>
<td style="border:1px red solid">
<img src="square.png">
</td>
</tr>
</table>
```
[iframe src="valign"]
А вот, как браузер отобразит соседние символы в этом случае: `p<img src="square.png">p`
[iframe src="valign-p"]
С другой стороны, сама строка никуда не делась, изображение по-прежнему является её частью, а браузер планирует разместить другое текстовое содержимое рядом, хоть и сверху. Поэтому если изображение маленькое, то произойдёт дополнение пустым местом до высоты строки:
Например, для `<img src="square.png" style="height:10px">`:
[iframe src="valign-small"]
Таким образом, требуется уменьшить еще и `line-height` контейнера. Окончательное решение для маленьких изображений с `vertical-align`:
```html
<style>
* { margin: 0; padding: 0; }
*!*
td { line-height: 1px }
img { vertical-align: top }
*/!*
</style>
<table>
<tr>
<td style="border:1px red solid">
<img src="square.png" style="height:10px">
</td>
</tr>
</table>
```
Результат:
[iframe src="valign-small-lh"]
## Итого
<ul>
<li>Пробелы под картинками появляются, чтобы оставить место под "хвосты" букв в строке. Строка "подразумевается", т.к. `display:inline`.</li>
<li>Можно избежать пробела, если изменить `display`, например, на `block`.</li>
<li>Альтернатива: `vertical-align:top` (или `bottom`), но для маленьких изображений может понадобиться уменьшить `line-height`, чтобы контейнер не оставлял место под строку.</li>
</ul>

View file

@ -0,0 +1,23 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<style>
* { margin: 0; padding: 0; }
img { display: block; }
</style>
<table>
<tr>
<td style="border:1px red solid">
<img src="http://js.cx/clipart/square_50.png" width="50" height="50">
</td>
</tr>
</table>
</body>
</html>

View file

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<style> * { margin: 0; padding: 0; } </style>
<table>
<tr>
<td style="border:1px red solid; font-size:120%">
<img src="http://js.cx/clipart/square_50.png" width="50" height="50">p
</td>
</tr>
</table>
</body>
</html>

View file

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<style> * { margin: 0; padding: 0; } </style>
<table>
<tr>
<td style="border:1px red solid">
<img src="http://js.cx/clipart/square_50.png" width="50" height="50">
</td>
</tr>
</table>
</body>
</html>

View file

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<style> * { margin: 0; padding: 0; } </style>
<table>
<tr>
<td style="border:1px red solid">
p<img src="http://js.cx/clipart/square_50.png" width="50" height="50" style="vertical-align:top">p
</td>
</tr>
</table>
</body>
</html>

View file

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<style> * { margin: 0; padding: 0; } </style>
<table>
<tr>
<td style="border:1px red solid; line-height: 1px">
<img src="http://js.cx/clipart/square_50.png" width="10" height="10" style="vertical-align:top">
</td>
</tr>
</table>
</body>
</html>

View file

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<style> * { margin: 0; padding: 0; } </style>
<table>
<tr>
<td style="border:1px red solid">
<img src="http://js.cx/clipart/square_50.png" width="10" height="10" style="vertical-align:top">
</td>
</tr>
</table>
</body>
</html>

View file

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<style> * { margin: 0; padding: 0; } </style>
<table>
<tr>
<td style="border:1px red solid">
<img src="http://js.cx/clipart/square_50.png" width="50" height="50" style="vertical-align:top">
</td>
</tr>
</table>
</body>
</html>

View file

@ -0,0 +1,162 @@
# Свойство "overflow"
Свойство `overflow` управляет тем, как ведёт себя содержимое блочного элемента, если его размер превышает допустимую длину/ширину.
[cut]
Обычно блок увеличивается в размерах при добавлении в него элементов, заключая в себе всех потомков.
Но что, если высота/ширина указаны явно? Тогда блок не может увеличиться, и содержимое "переполняет" блок. Его отображение в этом случае задаётся свойством `overflow`.
Возможные значения
<ul>
<li>`visible` (по умолчанию)</li>
<li>`hidden`</li>
<li>`scroll`</li>
<li>`auto`</li>
</ul>
## visible
Если не ставить `overflow` явно или поставить `visible`, то содержимое отображается за границами блока.
Например:
```html
<!--+ autorun -->
<style>
.overflow {
*!*
/* overflow не задан */
*/!*
width: 200px;
height: 80px;
border: 1px solid black;
}
</style>
<div class="overflow">
visible ЭтотТекстВылезаетСправаЭтотТекстВылезаетСправа
Этот текст вылезает снизу Этот текст вылезает снизу
Этот текст вылезает снизу Этот текст вылезает снизу
</div>
```
Как правило, такое переполнение указывает на ошибку в вёрстке. Если содержимое может быть больше контейнера -- используют другие значения.
## hidden
Переполняющее содержимое не отображается.
```html
<!--+ autorun -->
<style>
.overflow {
*!*
overflow: hidden;
*/!*
width: 200px;
height: 80px;
border: 1px solid black;
}
</style>
<div class="overflow">
hidden ЭтотТекстОбрезанСправаЭтотТекстОбрезанСправа
Этот текст будет обрезан снизу Этот текст будет обрезан снизу
Этот текст будет обрезан снизу Этот текст будет обрезан снизу
</div>
```
Вылезающее за границу содержимое становится недоступно.
Это свойство иногда используют от лени, когда какой-то элемент дизайна немного вылезает за границу, и вместо исправления вёрстки его просто скрывают. Как правило, долго оно не живёт, вёрстку всё равно приходится исправлять.
## auto
При переполнении отображается полоса прокрутки.
```html
<!--+ autorun -->
<style>
.overflow {
*!*
overflow: auto;
*/!*
width: 200px;
height: 100px;
border: 1px solid black;
}
</style>
<div class="overflow">
auto ЭтотТекстДастПрокруткуСправаЭтотТекстДастПрокруткуСправа
Этот текст даст прокрутку снизу Этот текст даст прокрутку снизу
Этот текст даст прокрутку снизу
</div>
```
## scroll
Полоса прокрутки отображается всегда.
```html
<!--+ autorun -->
<style>
.overflow {
*!*
overflow: scroll;
*/!*
width: 200px;
height: 80px;
border: 1px solid black;
}
</style>
<div class="overflow">
scroll
Переполнения нет.
</div>
```
То же самое, что `auto`, но полоса прокрутки видна всегда, даже если переполнения нет.
## overflow-x, overflow-y
Можно указать поведение блока при переполнении по ширине в `overflow-x` и высоте -- в `overflow-y`:
```html
<!--+ autorun -->
<style>
.overflow {
*!*
overflow-x: auto;
overflow-y: hidden;
*/!*
width: 200px;
height: 80px;
border: 1px solid black;
}
</style>
<div class="overflow">
ПоШиринеПолосаПрокруткиAutoПоШиринеПолосаПрокруткиAuto
Этот текст вылезает снизу Этот текст вылезает снизу
Этот текст вылезает снизу Этот текст вылезает снизу
</div>
```
## Итого
Свойства `overflow-x/overflow-y` (или оба одновременно: `overflow`) задают поведение контейнера при переполнении:
<dl>
<dt>`visible`</dt>
<dd>По умолчанию, содержимое вылезает за границы блока.</dd>
<dt>`hidden`</dt>
<dd>Переполняющее содержимое невидимо.</dd>
<dt>`auto`</dt>
<dd>Полоса прокрутки при переполнении.</dd>
<dt>`scroll`</dt>
<dd>Полоса прокрутки всегда.</dd>
</dl>
Кроме того, значение `overflow: auto | hidden` изменяет поведение контейнера, содержащего `float'ы`. Так как элемент с `float` находится вне потока, то обычно контейнер не выделяет под него место. Но если стоит такой `overflow`, то место выделяется, т.е. контейнер растягивается. Более подробно этот вопрос рассмотрен в статье [](/float).

View file

@ -0,0 +1,140 @@
# Особенности свойства "height" в %
Обычно свойство `height`, указанное в процентах, означает высоту относительно внешнего блока.
Однако, всё не так просто. Интересно, что для произвольного блочного элемента `height` в процентах работать не будет!
[cut]
Чтобы лучше понимать ситуацию, рассмотрим пример.
## Пример
Наша цель -- получить вёрстку такого вида:
[iframe src="height-percent" height=160 link edit]
**При этом блок с левой стрелкой должен быть отдельным элементом внутри контейнера.**
Это удобно для интеграции с JavaScript, чтобы отлавливать на нём клики мыши.
То есть, HTML-код требуется такой:
```html
<div class="container">
<div class="toggler">
<!-- стрелка влево при помощи CSS, ширина фиксирована -->
</div>
<div class="content">
...Текст...
</div>
</div>
```
Как это реализовать? Подумайте перед тем, как читать дальше...
Придумали?... Если да -- продолжаем.
Есть разные варианты, но, возможно, вы решили сдвинуть `.toggler` влево, при помощи `float:left` (тем более что он фиксированной ширины) и увеличить до `height: 100%`, чтобы он занял всё пространство по вертикали.
**Вы ещё не видите подвох? Смотрим внимательно, что будет происходить с `height: 100%`...**
## Демо height:100% + float:left
CSS:
```css
.container {
border: 1px solid black;
}
.content {
*!*/* margin-left нужен, так как слева от содержимого будет стрелка */*/!*
margin-left: 35px;
}
.toggler {
*!*/* Зададим размеры блока со стрелкой */*/!*
height: 100%;
width: 30px;
float: left;
background: #EEE url("arrow_left.png") center center no-repeat;
border-right: #AAA 1px solid;
cursor: pointer;
}
```
А теперь -- посмотрим этот вариант в действии:
[iframe src="height-percent-float" height=160 link edit]
Как видно, блок со стрелкой вообще исчез! Куда же он подевался?
Ответ нам даст спецификация CSS 2.1 [пункт 10.5](http://www.w3.org/TR/CSS2/visudet.html#propdef-height).
**"Если высота внешнего блока вычисляется по содержимому, то высота в % не работает, и заменяется на `height:auto`. Кроме случая, когда у элемента стоит `position:absolute`."**
В нашем случае высота `.container` как раз определяется по содержимому, поэтому для `.toggler` проценты не действуют, а размер вычисляется как при `height:auto`.
Какая же она -- эта автоматическая высота? Вспоминаем, что обычно размеры `float` определяются по содержимому ([10.3.5](http://www.w3.org/TR/CSS2/visudet.html#float-width)). А содержимого-то в `.toggler` нет, так что высота нулевая. Поэтому этот блок и не виден.
Если бы мы точно знали высоту внешнего блока и добавили её в CSS -- это решило бы проблему.
Например:
```css
.container {
height: 200px; /* теперь height в % внутри будет работать */
}
```
Результат:
[iframe src="height-percent-float-exact" height="230" link edit]
...Но в данном случае этот путь неприемлем! Ведь мы не знаем, сколько будет текста и какой будет итоговая высота.
Поэтому решим задачу по-другому.
## Правильно: height:100% + position:absolute
Проценты будут работать, если поставить `.toggler` свойство `position: absolute` и спозиционировать его в левом-верхнем углу `.container` (у которого сделать `position:relative`):
```css
.container {
*!*position: relative;*/!*
border: 1px solid black;
}
.content {
margin-left: 35px;
}
.toggler {
*!*
position: absolute;
left: 0;
top: 0;
*/!*
height: 100%;
width: 30px;
cursor: pointer;
border-right: #AAA 1px solid;
background: #EEE url("arrow_left.png") center center no-repeat;
}
```
Результат:
[iframe src="height-percent" height=160 link edit]
## Итого
<ul>
<li>Свойство `height`, указанное в %, работает только если для внешнего блока указана высота.</li>
<li>Стандарт CSS 2.1 предоставляет обход этой проблемы, отдельно указывая, что проценты работают при `position:absolute`. На практике это часто выручает.
</li>
</ul>

View file

@ -0,0 +1,41 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
.container {
border: 1px solid black;
height: 200px;
}
.toggler {
height: 100%;
background: #EEE url(http://js.cx/height-percent/arrow_left.png) center center no-repeat;
border-right: #AAA 1px solid;
width: 30px;
float: left;
margin-le
cursor: pointer;
}
.content {
margin-left: 35px;
}
p { font-size: 80%; }
</style>
</head>
<body>
<div class="container">
<div class="toggler"></div>
<div class="content">
<p>Ви́нни-Пу́х (англ. Winnie-the-Pooh) — плюшевый мишка, персонаж повестей и стихов Алана Александра Милна (цикл не имеет общего названия и обычно тоже называется «Винни-Пух», по первой книге). Один из самых известных героев детской литературы XX века.</p>
<p>В 1960-е—1970-е годы, благодаря пересказу Бориса Заходера «Винни-Пух и все-все-все», а затем и фильмам студии «Союзмультфильм», где мишку озвучивал Евгений Леонов, Винни-Пух стал очень популярен и в Советском Союзе.</p>
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,40 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
.container {
border: 1px solid black;
}
.toggler {
height: 100%;
background: #EEE url(http://js.cx/height-percent/arrow_left.png) center center no-repeat;
border-right: #AAA 1px solid;
width: 30px;
float: left;
cursor: pointer;
}
.content {
margin-left: 35px;
}
p { font-size: 80%; }
</style>
</head>
<body>
<div class="container">
<div class="toggler"></div>
<div class="content">
<p>Ви́нни-Пу́х (англ. Winnie-the-Pooh) — плюшевый мишка, персонаж повестей и стихов Алана Александра Милна (цикл не имеет общего названия и обычно тоже называется «Винни-Пух», по первой книге). Один из самых известных героев детской литературы XX века.</p>
<p>В 1960-е—1970-е годы, благодаря пересказу Бориса Заходера «Винни-Пух и все-все-все», а затем и фильмам студии «Союзмультфильм», где мишку озвучивал Евгений Леонов, Винни-Пух стал очень популярен и в Советском Союзе.</p>
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,42 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
.container {
border: 1px solid black;
position: relative;
}
.content {
margin-left: 35px;
}
.toggler {
height: 100%;
background: #EEE url(http://js.cx/height-percent/arrow_left.png) center center no-repeat;
border-right: #AAA 1px solid;
width: 30px;
position: absolute;
left: 0;
top: 0;
cursor: pointer;
}
p { font-size: 80%; }
</style>
</head>
<body>
<div class="container">
<div class="toggler"></div>
<div class="content">
<p>Ви́нни-Пу́х (англ. Winnie-the-Pooh) — плюшевый мишка, персонаж повестей и стихов Алана Александра Милна (цикл не имеет общего названия и обычно тоже называется «Винни-Пух», по первой книге). Один из самых известных героев детской литературы XX века.</p>
<p>В 1960-е—1970-е годы, благодаря пересказу Бориса Заходера «Винни-Пух и все-все-все», а затем и фильмам студии «Союзмультфильм», где мишку озвучивал Евгений Леонов, Винни-Пух стал очень популярен и в Советском Союзе.</p>
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,76 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<input type="checkbox">
<input type="checkbox" checked>
<input type="text" id="message">
<h3 id="widget-title">Сообщения:</h3>
<ul id="messages">
<li id="message-1">Сообщение 1</li>
<li id="message-2">Сообщение 2</li>
<li id="message-3" data-action="delete">Сообщение 3</li>
<li id="message-4" data-action="edit do-not-delete">Сообщение 4</li>
<li id="message-5" data-action="edit delete">Сообщение 5</li>
<li><a href="#">...</a></li>
</ul>
<a href="http://site.com/list.zip">Ссылка на архив</a>
<a href="http://site.com/list.pdf">..И на PDF</a>
<script>
// тестовая функция для селекторов
// проверяет, чтобы элементов по селектору selector было ровно count
function test(selector, count) {
var elems = document.querySelectorAll(selector);
var ok = (elems.length == count);
if (!ok) alert(selector+": " + elems.length + " != " + count);
}
// ------------- селекторы --------------
// Выбрать input типа checkbox
test('input[type="checkbox"]', 1);
// Выбрать input типа checkbox, НЕ отмеченный
test('input[type="checkbox"]:not(:checked)', 1);
// Найти все элементы с id=message или message-*
test('[id|="message"]', 6);
// Найти все элементы с id=message-*
test('[id^="message-"]', 5);
// Найти все ссылки с расширением href="...zip"
test('a[href$=".zip"]', 1);
// Найти все элементы с data-action, содержащим delete в списке (через пробел)
test('[data-action~="delete"]', 2);
// Найти все элементы, у которых ЕСТЬ атрибут data-action,
// но он НЕ содержащит delete в списке (через пробел)
test('[data-action]:not([data-action~="delete"])', 1);
// Выбрать все чётные элементы списка #messages
test('#messages li:nth-child(2n)', 3);
// Выбрать один элемент сразу за заголовком h3#widget-title
// на том же уровне вложенности
test('h3#widget-title + *', 1);
// Выбрать все ссылки, следующие за заголовком h3#widget-title
// на том же уровне вложенности
test('h3#widget-title ~ a', 2);
// Выбрать ссылку внутри последнего элемента списка #messages
test('#messages li:last-child a', 1);
</script>
</body>
</html>

View file

@ -0,0 +1,6 @@
```html
<!--+ src="index.html" -->
```

View file

@ -0,0 +1,84 @@
<!DOCTYPE HTML>
<html>
<head><meta charset="utf-8"></head>
<body>
<input type="checkbox">
<input type="checkbox" checked>
<input type="text" id="message">
<h3 id="widget-title">Сообщения:</h3>
<ul id="messages">
<li id="message-1">Сообщение 1</li>
<li id="message-2">Сообщение 2</li>
<li id="message-3" data-action="delete">Сообщение 3</li>
<li id="message-4" data-action="edit do-not-delete">Сообщение 4</li>
<li id="message-5" data-action="edit delete">Сообщение 5</li>
<li><a href="#">...</a></li>
</ul>
<a href="http://site.com/list.zip">Ссылка на архив</a>
<a href="http://site.com/list.pdf">..И на PDF</a>
<script>
/**
* Функция test(selector, count) находит элементы по селектору
* и сравнивает их число с count.
*
* Иными словами, вызовы ниже проверяют,
* что число элементов по селектору - правильное
**/
test('input', 3); // далее вместо '...' вставьте правильные селекторы
// Выбрать input типа checkbox
test('...', 1);
// Выбрать input типа checkbox, НЕ отмеченный
test('...', 1);
// Найти все элементы с id=message или message-*
test('...', 6);
// Найти все элементы с id=message-*
test('...', 5);
// Найти все ссылки с расширением href="...zip"
test('...', 1);
// Найти все элементы с data-action, содержащим delete в списке (через пробел)
test('...', 2);
// Найти все элементы, у которых ЕСТЬ атрибут data-action,
// но он НЕ содержит delete в списке (через пробел)
test('...', 1);
// Выбрать все чётные элементы списка #messages
test('...', 3);
// Выбрать один элемент сразу за заголовком h3#widget-title
// на том же уровне вложенности
test('...', 1);
// Выбрать все ссылки, следующие за заголовком h3#widget-title
// на том же уровне вложенности
test('...', 2);
// Выбрать ссылку внутри последнего элемента списка #messages
test('...', 1);
function test(selector, count) {
if (selector === '...') return;
var elems = document.querySelectorAll(selector);
var ok = (elems.length == count);
if (!ok) alert(selector+": " + elems.length + " != " + count);
}
</script>
</body>
</html>

View file

@ -0,0 +1,42 @@
# Выберите элементы селектором
[importance 5]
HTML-документ:
```html
<input type="checkbox">
<input type="checkbox" checked>
<input type="text" id="message">
<h3 id="widget-title">Сообщения:</h3>
<ul id="messages">
<li id="message-1">Сообщение 1</li>
<li id="message-2">Сообщение 2</li>
<li id="message-3" data-action="delete">Сообщение 3</li>
<li id="message-4" data-action="edit do-not-delete">Сообщение 4</li>
<li id="message-5" data-action="edit delete">Сообщение 5</li>
<li><a href="#">...</a></li>
</ul>
<a href="http://site.com/list.zip">Ссылка на архив</a>
<a href="http://site.com/list.pdf">..И на PDF</a>
```
Задания:
<ol>
<li>Выбрать `input` типа `checkbox`.</li>
<li>Выбрать `input` типа `checkbox`, НЕ отмеченный.</li>
<li>Найти все элементы с `id=message` или `message-*`.</li>
<li>Найти все элементы с `id=message-*`.</li>
<li>Найти все ссылки с расширением `href="...zip"`.</li>
<li>Найти все элементы с атрибутом `data-action`, содержащим `delete` в списке (через пробел).</li>
<li>Найти все элементы, у которых ЕСТЬ атрибут `data-action`, но он НЕ содержит `delete` в списке (через пробел).</li>
<li>Выбрать все чётные элементы списка `#messages`.</li>
<li>Выбрать один элемент сразу за заголовком `h3#widget-title` на том же уровне вложенности.</li>
<li>Выбрать все ссылки, следующие за заголовком `h3#widget-title` на том же уровне вложенности.</li>
<li>Выбрать ссылку внутри последнего элемента списка `#messages`.</li>
</ol>
[edit src="source"]Исходный документ с вспомогательной функцией `test` для проверки[/edit]

View file

@ -0,0 +1,30 @@
# Выбор элементов
Для выбора элементов, начиная с первого, можно использовать селектор [nth-child](http://css-tricks.ru/Articles/Details/HowNthChildWorks).
Его вид: `li:nth-child(n+2)`, т.к. `n` идёт от нуля, соответственно первым будет второй элемент (`n=0`), что нам и нужно.
# Решение
Отступ, размером в одну строку, при `line-height: 1.5` -- это `1.5em`.
Правило:
```css
li:nth-child(n+2) {
margin-top: 1.5em;
}
```
Полный код [edit src="solution"]в песочнице[/edit].
# Ещё решение
Ещё один вариант селектора: `li + li`
```css
li + li {
margin-top: 1.5em;
}
```

View file

@ -0,0 +1,32 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
body {
font: 14px/1.5 Georgia, serif;
}
ul {
margin: 0;
}
li:nth-child(n+2) {
margin-top: 1.5em;
}
</style>
</head>
<body>
Текст вверху без отступа от списка.
<ul>
<li>Маша</li>
<li>Паша</li>
<li>Даша</li>
<li>Женя</li>
<li>Саша</li>
<li>Гоша</li>
</ul>
Текст внизу без отступа от списка.
</body>
</html>

View file

@ -0,0 +1,28 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
body {
font: 14px/1.5 Georgia, serif;
}
ul {
margin: 0;
}
</style>
</head>
<body>
Текст вверху без отступа от списка.
<ul>
<li>Маша</li>
<li>Паша</li>
<li>Даша</li>
<li>Женя</li>
<li>Саша</li>
<li>Гоша</li>
</ul>
Текст внизу без отступа от списка.
</body>
</html>

View file

@ -0,0 +1,38 @@
# Отступ между элементами, размер одна строка
[importance 4]
Есть список `UL/LI`.
```html
Текст вверху без отступа от списка.
<ul>
<li>Маша</li>
<li>Паша</li>
<li>Даша</li>
<li>Женя</li>
<li>Саша</li>
<li>Гоша</li>
</ul>
Текст внизу без отступа от списка.
```
Размеры шрифта и строки заданы стилем:
```css
body {
font: 14px/1.5 Georgia, serif;
}
```
**Сделайте, чтобы между элементами был вертикальный отступ.**
<ul>
<li>Размер отступа: ровно 1 строка.</li>
<li>Нужно добавить только одно правило CSS с одним псевдоселектором, можно использовать CSS3.</li>
<li>Не должно быть лишних отступов сверху и снизу списка.</li>
</ul>
Результат:
[iframe src="solution" border=1 link]
[edit src="source" task/]

View file

@ -0,0 +1,32 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
body {
font: 14px/1.5 Georgia, serif;
}
ul {
margin: 0;
}
li:nth-child(odd):not(:first-child) {
margin-top: 1.5em;
}
</style>
</head>
<body>
Текст вверху без отступа от списка.
<ul>
<li>Маша</li>
<li>Паша</li>
<li>Даша</li>
<li>Женя</li>
<li>Саша</li>
<li>Гоша</li>
</ul>
Текст внизу без отступа от списка.
</body>
</html>

View file

@ -0,0 +1,26 @@
# Селектор
Для отступа между парами, то есть перед каждым нечётным элементом, можно использовать селектор [nth-child](http://css-tricks.ru/Articles/Details/HowNthChildWorks).
Селектор будет `li:nth-child(odd)`, к нему нужно ещё добавить отсечение первого элемента: `li:nth-child(odd):not(:first-child)`.
Можно поступить и по-другому: `li:nth-child(2n+3)` выберет все элементы для `n=0,1,2...`, то есть 3й, 5й и далее, те же, что и предыдущий селектор. Немного менее очевидно, зато короче.
# Правило
Отступ, размером в одну строку, при `line-height: 1.5` -- это `1.5em`.
Поставим отступ перед каждым *нечётным* элементом, кроме первого:
```css
li:nth-child(odd):not(:first-child) {
margin-top: 1.5em;
}
```
Получится так:
```html
<!--+ run src="index.html" -->
```

View file

@ -0,0 +1,32 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
body {
font: 14px/1.5 Georgia, serif;
}
ul {
margin: 0;
}
li:nth-child(odd):not(:first-child) {
margin-top: 1.5em;
}
</style>
</head>
<body>
Текст вверху без отступа от списка.
<ul>
<li>Маша</li>
<li>Паша</li>
<li>Даша</li>
<li>Женя</li>
<li>Саша</li>
<li>Гоша</li>
</ul>
Текст внизу без отступа от списка.
</body>
</html>

View file

@ -0,0 +1,28 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
body {
font: 14px/1.5 Georgia, serif;
}
ul {
margin: 0;
}
</style>
</head>
<body>
Текст вверху без отступа от списка.
<ul>
<li>Маша</li>
<li>Паша</li>
<li>Даша</li>
<li>Женя</li>
<li>Саша</li>
<li>Гоша</li>
</ul>
Текст внизу без отступа от списка.
</body>
</html>

View file

@ -0,0 +1,38 @@
# Отступ между парами, размером со строку
[importance 4]
Есть список `UL/LI`.
```html
Текст вверху без отступа от списка.
<ul>
<li>Маша</li>
<li>Паша</li>
<li>Даша</li>
<li>Женя</li>
<li>Саша</li>
<li>Гоша</li>
</ul>
Текст внизу без отступа от списка.
```
Размеры шрифта и строки заданы стилем:
```css
body {
font: 14px/1.5 Georgia, serif;
}
```
**Сделайте, чтобы между каждой парой элементов был вертикальный отступ.**
<ul>
<li>Размер отступа: ровно 1 строка.</li>
<li>Нужно добавить только одно правило CSS, можно использовать CSS3.</li>
<li>Не должно быть лишних отступов сверху и снизу списка.</li>
</ul>
Результат:
[iframe src="solution" border=1 link]
[edit src="source" task/]

View file

@ -0,0 +1,255 @@
# Знаете ли вы селекторы?
CSS3-селекторы -- фундаментально полезная вещь.
Даже если вы почему-то (старый IE?) не пользуетесь ими в CSS, есть много фреймворков для их кросс-браузерного использования CSS3 из JavaScript.
Поэтому эти селекторы необходимо знать.
[cut]
## Основные виды селекторов
Основных видов селекторов всего несколько:
<ul>
<li>`*` -- любые элементы.</li>
<li>`div` -- элементы с таким тегом.</li>
<li>`#id` -- элемент с данным `id`.</li>
<li>`.class` -- элементы с таким классом.</li>
<li>`[name="value"]` -- селекторы на атрибут (см. далее).</li>
<li>`:visited` -- "псевдоклассы", остальные разные условия на элемент (см. далее).</li>
</ul>
**Селекторы можно комбинировать, записывая последовательно, без пробела:**
<ul>
<li>`.c1.c2` -- элементы одновременно с двумя классами `c1` и `c2`</li>
<li>`a#id.c1.c2:visited` -- элемент `a` с данным `id`, классами `c1` и `c2`, и псевдоклассом `visited`</li>
</ul>
## Отношения
В CSS3 предусмотрено четыре вида отношений между элементами.
Самые известные вы наверняка знаете:
<ul>
<li>`div p` -- элементы `p`, являющиеся потомками `div`.</li>
<li>`div > p` -- только непосредственные потомки</li>
</ul>
Есть и два более редких:
<ul>
<li>`div ~ p` -- правые соседи: все `p` на том же уровне вложенности, которые идут после `div`.</li>
<li>`div + p` -- первый правый сосед: `p` на том же уровне вложенности, который идёт сразу после `div` (если есть).</li>
</ul>
Посмотрим их на примере HTML:
```html
<h3>Балтославянские языки</h3>
<ol id="languages">
...Вложенный OL/LI список языков...
</ol>
```
CSS-селекторы:
```css
##languages li {
color: brown; /* потомки #languages, подходящие под селектор LI */
}
##languages > li {
color: black; /* первый уровень детей #languages подходящих под LI */
}
##e-slavic { font-style: italic; }
*!*
##e-slavic ~ li { /* правые соседи #e-slavic с селектором LI */
color: red;
}
*/!*
##latvian {
font-style: italic;
}
##latvian * { /* потомки #latvian, подходяще под * (т.е. любые) */
font-style: normal;
}
*!*
##latvian + li { /* первый правый сосед #latvian с селектором LI */
color: green;
}
*/!*
```
Результат:
[iframe src="relation" border="1" edit link]
## Фильтр по месту среди соседей
При выборе элемента можно указать его место среди соседей.
Список псевдоклассов для этого:
<ul>
<li>`:first-child` -- первый потомок своего родителя.</li>
<li>`:last-child` -- последний потомок своего родителя.</li>
<li>`:only-child` -- единственный потомок своего родителя, соседних элементов нет.</li>
<li>`:nth-child(a)` -- потомок номер `a` своего родителя, например `:nth-child(2)` -- второй потомок. Нумерация начинается с `1`.</li>
<li>`:nth-child(an+b)` -- расширение предыдущего селектора через указание номера потомка формулой, где `a,b` -- константы, а под `n` подразумевается любое целое число.
Этот псевдокласс будет фильтровать все элементы, которые попадают под формулу при каком-либо `n`. Например:
<ul>
<li>`:nth-child(2n)` даст элементы номер `2`, `4`, `6`..., то есть чётные.</li>
<li>`:nth-child(2n+1)` даст элементы номер `1`, `3`..., то есть нечётные.</li>
<li>`:nth-child(3n+2)` даст элементы номер `2`, `5`, `8` и так далее.</li>
</ul>
</li>
</ul>
Пример использования для выделения в списке:
[iframe src="nthchild" border="1" edit link]
```css
/*+ hide="CSS к примеру выше" */
li:nth-child(2n) { /* чётные */
background: #eee;
}
li:nth-child(3) { /* 3-ий потомок */
color: red;
}
```
<ul>
<li>`:nth-last-child(a)`, `:nth-last-child(an+b)` -- то же самое, но отсчёт начинается с конца, например `:nth-last-child(2)` -- второй элемент с конца.</li>
</ul>
## Фильтр по месту среди соседей с тем же тегом
Есть аналогичные псевдоклассы, которые учитывают не всех соседей, а только с тем же тегом:
<ul>
<li>`:first-of-type`</li>
<li>`:last-of-type`</li>
<li>`:only-of-type`</li>
<li>`:nth-of-type`</li>
<li>`:nth-last-of-type`</li>
</ul>
Они имеют в точности тот же смысл, что и обычные `:first-child`, `:last-child` и так далее, но во время подсчёта игнорируют элементы с другими тегами, чем тот, к которому применяется фильтр.
Пример использования для раскраски списка `DT` "через один" и предпоследнего `DD`:
[iframe src="nthchild-type" border="1" edit link]
```css
/*+ hide="CSS к примеру выше" */
dt:nth-of-type(2n) {
/* чётные dt (соседи с другими тегами игнорируются) */
background: #eee;
}
dd:nth-last-of-type(2) {
/* второй dd снизу */
color: red;
}
```
Как видим, селектор `dt:nth-of-type(2n)` выбрал каждый второй элемент `dt`, причём другие элементы (`dd`) в подсчётах не участвовали.
## Селекторы атрибутов
<dl>
<dt>На атрибут целиком</dt>
<dd>
<ul>
<li>`[attr]` -- атрибут установлен,</li>
<li>`[attr="val"]` -- атрибут равен `val`.</li>
</ul>
</dd>
<dt>На начало атрибута</dt>
<dd>
<ul>
<li>`[attr^="val"]` -- атрибут начинается с `val`, например `"value"`.</li>
<li>`[attr|="val"]` -- атрибут равен `val` *или* начинается с `val-`, например равен `"val-1"`.</li>
</ul>
</dd>
<dt>На содержание</dd>
<dd>
<ul>
<li>`[attr*="val"]` -- атрибут содержит подстроку `val`, например равен `"myvalue"`.</li>
<li>`[attr~="val"]` -- атрибут содержит `val` как одно из значений через пробел.
Например: `[attr~="delete"]` верно для `"edit delete"` и неверно для `"undelete"` или `"no-delete"`.</li>
</ul>
</dd>
<dt>На конец атрибута</dt>
<dd>
<ul>
<li>`[attr$="val"]` -- атрибут заканчивается на `val`, например равен `"myval"`.</li>
</ul>
</dd>
</dl>
## Другие псевдоклассы
<ul>
<li>`:not(селектор)` -- все, кроме подходящих под селектор.</li>
<li>`:focus` -- в фокусе.</li>
<li>`:hover` -- под мышью.</li>
<li>`:empty` -- без детей (даже без текстовых).</li>
<li>`:checked`, `:disabled`, `:enabled` -- состояния `INPUT`.</li>
<li>`:target` -- этот фильтр сработает для элемента, `ID` которого совпадает с анкором `#...` текущего URL.
Например, если на странице есть элемент с `id="intro"`, то правило `:target { color: red }` подсветит его в том случае, если текущий URL имеет вид `http://...#intro`.
</li>
</ul>
## Псевдоэлементы ::before, ::after
"Псевдоэлементы" -- различные вспомогательные элементы, которые браузер записывает или может записать в документ.
При помощи *псевдоэлементов* `::before` и `::after` можно добавлять содержимое в начало и конец элемента:
```html
<!--+ autorun -->
<style>
li::before {
content: " [[ ";
}
li::after {
content: " ]] ";
}
</style>
Обратите внимание: содержимое добавляется <b>внутрь</b> LI.
<ul>
<li>Первый элемент</li>
<li>Второй элемент</li>
</ul>
```
Псевдоэлементы `::before`/`::after` добавили содержимое в начало и конец каждого `LI`.
[smart header="`:before` или `::before`?"]
Когда-то все браузеры реализовали эти псевдоэлементы с одним двоеточием: `:after/:before`.
Стандарт с тех пор изменился и сейчас все, кроме IE8, понимают также современную запись с двумя двоеточиями. А для IE8 нужно по-прежнему одно.
Поэтому если вам важна поддержка IE8, то имеет смысл использовать одно двоеточие.
Версии IE7- не понимают этих селекторов.
[/smart]
## Практика
Вы можете использовать информацию выше как справочную для решения задач ниже, которые уже реально покажут, владеете вы CSS-селекторами или нет.

View file

@ -0,0 +1,38 @@
<!DOCTYPE HTML>
<html>
<head>
<style>
dt:nth-of-type(2n) {
/* чётные dt (соседи с другими тегами игнорируются) */
background: #eee;
}
dd:nth-last-of-type(2) {
/* второй dd снизу */
color: red;
}
code {
border: 1px solid black;
}
</style>
</head>
<body>
<dl>
<dt>Первый dt</dt>
<dd>Описание dd</dd>
<dt>Второй dt <code>dt:nth-of-type(2n)</code></dt>
<dd>Описание dd</dd>
<dt>Третий dt</dt>
<dd>Описание dd <code>dd:nth-last-of-type(2)</code></dd>
<dt>Четвёртый dt <code>dt:nth-of-type(2n)</code></dt>
<dd>Описание dd</dd>
</dl>
</body>
</html>

View file

@ -0,0 +1,32 @@
<!DOCTYPE HTML>
<html>
<head>
<style>
li:nth-child(2n) { /* чётные */
background: #eee;
}
li:nth-child(3) { /* 3-ий потомок */
color: red;
}
code {
border: 1px solid black;
}
</style>
</head>
<body>
<ul>
<li>Древнерусский язык</li>
<li>Древненовгородский диалект <code>li:nth-child(2n)</code></li>
<li>Западнорусский письменный язык <code>li:nth-child(3)</code></li>
<li>Украинский язык <code>li:nth-child(2n)</code></li>
<li>Белорусский язык</li>
<li>Другие языки <code>li:nth-child(2n)</code></li>
</ul>
</body>
</html>

View file

@ -0,0 +1,59 @@
<!DOCTYPE HTML>
<html>
<head>
<style>
#languages li {
color: brown;
}
#languages > li {
color: black;
}
#e-slavic { font-style: italic; }
#e-slavic ~ li {
color: red;
}
#latvian { font-style: italic; }
#latvian * { font-style: normal }
#latvian + li {
color: green;
}
code {
border: 1px solid black;
}
</style>
</head>
<body>
<h3>Балтославянские языки</h3>
<ol id="languages">
<li>Славянские языки
<ol>
<li>Славянские микроязыки</li>
<li>Праславянский язык</li>
<li id="e-slavic">Восточнославянские языки <code>#e-slavic</code></li>
<li>Западнославянские языки <code>#e-slavic ~ li</code></li>
<li>Южнославянские языки <code>#e-slavic ~ li</code></li>
<li> ... <code>#e-slavic ~ li</code></li>
</ol>
</li>
<li>Балтийские языки
<ol>
<li>Литовский язык</li>
<li id="latvian">Латышский язык <code>#latvian</code>
<ol><li>Латгальский язык <code>#latvian *</code></li></ol>
</li>
<li>Прусский язык <code>#latvian + li </code></li>
<li>... (следующий элемент уже не <code>#latvian + li</code>)</li>
</ol>
</li>
</ol>
</body>
</html>

View file

@ -0,0 +1,46 @@
# CSS без IE6(7)
CSS-возможности, которыми мы можем пользоваться, если НЕ поддерживаем IE6.
[cut]
<dl>
<dt>Селекторы атрибутов:</dt>
<dd>
<ul>
<li>`[attr]` -- атрибут установлен,</li>
<li>`[attr="val"]` -- атрибут равен `val`,</li>
<li>`[attr^="val"]` -- атрибут начинается с `val`, например `"value"`.</li>
<li>`[attr*="val"]` -- атрибут содержит `val`, например равен `"myvalue"`.</li>
<li>`[attr$="val"]` -- атрибут заканчивается на `val`, например равен `"myval"`.</li>
<li>`[attr~="val"]` -- атрибут содержит `val` как одно из значений через пробел, например: `[data-actions~="edit"]` верно для значения `data-actions="edit delete"`.</li>
<li>`[attr|="val"]` -- атрибут равен `val` *или* начинается с `val-`, например равен `"val-1"`.</li>
</ul>
</dd>
<dt>Селекторы элементов:</dt>
<dd>
<ul>
<li>`ul > li` -- непосредственный потомок,</li>
<li>`.prev + .me` -- выбирает `.me`, которые стоят сразу после `.prev`, т.е. "правый брат".</li>
<li>`.prev ~ .me` -- выбирает `.me`, которые стоят после `.prev`, но не обязательно сразу после, между ними могут быть другие элементы,</li>
<li>`.a.b` -- несколько классов одновременно,</li>
<li>`:hover` -- курсор над элементом (в IE6 работает только с `A`),
<li>`:first-child` -- первый потомок в своём родителе.</li>
</ul>
Внимание, IE7 не пересчитывает стили при изменении окружающих элементов для селекторов `.prev + .me`, `.prev` и `:first-child`. Иными словами, не обновляет стиль при добавлении/удалении соседей через JavaScript.
</dd>
<dt>Свойства: </dt>
<dd>
<ul>
<li>`min-width/min-height` -- минимальная ширина/высота</li>
<li>`max-width/max-height` -- максимальная ширина/высота</li>
<li>`position: fixed`</li>
</ul>
</dd>
</dl>
Здесь перечислены в основном возможности. Разумеется, была поправлена и масса багов.
При отказе от поддержки IE7, и, тем более, IE8, список ещё шире и включает в себя почти весь CSS 2.1.

Binary file not shown.

After

Width:  |  Height:  |  Size: 562 B

View file

@ -0,0 +1,203 @@
# CSS-спрайты
CSS-спрайт -- способ объединить много изображений в одно, чтобы:
<ol>
<li>Cократить количество обращений к серверу.</li>
<li>Загрузить несколько изображений сразу, включая те, которые понадобятся в будущем.</li>
<li>Если у изображений сходная палитра, то объединённое изображение будет меньше по размеру, чем совокупность исходных картинок.</li>
</ol>
[cut]
Рассмотрим, как это работает, на примере дерева:
```html
<ul>
<li class="open">
<div class="icon"></div>
<div class="text">Раздел 1<br>В две строки</div>
<ul>
<li class="closed">
<div class="icon"></div>
<div class="text">Раздел 1.1 в одну строку</div>
</li>
<li class="leaf">
<div class="icon"></div>
<div class="text">Страница 1.2<br> в две строки</div>
</li>
</ul>
</li>
<li class="closed">
<div class="icon"></div>
<div class="text">Раздел 2<br>В две строки</div>
</li>
</ul>
```
[iframe src="sprite-tree-src" border=1 height=200 link edit]
Сейчас "плюс", "минус" и "статья" -- три отдельных изображения. Объединим их в спрайт.
## Шаг 1. Использовать background
Первый шаг к объединению изображений в "спрайт" -- показывать их через `background`., а не через тег `IMG`.
В данном случае он уже сделан. Стиль для дерева:
```css
.icon {
width: 16px;
height: 16px;
float: left;
}
.open .icon {
cursor: pointer;
background: url(minus.gif);
}
.closed .icon {
cursor: pointer;
background: url(plus.gif);
}
.leaf .icon {
cursor: text;
background: url(article.gif);
}
```
## Шаг 2. Объединить изображения
Составим из нескольких изображений одно `icons.gif`, расположив их, например, по вертикали.
Из <img src="plus.gif">, <img src="minus.gif"> и <img src="article.gif"> получится одна картинка: <img src="icons.gif">
## Шаг 3. Показать часть спрайта в "окошке"
А теперь самое забавное. Размер `DIV'а` для иконки -- жёстко фиксирован:
```css
.icon {
*!*
width: 16px;
height: 16px;
*/!*
float: left;
}
```
Это значит, что если поставить `background'ом` объединённую картинку, то вся она не поместится, будет видна только верхняя часть:
[iframe src="sprite-tree-1" height=60 border=1]
Если бы высота иконки была больше, например, `16x48`, как в примере ниже, то было бы видно и остальное:
[iframe src="height48" height=80 border=1]
..Но так как там всего `16px`, то помещается только одно изображение.
## Шаг 4. Сдвинуть спрайт
Сдвиг фона `background-position` позволяет выбирать, какую именно часть спрайта видно.
В спрайте `icons.gif` изображения объединены так, что сдвиг на `16px` покажет следующую иконку:
```css
.icon {
width: 16px;
height: 16px;
float: left;
background: url(icons.gif) no-repeat;
}
.open .icon {
background-position: 0 -16px; /* вверх на 16px */
cursor: pointer;
}
.closed .icon {
background-position: 0 0px; /* по умолчанию */
cursor: pointer;
}
.leaf .icon {
background-position: 0 -32px; /* вверх на 32px */
cursor: text;
}
```
Результат:
[iframe src="sprite-tree" border=1 height=200 link edit]
<ul>
<li>В спрайт могут объединяться изображения разных размеров, т.е. сдвиг может быть любым.</li>
<li>Сдвигать можно и по горизонтали и по вертикали.</li>
</ul>
### Отступы
Обычно отступы делаются `margin/padding`, но иногда их бывает удобно предусмотреть в спрайте.
Тогда если элемент немного больше, чем размер изображения, то в "окошке" не появится лишнего.
Пример спрайта с отступами:
<img src="sprites-example.png">
Иконка RSS находится в нём на координатах `(90px, 40px)`:
<img src="sprites-example-lines2.png">
Это значит, что чтобы показать эту иконку, нужно сместить фон:
```css
background-position: -90px -40px;
```
При этом в левом-верхнем углу фона как раз и будет эта иконка:
[iframe src="sprite-example" border=1]
Элемент, в котором находится иконка (в рамке), больше по размеру, чем картинка.
Его стиль:
```css
.rss {
width: 35px; /* ширина/высота больше чем размер иконки */
height: 35px;
border: 1px solid black;
float: left;
background-image: url(sprite.png);
background-position: -90px -40px;
}
```
Если бы в спрайте не было отступов, то в такое большое "окошко" наверняка влезли бы другие иконки.
## Итого
[smart header="Когда использовать для изображений `IMG`, а когда -- `CSS background`?"]
Решение лучше всего принимать, исходя из принципов семантической вёрстки.
Задайте вопрос -- что здесь делает изображение? Является ли оно самостоятельным элементом страницы (фотография, аватар посетителя), или же оформляет что-либо (иконка узла дерева)?
Элемент `IMG` следует использовать в первом случае, а для оформления у нас есть CSS.
[/smart]
Спрайты позволяют:
<ol>
<li>Cократить количество обращений к серверу.</li>
<li>Загрузить несколько изображений сразу, включая те, которые понадобятся в будущем.</li>
<li>Если у изображений сходная палитра, то объединённое изображение будет меньше по размеру, чем совокупность исходных картинок.</li>
</ol>
Если фоновое изображение нужно повторять по горизонтали или вертикали, то спрайты тоже подойдут -- изображения в них нужно располагать в этом случае так, чтобы при повторении не были видны соседи, т.е., соответственно, вертикально или горизонтально, но не "решёткой".
Далее мы встретимся со спрайтами при создании интерфейсов, чтобы кнопка при наведении меняла своё изображение. Один спрайт будет содержать все состояния кнопки, а переключение внешнего вида -- осуществляться при помощи сдвига `background-position`.
Для автоматизированной сборки спрайтов используются специальные инструменты, например <a href="http://csssprites.org/">SmartSprites</a>.

View file

@ -0,0 +1,34 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
.icon {
width: 16px;
height: 48px;
float: left;
outline: 1px dotted black;
background: url(http://js.cx/sprite-tree/icons.gif) no-repeat;
}
li {
list-style: none;
}
.text {
margin: 6px 0 6px 16px;
}
</style>
</head>
<body>
<ul>
<li class="closed">
<div class="icon"></div>
<div class="text">Пример раздела</div>
</li>
</ul>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 767 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 535 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 535 B

View file

@ -0,0 +1,25 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<style>
.rss {
width: 35px;
height: 35px;
border: 1px solid black;
float: left;
background-image: url(http://js.cx/sprite-example/sprite.png);
background-position: -90px -40px;
}
</style>
</head>
<body>
<div class="rss"></div>
Очень интересная новость Очень интересная новость Очень интересная новость Очень интересная новость Очень интересная новость
Очень интересная новость Очень интересная новость Очень интересная новость Очень интересная новость Очень интересная новость
</body>
</html>

View file

@ -0,0 +1,34 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
.icon {
width: 16px;
height: 48px;
float: left;
outline: 1px dotted black;
background: url(http://js.cx/sprite-tree/icons.gif) no-repeat;
}
li {
list-style: none;
}
.text {
margin: 6px 0 6px 16px;
}
</style>
</head>
<body>
<ul>
<li class="closed">
<div class="icon"></div>
<div class="text">Пример раздела</div>
</li>
</ul>
</body>
</html>

View file

@ -0,0 +1,34 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
.icon {
width: 16px;
height: 16px;
float: left;
outline: 1px dotted black;
background: url(http://js.cx/sprite-tree/icons.gif) no-repeat;
}
li {
list-style: none;
}
.text {
margin: 6px 0 6px 16px;
}
</style>
</head>
<body>
<ul>
<li class="closed">
<div class="icon"></div>
<div class="text">Пример раздела</div>
</li>
</ul>
</body>
</html>

View file

@ -0,0 +1,63 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
.icon {
width: 16px;
height: 16px;
float: left;
}
.open .icon {
cursor: pointer;
background: url(http://js.cx/sprite-tree/minus.gif);
}
.closed .icon {
cursor: pointer;
background: url(http://js.cx/sprite-tree/plus.gif);
}
.leaf .icon {
cursor: text;
background: url(http://js.cx/sprite-tree/article.gif);
}
li {
list-style: none;
}
.text {
margin: 6px 0 6px 16px;
}
</style>
</head>
<body>
<ul>
<li class="open">
<div class="icon"></div>
<div class="text">Раздел 1<br>В две строки</div>
<ul>
<li class="closed">
<div class="icon"></div>
<div class="text">Раздел 1.1 в одну строку</div>
</li>
<li class="leaf">
<div class="icon"></div>
<div class="text">Страница 1.2<br> в две строки</div>
</li>
</ul>
</li>
<li class="closed">
<div class="icon"></div>
<div class="text">Раздел 2<br>В две строки</div>
</li>
</ul>
</body>
</html>

View file

@ -0,0 +1,64 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
.icon {
width: 16px;
height: 16px;
float: left;
background: url(http://js.cx/sprite-tree/icons.gif) no-repeat;
}
.open .icon {
background-position: 0 -16px;
cursor: pointer;
}
.closed .icon {
background-position: 0 0px;
cursor: pointer;
}
.leaf .icon {
background-position: 0 -32px;
cursor: text;
}
li {
list-style: none;
}
.text {
margin: 6px 0 6px 16px;
}
</style>
</head>
<body>
<ul>
<li class="open">
<div class="icon"></div>
<div class="text">Раздел 1<br>В две строки</div>
<ul>
<li class="closed">
<div class="icon"></div>
<div class="text">Раздел 1.1 в одну строку</div>
</li>
<li class="leaf">
<div class="icon"></div>
<div class="text">Страница 1.2<br> в две строки</div>
</li>
</ul>
</li>
<li class="closed">
<div class="icon"></div>
<div class="text">Раздел 2<br>В две строки</div>
</li>
</ul>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View file

@ -0,0 +1,145 @@
# Правила форматирования CSS
Для того, чтобы CSS легко читался, полезно соблюдать пять правил форматирования.
[cut]
## Каждое свойство -- на отдельной строке
Так -- неверно:
```css
##snapshot-box h2 { padding: 0 0 6px 0; font-weight: bold; position: absolute; left: 0; top: 0; }
```
Так -- правильно:
```css
##snapshot-box h2 {
position: absolute;
left: 0;
top: 0;
padding: 0 0 6px 0;
font-weight: bold;
}
```
Цель -- лучшая читаемость, проще найти и поправить свойство.
## Каждый селектор -- на отдельной строке
Неправильно:
```css
##snapshot-box h2, #profile-box h2, #order-box h2 {
padding: 0 0 6px 0;
font-weight: bold;
}
```
Правильно:
```css
##snapshot-box h2,
##profile-box h2,
##order-box h2 {
padding: 0 0 6px 0;
font-weight: bold;
}
```
Цель -- лучшая читаемость, проще найти селектор.
## Свойства, сильнее влияющие на документ, идут первыми
Рекомендуется располагать свойства в следующем порядке:
<ol>
<li>Сначала положение элемента относительно других:
`position`, `left/right/top/bottom`, `float`, `clear`, `z-index`.</li>
<li>Затем размеры и отступы:
`width`, `height`, `margin`, `padding`...</li>
<li>Рамка `border`, она частично относится к размерам.</li>
<li>Общее оформление содержимого:
`list-style-type`, `overflow`...</li>
<li>Цветовое и стилевое оформление:
`background`, `color`, `font`...</li>
</ol>
**Общая логика сортировки: "от общего -- к локальному и менее важному".**
При таком порядке свойства, определяющие структуру документа, будут видны наиболее отчётливо, в начале, а самые незначительно влияющие (например цвет) -- в конце.
Например:
```css
##snapshot-box h2 {
position: absolute; /* позиционирование */
left: 0;
top: 0;
padding: 0 0 6px 0; /* размеры и отступы */
color: red; /* стилевое оформление */
font-weight: bold;
}
```
</li>
<li>**Свойство без префикса пишется последним.**
Например:
```css
-webkit-box-shadow:0 0 100px 20px #000;
box-shadow:0 0 100px 20px #000;
```
Это нужно, чтобы стандартная (окончательная) реализация всегда была важнее, чем временные браузерные.
</li>
## Организация CSS-файлов проекта
Стили можно разделить на две основные группы:
<ol>
<li>**Блоки-компоненты имеют свой CSS.** Например, CSS для диалогового окна, CSS для профиля посетителя, CSS для меню.
Такой CSS идёт "в комплекте" с модулем, его удобно выделять в отдельные файлы и подключать через `@import`.
Конечно, при разработке будет много CSS-файлов, но при выкладке проекта система сборки и сжатия CSS заменит директивы `@import` на их содержимое, объединяя все CSS в один файл.
</li>
<li>**Страничный и интегрирующий CSS**.
Этот CSS описывает общий вид страницы, расположение компонент и их дополнительную стилизацию, зависящую от места на странице и т.п.
```css
.tab .profile { /* профиль внутри вкладки */
float: left;
width: 300px;
height: 200px;
}
```
Важные страничные блоки можно выделять особыми комментариями:
```css
/** ===========================
* Профиль посетителя
* ===========================
*/
.profile {
border: 1px solid gray;
}
.profile h2 {
color: blue;
font-size: 1.8em;
}
```
</li>
</ol>
CSS-препроцессоры, такие как [SASS](http://sass-lang.com/), [LESS](http://lesscss.org/), [Stylus](http://learnboost.github.com/stylus/), [Prefix-free](http://leaverou.github.com/prefixfree/) делает написание CSS сильно удобнее..
Выберите один из них и используйте. Единственно, они добавляют дополнительную предобработку CSS, которую нужно учесть, и желательно, на сервере.

View file

@ -0,0 +1,290 @@
# Единицы измерения: "px", "em", "rem", "%" и другие
В этом очерке я постараюсь не только рассказать о различных единицах измерения, но и построить общую картину -- что и когда выбирать.
[cut]
## Абсолютные: px
Пиксель `px` -- это самая базовая, абсолютная и окончательная единица измерения.
Количество пикселей задаётся в настроках [разрешения экрана](http://ru.wikipedia.org/wiki/%D0%A0%D0%B0%D0%B7%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%B8%D0%B5_(%D0%BA%D0%BE%D0%BC%D0%BF%D1%8C%D1%8E%D1%82%D0%B5%D1%80%D0%BD%D0%B0%D1%8F_%D0%B3%D1%80%D0%B0%D1%84%D0%B8%D0%BA%D0%B0), один `px` -- это как раз один такой пиксель на экране. Все значения браузер в итоге пересчитает в пиксели.
Пиксели могут быть дробными, например размер можно задать в `16.5px`. Это совершенно нормально, браузер сам использует дробные пиксели для внутренних вычислений. К примеру, есть элемент шириной в `100px`, его нужно разделить на три части -- волей-неволей появляются `33.333...px`.
Для мобильных устройств, у которых много пикселей на экране, но сам экран маленький, чтобы обеспечить читаемость, браузер автоматически применяет масштабирование. При окончательном отображении дробные пиксели, конечно же, округляются и становятся целыми.
[compare]
+Главное достоинство пикселя -- чёткость и понятность
-Другие единицы измерения -- в некотором смысле "мощнее", они являются относительными и позволяют устанавливать соотношения между различными размерами
[/compare]
[warn header="Давно на свалке: `mm`, `cm`, `pt`, `pc`"]
Существуют также "производные" от пикселя единицы измерения: `mm`, `cm`, `pt` и `pc`, но они давно отправились на свалку истории.
Вот, если интересно, их значения:
<ul>
<li>`1mm` (мм) = `3.8px`</li>
<li>`1cm` (см) = `38px`</li>
<li>`1pt` (типографский пункт) = `4/3 px`</li>
<li>`1pc` (типографская пика) = `16px`</li>
</ul>
Так как браузер пересчитывает эти значения в пиксели, то смысла в их употреблении нет.
[/warn]
[smart header="Почему сантиметре `cm` содержится ровно 38 пикселей?"]
В реальной жизни сантиметр -- это такой отрезок, эталон длины. А [пиксель](http://ru.wikipedia.org/wiki/%D0%9F%D0%B8%D0%BA%D1%81%D0%B5%D0%BB%D1%8C) может быть разным, в зависимости от экрана.
Но в формулах выше под пикселем понимается "сферический пиксель в вакууме", точка на "стандартизованном экране", характеристики которого описаны в [спецификации](http://www.w3.org/TR/CSS2/syndata.html#length-units).
Поэтому ни о каком соответствии `cm` реальному сантиметру здесь нет и речи. Полностью синтетическая и ненужная единица измерения.
[/smart]
## Относительно шрифта: em
`1em` -- текущий размер шрифта.
Можно брать любые пропорции от текущего шрифта: `2em`, `0.5em` и т.п.
**Размеры в `em` -- *относительные*, они определяются по текущему контексту.**
Например, давайте сравним `px` с `em` на таком примере:
```html
<!--+ autorun height=80 -->
<div style="font-size:24px">
Страусы
<div style="font-size:24px">Живут также в Африке</div>
</div>
```
`24` пикселей -- и в Африке `24` пикселей, поэтому две строчки выше одинаковы.
А вот аналогичный пример с `em` вместо `px`:
```html
<!--+ autorun height=120 -->
<div style="font-size:1.5em">
Страусы
<div style="font-size:1.5em">Живут также в Африке</div>
</div>
```
Так как значение в `em` высчитывается относительно *текущего шрифта*, то вторая строка в `1.5` раза больше, чем первая.
**Выходит, задавая размеры в `em`, мы задаём зависимость элементов от стиля родителя. Хочется увеличить или уменьшить всё вместе -- легко, просто поправим один стиль.**
[smart header="Также относительно шрифта: `ex`, `ch`"]
В спецификации указаны также единицы [ex](http://www.w3.org/TR/css3-values/#ex-unit) и [ch](http://www.w3.org/TR/css3-values/#ch-unit) ), которые означают размер в зависимости от таких характеристик шрифта как размер символа `"x"` и размер символа `"0"`.
Эти размеры присутствуют всегда, даже если по коду этих символов в шрифте находятся другие значения, а не именно буква `"x"` и ноль `"0"`.
Эти единицы используются чрезвычайно редко, так как "размер шрифта" `em` обычно вполне подходит.
[/smart]
## Проценты %
Проценты `%`, как и `em` -- относительные единицы.
Вот пример с `%`, он выглядит в точности так же, как с `em`:
```html
<!--+ autorun height=120 -->
<div style="font-size:150%">
Страусы
<div style="font-size:150%">Живут также в Африке</div>
</div>
```
Когда мы говорим "процент", то возникает вопрос -- "Процент от чего?"
**Как правило, процент будет от значения свойства родителя с тем же названием, но не всегда.**
Это очень важная особенность процентов, про которую, увы, часто забывают.
Отличный источник информации по этой теме -- стандарт, [Visual formatting model details](http://www.w3.org/TR/CSS2/visudet.html).
Некоторые примеры:
<ul>
<li>При установке свойства `margin-left` в `%`, процент берётся от *ширины* родительского блока (а вовсе не от его `margin-left`!)</li>
<li>При установке свойства `line-height` в `%`, процент берётся от текущего *размера шрифта* (а вовсе не от текущего `line-height`!)</li>
<li>Для `width/height` при `position:fixed`, процент берётся от ширины/высоты *окна* (а не родителя и не документа).</li>
<li>Кроме того, иногда `%` требует соблюдения дополнительных условий, за примером -- обратитесь к статье [](/height-percent).</li>
<li>Детали по `line-height` и размеру шрифта вы также можете найти в статье [](/font-size-line-height).</li>
</ul>
## Микс px и em: rem
Итак, что у нас есть:
<ul>
<li>`px` -- абсолютные, чёткие, понятные, не зависящие ни от чего.</li>
<li>`em` -- относительно размера шрифта.</li>
<li>`%` -- относительно такого же свойства родителя (а может и не родителя, а может и не такого же -- см. оговорки выше).</li>
</ul>
Может быть, пора уже остановиться, может этого достаточно?
Э-э, нет! Не все вещи делаются удобно.
Вернёмся к теме шрифтов. Бывают задачи, когда мы хотим сделать на странице большие кнопки "Шрифт больше" и "Шрифт меньше". При нажатии на них будет срабатывать JavaScript, который будет увеличивать или уменьшать шрифт.
Вообще-то это можно сделать без JavaScript, в браузере обычно есть горячие клавиши для масштабирования вроде [key Ctrl++], но они работают слишком тупо -- берут и увеличивают всю страницу, вместе с изображениями и другими элементами, которые масштабировать как раз не надо. А надо увеличить, к примеру, только шрифт, потому что посетитель хочет комфортнее читать. И увеличенный шрифт по-новому обтечёт элементы страницы.
Какую единицу использовать для задания шрифтов? Лучше бы не `px`, ведь такие значения абслютны, если менять, то везде, вполне возможна ситуация, когда мы в одном правиле размер поменяли, а другое забыли.
Следующие кандидаты -- `em` и `%`.
Разницы между ними здесь нет, так как при задании `font-size` в процентах, эти проценты берутся от `font-size` родителя, то есть ведут себя так же, как и `em`.
Вроде бы, использовать можно, однако есть проблема.
Посмотрите на пример с вложенными `<li>`:
```html
<!--+ run autorun -->
<style>
li {
font-size: 0.8em;
}
</style>
<ul>
<li>Собака
<ul>
<li>бывает
<ul>
<li>кусачей
<ul>
<li>только
<ul>
<li>от жизни
<ul>
<li>собачей</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
```
Проблема очевидна. Хотели, как лучше, а получилось... Мелковато. Каждый `<li>` получил размер шрифта `0.8` от внешнего, это не совсем то, чего мы бы здесь хотели.
Время появиться единице `rem`, которая, можно сказать, придумана для таких случаев!
**Единица `rem` задаёт размер относительно размера шрифта элемента `<html>`.**
Как правило, браузеры ставят этому элементу некоторый "разумный" (reasonable) размер по-умолчанию, который мы, конечно, можем переопределить и использовать `rem` для задания шрифтов внутри:
```html
<!--+ run height=400 autorun -->
<style>
*!*
html {
font-size: 14px;
}
li {
font-size: 0.8rem;
}
*/!*
</style>
<div><button id="up">Кликните, чтобы увеличить размер шрифта</button></div>
<img src="http://js.cx/clipart/angry_dog.png">
<ul>
<li>Собака
<ul>
<li>бывает
<ul>
<li>кусачей
<ul>
<li>только
<ul>
<li>от жизни
<ul>
<li>собачей</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<script>
var html = document.documentElement;
up.onclick = function() {
// при помощи JS увеличить размер шрифта html на 2px
html.style.fontSize = parseInt(getComputedStyle(html, '').fontSize) + 2 + 'px';
};
</script>
```
Получилось удобное масштабирование для шрифтов, не влияющее на другие элементы.
Можно воспринимать `rem` как остановку посередине между `em` и `px`, потому что элементы в `rem` не зависят друг от друга и от контекста -- и этим похожи на `px`, а с другой стороны они все заданы относительно размера шрифта `<html>`.
[warn header="Не поддерживается в IE8-"]
Единица `rem` не поддерживается в IE8-. Для этих браузеров, которых становится всё меньше, есть два выхода:
<ol>
<li>Либо использовать `em` и правила, страхующие от вложенности, вроде:
```css
li { font-size: 0.8em }
li li { font-size: 0.8em }
li li li { font-size: 0.8em }
```
</li>
<li>Либо сделать два правила в стилях: первое указывает размер в `px` (для IE8-), а второе -- в `rem` (переопределит первое в современных браузерах) и отключить маштабирование шрифтов для IE8-. Это проще.</li>
</ol>
[/warn]
## Относительно экрана: vw, vh, vmin, vmax
Во всех современных браузерах, исключая IE8-, поддерживаются новые единицы из черновика стандарта [CSS Values and Units 3](http://dev.w3.org/csswg/css3-values/):
<ul>
<li>`vw` -- 1% ширины окна</li>
<li>`vh` -- 1% высоты окна</li>
<li>`vmin` -- наименьшее из (`vw`, `vh`), в IE9 обозначается `vm`</li>
<li>`vmax` -- наибольшее из (`vw`, `vh`)</li>
</ul>
**Эти значения были созданы, в первую очередь, для поддержки мобильных устройств.**
Их основное преимущество -- в том, что любые размеры, которые в них заданы, автоматически масштабируются при изменении размеров окна.
Ниже написан текст с размером `5vh`:
<p style="font-size:5vh">Страусы кусачими не бывают.</p>
**Вы сможете легко увидеть, как работает `vh`, если поменяете размер окна браузера. Текст будет расти/уменьшаться.**
## Итого
Мы рассмотрели единицы измерения:
<ul>
<li>`px` -- абсолютные пиксели, к которым привязаны и потому не нужны `mm`, `cm`, `pt` и `pc`. Используется для максимально конкретного и точного задания размеров.</li>
<li>`em` -- задаёт размер относительно шрифта родителя, можно относительно конкретных символов: `"x"`(`ex`) и `"0"`(`ch`), используется там, где нужно упростить масштабирование компоненты.</li>
<li>`rem` -- задаёт размер относительно шрифта `<html>`, используется для удобства глобального масштабирования: элементы которые планируется масштабировать, задаются в `rem`, а JS меняет шрифт у `<html>`.</li>
<li>`%` -- относительно такого же свойства родителя (как правило, но не всегда), используется для ширин, высот и так далее, без него никуда, но надо знать, относительно чего он считает проценты.</li>
<li>`vw`, `vh`, `vmin`, `vmax` -- относительно размера экрана.</li>
</ul>
Здесь я постарался разобрать их применение и преимущества для решения конкретных задач, но вы, конечно, сможете использовать их для других ситуаций.

View file

@ -0,0 +1,265 @@
# Все значения свойства "display"
Свойство `display` имеет много разных значений. Обычно, используются только три из них: `none`, `inline` и `block`, потому что когда-то браузеры другие не поддерживали.
Но, после прихода IE7 и, особенно, IE8+, стало возможным использовать и другие значения тоже. Рассмотрим здесь весь список.
## Значение none
Самое простое значение. Элемент не показывается, вообще. Как будто его и нет.
```html
<!--+ autorun -->
<div style="border:1px solid black">
Невидимый div (
<div style="*!*display: none*/!*">Я - невидим!</div>
) Стоит внутри скобок
</div>
```
## Значение block
<ul>
<li>**Блочные элементы располагаются один над другим, вертикально** (если нет особых свойств позиционирования, например `float`).</li>
<li>**Блок стремится расшириться на всю доступную ширину. Можно указать ширину и высоту явно.**</li>
</ul>
Это значение `display` многие элементы имеют по умолчанию: `DIV`, заголовок, параграф.
```html
<!--+ autorun -->
<div style="border:1px solid black">
<div style="border: 1px solid blue; width: 50%">Первый</div>
<div style="border: 1px solid red">Второй</div>
</div>
```
Блоки прилегают друг к другу вплотную, если у них нет `margin`.
## Значение inline
<ul>
<li>**Элементы располагаются на той же строке, последовательно.**</li>
<li>**Ширина и высота элемента определяются по содержимому. Поменять их нельзя.**</li>
</ul>
Например, инлайновые элементы по умолчанию: `SPAN`, ссылка.
```html
<!--+ autorun -->
<span style="border:1px solid black">
<span style="border: 1px solid blue; width:50%">Ширина</span>
<a style="border: 1px solid red">Игнорируется</a>
</span>
```
Если вы присмотритесь внимательно к примеру выше, то увидите, что между внутренними `SPAN` и `A` есть пробел. Это потому, что он есть в HTML.
Если расположить элементы вплотную -- его не будет:
```html
<!--+ autorun -->
<span style="border:1px solid black">
<span style="border: 1px solid blue; width:50%">Без</span><a style="border: 1px solid red">Пробела</a>
</span>
```
Содержимое инлайн-элемента может переноситься на другую строку.
При этом каждая строка в смысле отображения является отдельным прямоугольником ("line box"). **Так что инлайн-элемент состоит из объединения прямоугольников, но в целом, в отличие от блока, прямоугольником не является.**
Например:
```html
<!--+ autorun -->
...<span style="background: #DEB887">
Ля Ля Ля Ля Ля Ля Ля Ля Ля Ля Ля Ля Ля Ля Ля Ля Ля Ля Ля Ля
Ля Ля Ля Ля Ля Ля Ля Ля Ля Ля Ля Ля Ля Ля Ля Ля Ля Ля Ля Ля
Ля Ля Ля Ля Ля Ля Ля Ля Ля Ля Ля Ля Ля Ля Ля Ля Ля Ля Ля Ля
</span>...
```
**Если инлайн-элемент граничит с блоком, то между ними обязательно будет перенос строки:**
```html
<!--+ autorun -->
<div style="border:1px solid black">
<span style="border: 1px solid red">Инлайн</span>
<div style="border: 1px solid blue; width:50%">Блок</div>
<span style="border: 1px solid red">Инлайн</span>
</div>
```
## Значение inline-block
Это значение -- означает элемент, который продолжает находиться в строке (`inline`), но при этом может иметь важные свойства блока.
Как и инлайн-элемент:
<ul>
<li>**Располагается в строке.**</li>
<li>**Размер устанавливается по содержимому.**</li>
</ul>
Во всём остальном -- это блок, то есть:
<ul>
<li>**Элемент всегда прямоугольный.**</li>
<li>**Работают свойства `width/height`.**</li>
</ul>
Это значение `display` используют, чтобы отобразить в одну строку блочные элементы, в том числе разных размеров.
Например:
```html
<!--+ autorun -->
<style>
li {
*!*
display: inline-block;
*/!*
list-style: none;
border: 1px solid red;
}
</style>
<ul style="border:1px solid black; padding:0">
<li>Инлайн Блок<br>3 строки<br>высота/ширина явно не заданы</li>
<li style="width:100px;height:100px">Инлайн<br>Блок 100x100</li>
<li style="width:60px;height:60px">Инлайн<br>Блок 60x60</li>
<li style="width:100px;height:60px">Инлайн<br>Блок 100x60</li>
<li style="width:60px;height:100px">Инлайн<br>Блок 60x100</li>
</ul>
```
Свойство `vertical-align` позволяет выровнять такие элементы внутри внешнего блока:
```html
<!--+ autorun -->
<style>
li {
display: inline-block;
list-style: none;
border: 1px solid red;
*!*
vertical-align: middle;
*/!*
}
</style>
<ul style="border:1px solid black; padding:0">
<li>Инлайн Блок<br>3 строки<br>высота/ширина явно не заданы</li>
<li style="width:100px;height:100px">Инлайн<br>Блок 100x100</li>
<li style="width:60px;height:60px">Инлайн<br>Блок 60x60</li>
<li style="width:100px;height:60px">Инлайн<br>Блок 100x60</li>
<li style="width:60px;height:100px">Инлайн<br>Блок 60x100</li>
</ul>
```
Как и в случае с инлайн-элементами, пробелы между блоками появляются из-за пробелов в HTML. Если элементы списка идут вплотную, например, генерируются в JavaScript -- их не будет.
**IE7 допускает это значение только для элементов, которые по умолчанию `inline`.**
## Значения table-*
Современные браузеры (не IE6,7) позволяют описывать таблицу любыми элементами, если поставить им соответствующие значения `display`.
Для таблицы целиком `table`, для строки -- `table-row`, для ячейки -- `table-cell` и т.д.
Пример использования:
```html
<!--+ run autorun -->
<form style="display: *!*table*/!*">
<div style="display: *!*table-row*/!*">
<label style="display: *!*table-cell*/!*">Имя:</label>
<input style="display: *!*table-cell*/!*">
</div>
<div style="display: *!*table-row*/!*">
<label style="display: *!*table-cell*/!*">Фамилия:</label>
<input style="display: *!*table-cell*/!*">
</div>
</form>
```
Важно то, что это действительно полноценная таблица. Используются табличные алгоритмы вычисления ширины и высоты элемента, [описанные в стандарте](http://www.w3.org/TR/CSS2/tables.html#width-layout).
**Это хорошо для семантической вёрстки и позволяет избавиться от лишних тегов.**
С точки зрения современного CSS, обычные `TABLE`, `TR`, `TD` и т.д. -- это просто элементы с предопределёнными значениями `display`:
```css
table { display: table }
tr { display: table-row }
thead { display: table-header-group }
tbody { display: table-row-group }
tfoot { display: table-footer-group }
col { display: table-column }
colgroup { display: table-column-group }
td, th { display: table-cell }
caption { display: table-caption }
```
Очень подробно об алгоритмах вычисления размеров и отображении таблиц рассказывает стандарт [CSS 2.1 - Tables](http://www.w3.org/TR/CSS2/tables.html).
### Вертикальное центрирование с table-cell
Внутри ячеек свойство [vertical-align](http://www.w3.org/TR/CSS2/visudet.html#propdef-vertical-align) выравнивает содержимое по вертикали.
Это можно использовать для центрирования:
```html
<!--+ run autorun -->
<style>
div { border: 1px solid black }
</style>
<div style="height:100px; *!*display: table-cell; vertical-align: middle*/!*">
<div>Элемент<br>С неизвестной<br>Высотой</div>
</div>
```
CSS не требует, чтобы вокруг `table-cell` была структура таблицы: `table-row` и т.п. Может быть просто такой одинокий `DIV`, это допустимо.
При этом он ведёт себя как ячейка `TD`, то есть подстраивается под размер содержимого и умеет вертикально центрировать его при помощи `vertical-align`.
Значение `display: table-cell` поддерживается во всех браузерах, кроме IE<8. В IE6,7 можно использовать для центрирования CSS-выражения или реальную таблицу.
## Значения list-item и run-in
У свойства `display` есть и другие значения. Они используются реже, поэтому посмотрим на них кратко:
<dl>
<dt>`list-item`</dt>
<dd>Этот display по умолчанию используется для элементов списка. Он добавляет к блоку содержимым ещё и блок с номером(значком) списка, который стилизуется стандартными списочными свойствами:
```html
<!--+ autorun -->
<div style="*!*display: list-item*/!*; list-style:inside square">Пункт 1</div>
```
</dd>
<dt>`run-in`</dt>
<dd>Если после `run-in` идёт `block`, то `run-in` становится его первым инлайн-элементом, то есть отображается в начале `block`.
Если ваш браузер поддерживает это значение,** то примере ниже `h3`, благодаря `display:run-in`, окажется визуально внутри `div`:
```html
<!--+ autorun -->
<h3 style="*!*display: run-in*/!*; border: 2px solid red">Про пчёл.</h3>
<div style="border: 2px solid black">Пчёлы - отличные создания, они делают мёд.</div>
```
Если же вы видите две строки, то ваш браузер НЕ поддерживает `run-in`.
Вот, для примера, правильный вариант отображения `run-in`, оформленный другим кодом:
```html
<!--+ autorun -->
<div style="border: 2px solid black">
<h3 style="display: inline; border: 2px solid red">Про пчёл.</h3>Пчёлы - отличные создания, они делают мёд.
</div>
```
Если этот вариант отличается от того, что вы видите выше -- ваш браузер не поддерживает `run-in`. На момент написания этой статьи только IE поддерживал `display:run-in`.
</dd>
</dl>

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

View file

@ -0,0 +1,75 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
.gallery li {
float: left;
width: 130px;
list-style: none;
/* красивости */
border: 1px solid black;
text-align: center;
margin: 5px;
}
.gallery li:nth-child(2n) {
height: 200px;
}
</style>
</head>
<body>
<ul class="gallery">
<li>
<img src="http://js.cx/carousel/1.png" width="130" height="130">
<div>Картинка 1</div>
</li>
<li>
<img src="http://js.cx/carousel/2.png" width="130" height="130">
<div>Картинка 2</div>
</li>
<li>
<img src="http://js.cx/carousel/3.png" width="130" height="130">
<div>Картинка 3</div>
</li>
<li>
<img src="http://js.cx/carousel/4.png" width="130" height="130">
<div>Картинка 4</div>
</li>
<li>
<img src="http://js.cx/carousel/5.png" width="130" height="130">
<div>Картинка 5</div>
</li>
<li>
<img src="http://js.cx/carousel/6.png" width="130" height="130">
<div>Картинка 6</div>
</li>
<li>
<img src="http://js.cx/carousel/7.png" width="130" height="130">
<div>Картинка 7</div>
</li>
<li>
<img src="http://js.cx/carousel/8.png" width="130" height="130">
<div>Картинка 8</div>
</li>
<li>
<img src="http://js.cx/carousel/9.png" width="130" height="130">
<div>Картинка 9</div>
</li>
</ul>
</body>
</html>

View file

@ -0,0 +1,63 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
.gallery li {
display: inline-block;
vertical-align: middle;
width: 130px;
list-style: none;
/* красивости */
border: 1px solid black;
text-align: center;
margin: 5px;
}
.gallery li:nth-child(2n) {
height: 200px;
}
</style>
</head>
<body>
<ul class="gallery">
<li>
<img src="http://js.cx/carousel/1.png" width="130" height="130">
<div>Картинка 1</div>
</li>
<li>
<img src="http://js.cx/carousel/2.png" width="130" height="130">
<div>Картинка 2</div>
</li>
<li>
<img src="http://js.cx/carousel/3.png" width="130" height="130">
<div>Картинка 3</div>
</li>
<li>
<img src="http://js.cx/carousel/4.png" width="130" height="130">
<div>Картинка 4</div>
</li>
<li>
<img src="http://js.cx/carousel/5.png" width="130" height="130">
<div>Картинка 5</div>
</li>
<li>
<img src="http://js.cx/carousel/6.png" width="130" height="130">
<div>Картинка 6</div>
</li>
</ul>
</body>
</html>

View file

@ -0,0 +1,44 @@
# Наводящие вопросы
<ol>
<li>Что произойдёт, если контейнеру `UL` поставить рамку `border` -- в первом и во втором случае?</li>
<li>Что будет, если элементы `LI` различаются по размеру? Будут ли они корректно перенесены на новую строку в обоих случаях?</li>
<li>Как будут вести себя блоки, находящиеся под галереей?</ul>
</ol>
# Ответы
Разница колоссальная.
В первую очередь она в том, что `inline-block` продолжают участвовать в потоке, а `float` -- нет.
Ответы на вопросы по примеру:
<dl>
<dt>Что будет, если контейнеру `UL` поставить рамку `border`?</dt>
<dd>Контейнер не выделяет пространство под `float`. А больше там ничего нет. В результате он просто сожмётся в одну линию сверху.
Попробуйте сами, добавьте рамку в [edit src="solution"]песочнице[/edit].
А в случае с `inline-block` всё будет хорошо, т.к. элементы остаются в потоке.
</dd>
<dt>Что будет, если элементы `LI` различаются по размеру? Будут ли они корректно перенесены на новую строку в обоих случаях?</dt>
<dd>При `float:left` элементы двигаются направо до тех пор, пока не наткнутся на границу внешнего блока (с учётом `padding`) или на другой `float`-элемент.
Может получиться вот так:
<img src="gallery-float-diffsize.png">
Вы можете увидеть это, открыв демо-галерею в отдельном окне и изменяя его размер:
[demo src="gallery-float-diffsize"]
При использовании `inline-block` таких странностей не будет, блоки перенесутся корректно на новую строку. И, кроме того, можно выровнять элементы по высоте при помощи `li { vertical-align:middle }`:
[iframe height=500 src="gallery-inline-block" link edit]
</dd>
<dt>Как будут вести себя блоки, находящиеся под галереей?</dt>
<dd>В случае с `float` нужно добавить дополнительную очистку с `clear`, чтобы поведение было идентично обычному блоку.
Иначе блоки, находящиеся под галереей, вполне могут "заехать" по вертикали на территорию галереи.</dd>
</dl>

View file

@ -0,0 +1,72 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
.gallery li {
float: left;
width: 130px;
list-style: none;
/* красивости */
border: 1px solid black;
text-align: center;
margin: 5px;
}
</style>
</head>
<body>
<ul class="gallery">
<li>
<img src="http://js.cx/carousel/1.png" width="130" height="130">
<div>Картинка 1</div>
</li>
<li>
<img src="http://js.cx/carousel/2.png" width="130" height="130">
<div>Картинка 2</div>
</li>
<li>
<img src="http://js.cx/carousel/3.png" width="130" height="130">
<div>Картинка 3</div>
</li>
<li>
<img src="http://js.cx/carousel/4.png" width="130" height="130">
<div>Картинка 4</div>
</li>
<li>
<img src="http://js.cx/carousel/5.png" width="130" height="130">
<div>Картинка 5</div>
</li>
<li>
<img src="http://js.cx/carousel/6.png" width="130" height="130">
<div>Картинка 6</div>
</li>
<li>
<img src="http://js.cx/carousel/7.png" width="130" height="130">
<div>Картинка 7</div>
</li>
<li>
<img src="http://js.cx/carousel/8.png" width="130" height="130">
<div>Картинка 8</div>
</li>
<li>
<img src="http://js.cx/carousel/9.png" width="130" height="130">
<div>Картинка 9</div>
</li>
</ul>
</body>
</html>

View file

@ -0,0 +1,16 @@
# Разница inline-block и float
[importance 5]
Галерея изображений состоит из картинок в рамках с подписями (возможно, с другой дополнительной информацией).
Пример галереи:
[iframe src="solution" link edit].
Технически вывод такой галереи можно реализовать при помощи списка UL/LI, где:
<ol>
<li>каждый LI имеет `display:inline-block`</li>
<li>каждый LI имеет `float:left`</li>
</ol>
**Какие различия между этими подходами? Какой вариант выбрали бы вы?**

View file

@ -0,0 +1,3 @@
Для решения можно применить принцип двухколоночной верстки `float` + `margin`. Иконка будет левой колонкой, а содержимое -- правой.
[edit src="solution"/]

View file

@ -0,0 +1,63 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
.icon {
width: 16px;
height: 16px;
float: left;
}
.open .icon {
cursor: pointer;
background: url(http://js.cx/sprite-tree/minus.gif);
}
.closed .icon {
cursor: pointer;
background: url(http://js.cx/sprite-tree/plus.gif);
}
.leaf .icon {
cursor: text;
background: url(http://js.cx/sprite-tree/article.gif);
}
li {
list-style: none;
}
.text {
margin: 6px 0 6px 16px;
}
</style>
</head>
<body>
<ul>
<li class="open">
<div class="icon"></div>
<div class="text">Раздел 1<br>(занимает две строки)</div>
<ul>
<li class="closed">
<div class="icon"></div>
<div class="text">Раздел 1.1</div>
</li>
<li class="leaf">
<div class="icon"></div>
<div class="text">Страница 1.2<br>(занимает две строки)</div>
</li>
</ul>
</li>
<li class="closed">
<div class="icon"></div>
<div class="text">Раздел 2<br>(занимает две строки)</div>
</li>
</ul>
</body>
</html>

View file

@ -0,0 +1,39 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
/* ваш стиль */
</style>
</head>
<body>
<!-- картинки для узлов -->
<img src="http://js.cx/sprite-tree/minus.gif" width="16" height="16">
<img src="http://js.cx/sprite-tree/plus.gif" width="16" height="16">
<img src="http://js.cx/sprite-tree/article.gif" width="16" height="16">
<ul>
<li class="open">
<div class="icon"></div>
<div class="text">Раздел 1<br>(занимает две строки)</div>
<ul>
<li class="closed">
<div class="icon"></div>
<div class="text">Раздел 1.1</div>
</li>
<li class="leaf">
<div class="icon"></div>
<div class="text">Страница 1.2<br>(занимает две строки)</div>
</li>
</ul>
</li>
<li class="closed">
<div class="icon"></div>
<div class="text">Раздел 2<br>(занимает две строки)</div>
</li>
</ul>
</body>
</html>

View file

@ -0,0 +1,20 @@
# Дерево с многострочными узлами
[importance 3]
Сделайте дерево при помощи семантической вёрстки и CSS-спрайта с иконками (есть готовый).
Выглядеть должно так (не кликабельно):
[iframe src="solution" border="1" height=200 link edit]
<ul>
<li>Поддержка многострочных названий узлов</li>
<li>Над иконкой курсор становится указателем.</li>
</ul>
Исходный документ содержит список UL/LI и ссылку на картинку.
[edit task src="source"/]
P.S. Достаточно сделать HTML/CSS-структуру, действия добавим позже.

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View file

@ -0,0 +1,39 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
.nav {
height: 40px;
width: 80%;
margin: auto;
}
.nav .left {
float: left;
border:1px solid black;
}
.nav .right {
float: right;
border:1px solid black;
}
.nav .pages {
text-align: center;
line-height: 40px;
border:1px solid black;
}
</style>
</head>
<body>
Текст Сверху
<div class="nav">
<img src="http://js.cx/clipart/arrow-left.jpg" class="left" width="40" height="40">
<div class="pages">1 2 3 4 5 6 7 8 9</div>
<img src="http://js.cx/clipart/arrow-right.jpg" class="right" width="40" height="40">
</div>
Текст Снизу
</body>
</html>

View file

@ -0,0 +1,99 @@
HTML-структура:
```html
<div class="nav">
<img src="arrow-left.jpg" class="left" width="40" height="40">
<img src="arrow-right.jpg" class="right" width="40" height="40">
<ul class="pages"> <li>...</li> </ul>
</div>
```
Стили:
```css
.nav {
height: 40px;
width: 80%;
margin: auto;
}
.nav .left {
float: left;
cursor: pointer;
}
.nav .right {
float: right;
cursor: pointer;
}
.nav .pages {
list-style: none;
text-align: center;
margin: 0;
padding: 0;
}
.nav .pages li {
display: inline;
margin: 0 3px;
line-height: 40px;
cursor: pointer;
}
```
Основные моменты:
<ul>
<li>**Сначала идёт левая кнопка, затем правая, а лишь затем -- текст.**
Почему так, а не лево - центр - право?
Дело в том, что `float` смещает элемент вправо относительно обычного места. А какое обычное место будет у правого `IMG` без `float`?
Оно будет под списком, так как список -- блочный элемент, а `IMG` -- инлайн-элемент. При добавлении `float:right` элемент `IMG` сдвинется вправо, оставшись под списком.
Код в порядке лево-центр-право (неправильный):
```html
<div...>
<img src="arrow-left.jpg" class="left" width="40" height="40">
<ul class="pages"> (li) 1 2 3 4 5 6 7 8 9</ul>
<img src="arrow-right.jpg" class="right" width="40" height="40">
</div>
```
Его демо:
[iframe src="nav-div-wrong" border=1 height="140"]
Правильный порядок: лево-право-центр, тогда `float` останется на верхней строке.
Код, который даёт правильное отображение:
```html
<div ...>
<img src="arrow-left.jpg" class="left" width="40" height="40">
<img src="arrow-right.jpg" class="right" width="40" height="40">
<ul class="pages"> .. список .. </ul>
</div>
```
Также можно расположить стрелки при помощи `position: absolute`. Тогда, чтобы текст при уменьшении размеров окна не налез на стрелки -- нужно добавить в контейнер левый и правый `padding`:
Выглядеть будет примерно так:
```html
<div style="position:relative; padding: 0 40px;">
<img style="position:absolute;left:0" src="..left.." width="40" height="40">
<ul> (li) 1 2 3 4 5 6 7 8 9 </ul>
<img style="position:absolute;right:0" srr="..right.." width="40" height="40">
</div>
```
</li>
<li>**Центрирование одной строки по вертикали осуществляется указанием `line-height`, равной высоте.**
Это красиво лишь для одной строки: если окно становится слишком узким, и строка вдруг разбивается на две -- получается некрасиво, хотя и читаемо.
Если хочется сделать красивее для двух строк, то можно использовать другой способ центрирования.</li>
</ul>
[edit src="solution"]Полное решение[/edit]

View file

@ -0,0 +1,61 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
.nav {
height: 40px;
width: 80%;
margin: auto;
}
.nav .left {
float: left;
cursor: pointer;
}
.nav .right {
float: right;
cursor: pointer;
}
.nav .pages {
list-style: none;
text-align: center;
margin: 0;
padding: 0;
}
.nav .pages li {
display: inline;
margin: 0 3px;
line-height: 40px;
cursor: pointer;
}
</style>
</head>
<body>
Текст Сверху
<div class="nav">
<img src="http://js.cx/clipart/arrow-left.jpg" class="left" width="40" height="40">
<img src="http://js.cx/clipart/arrow-right.jpg" class="right" width="40" height="40">
<ul class="pages">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
</ul>
</div>
Текст Снизу
</body>
</html>

View file

@ -0,0 +1,39 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
.nav {
height: 40px;
width: 80%;
margin: auto;
}
/* ваш код */
</style>
</head>
<body>
Текст Сверху
<div class="nav">
<img src="http://js.cx/clipart/arrow-left.jpg" class="left" width="40" height="40">
<ul class="pages">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
</ul>
<img src="http://js.cx/clipart/arrow-right.jpg" class="right" width="40" height="40">
</div>
Текст Снизу
</body>
</html>

View file

@ -0,0 +1,19 @@
# Постраничная навигация (CSS)
[importance 5]
Оформите навигацию, центрированную внутри `DIV'а`:
[iframe src="solution" height="100" border="1"]
Требования:
<ul>
<li>Левая стрелка -- слева, правая -- справа, список страниц -- по центру.</li>
<li>Список страниц центрирован вертикально.</li>
<li>Текст сверху и снизу ни на что не наползает.</li>
<li>Курсор при наведении на стрелку или элемент списка становится стрелкой `pointer`.</li>
</ul>
[edit src="source" task/]
P.S. Без использования таблиц.

View file

@ -0,0 +1,41 @@
# Подсказка
Используйте свойство `box-sizing`.
# Решение
Да, можно -- указываем `box-sizing: border-box` и добавляем свойства:
```html
<!--+ run -->
<style>
.left {
float:left;
width:30%;
background: #aef;
}
.right {
float:right;
width:70%;
*!*
box-sizing: border-box;
-moz-box-sizing: border-box;
border-left: 2px solid green;
padding-left: 10px;
*/!*
background: tan;
}
</style>
<div class="left">
Левая<br>Колонка
</div>
<div class="right">
Правая<br>Колонка<br>...
</div>
```

View file

@ -0,0 +1,37 @@
# Добавить рамку, сохранив ширину
[importance 4]
Есть две колонки `30%/70%`:
```html
<!--+ autorun run play -->
<style>
.left {
float:left;
width:30%;
background: #aef;
}
.right {
float:right;
width:70%;
background: tan;
}
</style>
<div class="left">
Левая<br>Колонка
</div>
<div class="right">
Правая<br>Колонка<br>...
</div>
```
**Добавьте к правой колонке рамку `border-left` и отступ `padding-left`.**
Двухколоночная вёрстка при этом не должна сломаться!
Желательно не трогать свойство `width` ни слева ни справа и не создавать дополнительных элементов.
Требуется поддержка всех современных браузеров, IE начиная с версии 8.

View file

@ -0,0 +1,468 @@
# Свойство "float"
Свойство `float` в CSS занимает особенное место. До его появления расположить два блока один слева от другого можно было лишь при помощи таблиц. Но в его работе есть ряд особенностей. Поэтому его иногда не любят, но при их понимании `float` станет вашим верным другом и помощником.
Далее мы рассмотрим, как работает `float`, разберём решения сопутствующих проблем, а также ряд полезных рецептов.
[cut]
## Как работает float [#float-algorithm]
Синтаксис:
```css
float: left | right | none | inherit;
```
При применении этого свойства происходит следующее:
<ol>
<li>Элемент позиционируется как обычно, а затем *вынимается из <strike>документа</strike> потока* и сдвигается влево (для `left`) или вправо (для `right`) до того как коснётся либо границы родителя, либо другого элемента с `float`.</li>
<li>Если пространства по горизонтали не хватает для того, чтобы вместить элемент, то он сдвигается вниз до тех пор, пока не начнёт помещаться.</li>
<li>Другие непозиционированные блочные элементы без `float` ведут себя так, как будто элемента с `float` нет, так как он убран из потока.</li>
<li>Строки (inline-элементы), напротив, "знают" о `float` и обтекают элемент по сторонам.</li>
</ol>
Ещё детали:
<ol>
<li>**Элемент при наличии `float` получает `display:block`.** То есть, указав элементу, у которого `display:inline` свойство `float: left/right`, мы автоматически сделаем его блочным. В частности, для него будут работать `width/height`.
Исключением являются некоторые редкие `display` наподобие `inline-table` и `run-in` (см. [Relationships between 'display', 'position', and 'float'](http://www.w3.org/TR/CSS2/visuren.html#dis-pos-flo))</li>
<li>**Ширина `float`-блока определяется по содержимому.** (["CSS 2.1, 10.3.5"](http://www.w3.org/TR/CSS2/visudet.html#float-width)).</li>
<li>**Вертикальные отступы `margin` элементов с `float` не сливаются с отступами соседей,** в отличие от обычных блочных элементов.</li>
</ol>
Это пока только теория. Далее мы рассмотрим происходящее на примере.
### Текст с картинками
Одно из первых применений `float`, для которого это свойство когда-то было придумано -- это вёрстка текста с картинками, отжатыми влево или вправо.
Например, вот страница о Винни-Пухе с картинками, которым поставлено свойство `float`:
<img src="text.png">
Её HTML-код ([edit src="winnie"]открыть[/edit]) выглядит примерно так:
```html
<img src="1.jpg" style="float:right">
<p>Текст...</p>
<p>Текст...</p>
<img src="2.jpg" style="float:left">
<p>Текст...</p>
<img src="3.jpg" style="float:right">
<p>Текст...</p>
```
Каждая картинка, у которой есть `float`, обрабатывается в точности [по алгоритму](#float-algorithm), указанному выше.
Посмотрим, например, как выглядело бы начало текста без float:
[iframe src="winnie-nofloat" height=300 border=1 link edit]
<ol>
<li>Элемент `IMG` вынимается из <strike>документа</strike> потока. Иначе говоря, последующие блоки начинают вести себя так, как будто его нет, и заполняют освободившееся место (изображение для наглядности полупрозрачно):
[iframe src="winnie-nofloat-1" height=250 border=1 link edit]
</li>
<li>Элемент `IMG` сдвигается максимально вправо(при `float:right`):
[iframe src="winnie-nofloat-2" height=250 border=1 link edit]
</li>
<li>Строки, в отличие от блочных элементов, "чувствуют" `float` и уступают ему место, обтекая картинку слева:
[iframe src="winnie-nofloat-3" height=250 border=1 link edit]
</li>
</ol>
При `float:left` -- всё то же самое, только `IMG` смещается влево (или не смещается, если он и так у левого края), а строки -- обтекают справа
**Строки и инлайн-элементы смещаются, чтобы уступить место `float`. Обычные блоки -- ведут себя так, как будто элемента нет.**
Чтобы это увидеть, добавим параграфам фон и рамку, а также сделаем изображение немного прозрачным:
[iframe src="winnie-block-bg" height=300 border=1 link edit]
Как видно из рисунка, параграфы проходят "за" `float`. При этом строки в них о `float'ах` знают и обтекают их, поэтому соответствующая часть параграфа пуста.
### Блок с float
Свойство `float` можно поставить любому элементу, не обязательно картинке. При этом элемент станет блочным.
Посмотрим, как это работает, на конкретной задаче -- сделать рамку с названием вокруг картинки с Винни.
HTML будет такой:
```html
<h2>Винни-Пух</h2>
*!*
<div class="left-picture">
<img src="winnie-mult.jpg" width="200" height="150">
<div>Кадр из советского мультфильма</div>
</div>
*/!*
<p>Текст...</p>
```
..То есть, `div.left-picture` включает в себя картинку и заголовок к ней. Добавим стиль с `float`:
```css
.left-picture {
*!*
float: left;
*/!*
/* рамочка и отступ для красоты (не обязательно) */
margin: 0 10px 5px 0;
text-align: center;
border: 1px solid black;
}
```
Результат:
[iframe src="winnie-block" height=300 border=1 link edit]
Заметим, что блок `div.left-picture` "обернул" картинку и текст под ней, а не растянулся на всю ширину. Это следствие того, что ширина блока с `float` определяется по содержимому.
## Очистка под float
Разберём еще одну особенность использования свойства `float`.
Для этого выведем персонажей из мультфильма "Винни-Пух". Цель:
[iframe src="winnie-clear-3" height=600 border=1 link edit]
Реализуем её, шаг за шагом.
### Шаг 1. Добавляем информацию
Попробуем просто добавить Сову после Винни-Пуха:
```html
<h2>Винни-Пух</h2>
<div class="left">Картинка</div>
<p>..Текст о Винни..</p>
<h2>Сова</h2>
<div class="left">Картинка</div>
<p>..Текст о Сове..</p>
```
Результат [edit src="winnie-clear-1"]такого кода[/edit] будет странным, но предсказуемым:
[iframe src="winnie-clear-1" border="1" height=500 link edit]
Произошло следующее:
<ul>
<li>**Заголовок `<h2>Сова</h2>` не заметил `float`** (он же блочный элемент) и расположился сразу после предыдущего параграфа `<p>..Текст о Винни..</p>`.</li>
<li>После него идёт `float`-элемент -- картинка "Сова". Он был сдвинут влево. Согласно [алгоритму](#float-algorithm), он двигается до левой границы или до касания с другим `float`-элементом, что и произошло (картинка "Винни-Пух").</li>
<li>Так как у совы `float:left`, то **последующий текст обтекает её справа**.</li>
</ul>
### Шаг 2. Свойство clear
Мы, конечно же, хотели бы расположить заголовок "Сова" и остальную информацию ниже Винни-Пуха.
Для решения возникшей проблемы придумано свойство `clear`.
Синтаксис:
```css
clear: left | right | both;
```
Применение этого свойства сдвигает элемент вниз до тех пор, пока не закончатся `float'ы` слева/справа/с обеих сторон.
Применим его к заголовку `H2`:
```css
h2 {
clear: left;
}
```
Результат [edit src="winnie-clear-2"]получившегося кода[/edit] будет ближе к цели, но всё еще не идеален:
<img src="float-small-margin.png">
Элементы теперь в нужном порядке. Но куда пропал отступ `margin-top` у заголовка "Сова"?
Теперь заголовок "Сова" прилегает снизу почти вплотную к картинке, с учётом её `margin-bottom`, но без своего большого отступа `margin-top`.
Таково поведение свойства `clear`. Оно сдвинуло элемент `h2` вниз ровно настолько, чтобы элементов `float` не было *сбоку от его верхней границы*.
Если посмотреть на элемент заголовка внимательно в инструментах разработчика, то можно заметить отступ `margin-top` у заголовка по-прежнему есть, но он располагается "за" элементом `float` и не учитывается при работе в `clear`.
Чтобы исправить ситуацию, можно добавить перед заголовком пустой промежуточный элемент без отступов, с единственным свойством `clear:both`. Тогда уже под ним отступ заголовка будет работать нормально:
```html
<h2>Винни-Пух</h2>
<div class="left">Картинка</div>
<p>Текст</p>
*!*
<div style="clear:both"></div>
*/!*
<h2>Сова</h2>
<div class="left">Картинка</div>
<p>Текст</p>
```
Результат [edit src="winnie-clear-3"]получившегося кода[/edit]:
[iframe src="winnie-clear-3" border="1" height=600 link edit]
<ul>
<li>Свойство `clear` гарантировало, что `<div style="clear:both">` будет под картинкой с `float`.</li>
<li>Заголовок `<h2>Сова</h2>` идёт после этого `<div>`. Так что его отступ учитывается.</li>
</ul>
## Заполнение блока-родителя
Итак, мы научились располагать другие элементы *под* `float`. Теперь рассмотрим следующую особенность.
**Из-за того, что блок с `float` удалён из потока, родитель не выделяет под него места.**
Например, выделим для информации о Винни-Пухе красивый элемент-контейнер `<div class="hero">`:
```html
<div class="hero">
<h2>Винни-Пух</h2>
<div class="left">Картинка</div>
<p>Текст.</p>
</div>
```
Стиль контейнера:
```css
.hero {
background: #D2B48C;
border: 1px solid red;
}
```
Результат [edit src="winnie-clear-4"]получившегося кода[/edit]:
[iframe src="winnie-clear-4" border="1" height=300 link edit]
Элемент с `float` оказался выпавшим за границу родителя `.hero`.
Чтобы этого не происходило, используют одну из следующих техник.
### Поставить родителю float
Элемент с `float` обязан расшириться, чтобы вместить вложенные `float`.
Поэтому, если это допустимо, то установка `float` контейнеру всё исправит:
```css
.hero {
background: #D2B48C;
border: 1px solid red;
*!*
float: left;
*/!*
}
```
[iframe src="winnie-clearfill-float" border="1" height=300 link edit]
Разумеется, не всегда можно поставить родителю `float`, так что смотрим дальше.
### Добавить в родителя элемент с clear
Добавим элемент `div style="clear:both"` в самый конец контейнера `.hero`.
Он с одной стороны будет "нормальным" элементом, в потоке, и контейнер будет обязан выделить под него пространство, с другой -- он знает о `float` и сместится вниз.
Соответственно, и контейнер вырастет в размере:
```html
<div class="hero">
<h2>Винни-Пух</h2>
<div class="left">Картинка</div>
<p>Текст.</p>
*!*
<div style="clear:both"></div>
*/!*
</div>
```
Результат -- правильное отображение, как и в примере выше. [edit src="winnie-clearfill-div"]Открыть код[/edit].
Единственный недостаток этого метода -- лишний HTML-элемент в разметке.
### Универсальный класс clearfix
Чтобы не добавлять в HTML-код лишний элемент, можно задать его через `:after`.
```css
.clearfix:after {
content: "."; /* добавить содержимое: "." */
display: block; /* сделать блоком, т.к. inline не может иметь clear */
clear: both; /* с обеих сторон clear */
visibility: hidden; /* сделать невидимым, зачем нам точка внизу? */
height: 0; /* сделать высоту 0, чтобы не занимал место */
}
```
Добавив этот класс к родителю, получим тот же результат, что и выше. [edit src="winnie-clearfill-clearfix"]Открыть код[/edit].
Псевдоселектор `:after` не поддерживается в IE<8, но для старых IE сработает другое свойство:
```css
.clearfix {
zoom: 1; /* спец-свойство IE */
}
```
### overflow:auto/hidden
Если добавить родителю `overflow: hidden` или `overflow: auto`, то всё станет хорошо.
```css
.hero {
*!*
overflow: auto;
*/!*
}
```
Этот метод работает во всех браузерах. [edit src="winnie-clearfill-overflow"]Открыть код[/edit].
Несмотря на внешнюю странность, этот способ не является "хаком". Такое поведение прописано в спецификации CSS.
Однако, установка `overflow` может привести к появлению полосы прокрутки, способ с дополнительным элементом (или `.clearfix:after`, если без IE<8) более безопасен.
## Еще применения float
Одно применение -- для верстки текста, мы уже видели. Рассмотрим ещё несколько.
### Галерея
При помощи `float` можно сделать галерею изображений:
```html
<ul class="gallery">
<li>
<img src="1.png" width="130" height="130">
<div>Картинка 1</div>
</li>
<li>
<img src="2.png" width="130" height="130">
<div>Картинка 2</div>
</li>
...
</ul>
```
Стиль:
```css
.gallery li {
float: left;
width: 130px;
list-style: none;
}
```
Элементы `float:left` двигаются влево, а если это невозможно, то вниз, автоматически адаптируясь под ширину контейнера.
Результат:
[iframe src="gallery-float" border="1" height=550 link edit]
### Вёрстка в несколько колонок
Свойство `float` позволяет делать несколько вертикальных колонок.
### float:left + float:right
Например, для вёрстки в две колонки можно сделать два `<div>`. Первому указать `float:left` (левая колонка), а второму -- `float:right` (правая колонка).
Чтобы они не ссорились, каждой колонке нужно дополнительно указать ширину:
```html
<div>Шапка</div>
<div class="column-left">Левая колонка</div>
<div class="column-right">Правая колонка</div>
<div class="footer">Низ</div>
```
Стили:
```css
.column-left {
float: left;
width: 30%;
}
.column-right {
float: left;
width: 70%;
}
.footer {
clear: both;
}
```
Результат (добавлены краски):
[iframe src="two-columns" border="1" height=440 link edit]
В эту структуру легко добавить больше колонок с разной шириной. Правой колонке можно было бы указать и `float:right`.
### float + margin
Ещё вариант -- сделать `float` для левой колонки, а правую оставить в потоке, но с отбивкой через `margin`:
```css
.column-left {
float: left;
width: 30%;
}
.column-right {
margin-left: 30%;
}
.footer {
clear: both;
}
```
Результат (добавлены краски):
[iframe src="two-columns-2" border="1" height=440 link edit]
В примере выше -- показана небольшая проблема. Колонки не растягиваются до одинаковой высоты. Конечно, это не имеет значения, если фон одинаковый, но что, если он разный?
Технически, нет кросс-браузерного CSS-способа сделать, чтобы они растягивались. Есть различные обходы и трюки, которые позволяют обойти проблему в ряде ситуаций, но они выходят за рамки нашего обсуждения. Если интересно -- посмотрите, например, [Faux Columns](http://goodline.spb.ru/III-05-002.html).
Техник построения структуры страницы и колонок ("CSS layout") очень много. Более подробно вы можете с ними познакомиться в книгах и продвинутых статьях, либо просто придумать самому на основе того, как работает `float`.

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

View file

@ -0,0 +1,72 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
.gallery li {
float: left;
width: 130px;
list-style: none;
/* красивости */
border: 1px solid black;
text-align: center;
margin: 5px;
}
</style>
</head>
<body>
<ul class="gallery">
<li>
<img src="http://js.cx/carousel/1.png" width="130" height="130">
<div>Картинка 1</div>
</li>
<li>
<img src="http://js.cx/carousel/2.png" width="130" height="130">
<div>Картинка 2</div>
</li>
<li>
<img src="http://js.cx/carousel/3.png" width="130" height="130">
<div>Картинка 3</div>
</li>
<li>
<img src="http://js.cx/carousel/4.png" width="130" height="130">
<div>Картинка 4</div>
</li>
<li>
<img src="http://js.cx/carousel/5.png" width="130" height="130">
<div>Картинка 5</div>
</li>
<li>
<img src="http://js.cx/carousel/6.png" width="130" height="130">
<div>Картинка 6</div>
</li>
<li>
<img src="http://js.cx/carousel/7.png" width="130" height="130">
<div>Картинка 7</div>
</li>
<li>
<img src="http://js.cx/carousel/8.png" width="130" height="130">
<div>Картинка 8</div>
</li>
<li>
<img src="http://js.cx/carousel/9.png" width="130" height="130">
<div>Картинка 9</div>
</li>
</ul>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 239 KiB

View file

@ -0,0 +1,67 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
body, html {
margin: 0;
padding: 0;
}
.column-left {
float: left;
width: 30%;
}
.column-right {
margin-left: 30%;
width: 70%;
overflow: auto; /* расшириться вниз захватить float'ы */
}
.footer {
clear: both;
}
.inner {
margin: 1em;
}
</style>
</head>
<body>
<div style="background:yellow">Шапка</div>
<div class="column-left" style="background:#aef">
<div class="inner"> <!-- див для отступа внутри ширины родителя -->
<h3>Персонажи:</h3>
<ul>
<li>Винни-Пух</li>
<li>Ослик Иа</li>
<li>Сова</li>
<li>Кролик</li>
</ul>
</div>
</div>
<div class="column-right" style="background:tan">
<div class="inner">
<h3>Винни-Пух</h3>
<img src="http://js.cx/clipart/winnie-mult.jpg" style="float:left; margin: 0 1em .5em 0">
<p>Ви́нни-Пу́х (англ. Winnie-the-Pooh) — плюшевый мишка, персонаж повестей и стихов Алана Александра Милна (цикл не имеет общего названия и обычно тоже называется «Винни-Пух», по первой книге). Один из самых известных героев детской литературы XX века.</p>
<p>В 1960-е—1970-е годы, благодаря пересказу Бориса Заходера «Винни-Пух и все-все-все», а затем и фильмам студии «Союзмультфильм», где мишку озвучивал Евгений Леонов, Винни-Пух стал очень популярен и в Советском Союзе.</p>
</div>
</div>
<div class="footer" style="background:yellow">Низ</div>
</body>
</html>

View file

@ -0,0 +1,66 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
body, html {
margin: 0;
padding: 0;
}
.column-left {
float: left;
width: 30%;
}
.column-right {
float: left;
width: 70%;
overflow: auto; /* расшириться вниз захватить float'ы */
}
.footer {
clear: both;
}
.inner {
margin: 1em;
}
</style>
</head>
<body>
<div style="background:yellow">Шапка</div>
<div class="column-left" style="background:#aef">
<div class="inner"> <!-- див для отступа внутри ширины родителя -->
<h3>Персонажи:</h3>
<ul>
<li>Винни-Пух</li>
<li>Ослик Иа</li>
<li>Сова</li>
<li>Кролик</li>
</ul>
</div>
</div>
<div class="column-right" style="background:tan">
<div class="inner">
<h3>Винни-Пух</h3>
<img src="http://js.cx/clipart/winnie-mult.jpg" style="float:left; margin: 0 1em .5em 0">
<p>Ви́нни-Пу́х (англ. Winnie-the-Pooh) — плюшевый мишка, персонаж повестей и стихов Алана Александра Милна (цикл не имеет общего названия и обычно тоже называется «Винни-Пух», по первой книге). Один из самых известных героев детской литературы XX века.</p>
<p>В 1960-е—1970-е годы, благодаря пересказу Бориса Заходера «Винни-Пух и все-все-все», а затем и фильмам студии «Союзмультфильм», где мишку озвучивал Евгений Леонов, Винни-Пух стал очень популярен и в Советском Союзе.</p>
</div>
</div>
<div class="footer" style="background:yellow">Низ</div>
</body>
</html>

View file

@ -0,0 +1,36 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
.left-picture {
float: left;
/* рамочка и центрирование */
margin: 0 10px 5px 0;
text-align: center;
border: 1px solid black;
}
p {
background: #aef;
border: 1px solid red;
}
</style>
</head>
<body style="font-size:0.8em">
<h2>Винни-Пух</h2>
<img src="http://js.cx/clipart/winnie-mult.jpg" width="200" height="150" style="float:right;opacity:0.8">
<p>Ви́нни-Пу́х (англ. Winnie-the-Pooh) — плюшевый мишка, персонаж повестей и стихов Алана Александра Милна (цикл не имеет общего названия и обычно тоже называется «Винни-Пух», по первой книге). Один из самых известных героев детской литературы XX века.</p>
<p>В 1960-е—1970-е годы, благодаря пересказу Бориса Заходера «Винни-Пух и все-все-все», а затем и фильмам студии «Союзмультфильм», где мишку озвучивал Евгений Леонов, Винни-Пух стал очень популярен и в Советском Союзе.</p>
</body>
</html>

View file

@ -0,0 +1,34 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
.left-picture {
float: left;
/* рамочка и центрирование */
margin: 5px 10px 5px 0;
text-align: center;
border: 1px solid black;
}
</style>
</head>
<body style="font-size:0.8em">
<h2>Винни-Пух</h2>
<div class="left-picture">
<img src="http://js.cx/clipart/winnie-mult.jpg" width="200" height="150">
<div>Кадр из советского мультфильма</div>
</div>
<p>Ви́нни-Пу́х (англ. Winnie-the-Pooh) — плюшевый мишка, персонаж повестей и стихов Алана Александра Милна (цикл не имеет общего названия и обычно тоже называется «Винни-Пух», по первой книге).</p>
<p>Один из самых известных героев детской литературы XX века. </p>
</body>
</html>

View file

@ -0,0 +1,50 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
.left {
float: left;
width: 200px;
/* для красоты */
margin: 5px 10px 5px 0;
text-align: center;
border: 1px solid black;
}
h2 {
background: #aef;
}
</style>
</head>
<body style="font-size:0.8em">
<h2>Винни-Пух</h2>
<div class="left">
<img src="http://js.cx/clipart/winnie-mult.jpg" width="200" height="150">
<div>Кадр из советского мультфильма</div>
</div>
<p>Ви́нни-Пу́х (англ. Winnie-the-Pooh) — плюшевый мишка, персонаж повестей и стихов Алана Александра Милна (цикл не имеет общего названия и обычно тоже называется «Винни-Пух», по первой книге).</p>
<p>Один из самых известных героев детской литературы XX века.</p>
<h2>Сова</h2>
<div class="left">
<img src="http://js.cx/clipart/owl-mult.jpg" width="200" height="233">
<div>Кадр из советского мультфильма</div>
</div>
<p>Персонаж мультфильма про Винни-Пуха. Очень умная.</p>
<p>Говорит редко, но чрезвычайно мудро.</p>
</body>
</html>

View file

@ -0,0 +1,51 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
.left {
float: left;
width: 200px;
/* для красоты */
margin: 5px 10px 5px 0;
text-align: center;
border: 1px solid black;
}
h2 {
background: #aef;
clear: left;
}
</style>
</head>
<body style="font-size:0.8em">
<h2>Винни-Пух</h2>
<div class="left">
<img src="http://js.cx/clipart/winnie-mult.jpg" width="200" height="150">
<div>Кадр из советского мультфильма</div>
</div>
<p>Ви́нни-Пу́х (англ. Winnie-the-Pooh) — плюшевый мишка, персонаж повестей и стихов Алана Александра Милна (цикл не имеет общего названия и обычно тоже называется «Винни-Пух», по первой книге).</p>
<p>Один из самых известных героев детской литературы XX века.</p>
<h2>Сова</h2>
<div class="left">
<img src="http://js.cx/clipart/owl-mult.jpg" width="200" height="233">
<div>Кадр из советского мультфильма</div>
</div>
<p>Персонаж мультфильма про Винни-Пуха. Очень умная.</p>
<p>Говорит редко, но чрезвычайно мудро.</p>
</body>
</html>

View file

@ -0,0 +1,51 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
.left {
float: left;
width: 200px;
/* для красоты */
margin: 5px 10px 5px 0;
text-align: center;
border: 1px solid black;
}
h2 {
background: #aef;
}
</style>
</head>
<body style="font-size:0.8em">
<h2>Винни-Пух</h2>
<div class="left">
<img src="http://js.cx/clipart/winnie-mult.jpg" width="200" height="150">
<div>Кадр из советского мультфильма</div>
</div>
<p>Ви́нни-Пу́х (англ. Winnie-the-Pooh) — плюшевый мишка, персонаж повестей и стихов Алана Александра Милна (цикл не имеет общего названия и обычно тоже называется «Винни-Пух», по первой книге).</p>
<p>Один из самых известных героев детской литературы XX века.</p>
<div style="clear:both"></div>
<h2>Сова</h2>
<div class="left">
<img src="http://js.cx/clipart/owl-mult.jpg" width="200" height="233">
<div>Кадр из советского мультфильма</div>
</div>
<p>Персонаж мультфильма про Винни-Пуха. Очень умная.</p>
<p>Говорит редко, но чрезвычайно мудро.</p>
</body>
</html>

View file

@ -0,0 +1,41 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
.left {
float: left;
width: 200px;
/* для красоты */
margin: 5px 10px 5px 0;
text-align: center;
border: 1px solid black;
}
.hero {
background: #D2B48C;
border: 1px solid red;
}
</style>
</head>
<body style="font-size:0.8em">
<div class="hero">
<h2>Винни-Пух</h2>
<div class="left">
<img src="http://js.cx/clipart/winnie-mult.jpg" width="200" height="150">
<div>Кадр из советского мультфильма</div>
</div>
<p>Ви́нни-Пу́х (англ. Winnie-the-Pooh) — плюшевый мишка, персонаж повестей и стихов Алана Александра Милна (цикл не имеет общего названия и обычно тоже называется «Винни-Пух», по первой книге).</p>
<p>Один из самых известных героев детской литературы XX века.</p>
</div>
</body>
</html>

View file

@ -0,0 +1,55 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
.left {
float: left;
width: 200px;
/* для красоты */
margin: 5px 10px 5px 0;
text-align: center;
border: 1px solid black;
background: white;
}
.hero {
background: #D2B48C;
border: 1px solid red;
}
.clearfix:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
.clearfix {
zoom: 1;
}
</style>
</head>
<body style="font-size:0.8em">
<div class="hero clearfix">
<h2>Винни-Пух</h2>
<div class="left">
<img src="http://js.cx/clipart/winnie-mult.jpg" width="200" height="150">
<div>Кадр из советского мультфильма</div>
</div>
<p>Ви́нни-Пу́х (англ. Winnie-the-Pooh) — плюшевый мишка, персонаж повестей и стихов Алана Александра Милна (цикл не имеет общего названия и обычно тоже называется «Винни-Пух», по первой книге).</p>
<p>Один из самых известных героев детской литературы XX века.</p>
</div>
</body>
</html>

View file

@ -0,0 +1,43 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
.left {
float: left;
width: 200px;
/* для красоты */
margin: 5px 10px 5px 0;
text-align: center;
border: 1px solid black;
background: white;
}
.hero {
background: #D2B48C;
border: 1px solid red;
float: left;
}
</style>
</head>
<body style="font-size:0.8em">
<div class="hero">
<h2>Винни-Пух</h2>
<div class="left">
<img src="http://js.cx/clipart/winnie-mult.jpg" width="200" height="150">
<div>Кадр из советского мультфильма</div>
</div>
<p>Ви́нни-Пу́х (англ. Winnie-the-Pooh) — плюшевый мишка, персонаж повестей и стихов Алана Александра Милна (цикл не имеет общего названия и обычно тоже называется «Винни-Пух», по первой книге).</p>
<p>Один из самых известных героев детской литературы XX века.</p>
</div>
</body>
</html>

View file

@ -0,0 +1,43 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
.left {
float: left;
width: 200px;
/* для красоты */
margin: 5px 10px 5px 0;
text-align: center;
border: 1px solid black;
background: white;
}
.hero {
background: #D2B48C;
border: 1px solid red;
float: left;
}
</style>
</head>
<body style="font-size:0.8em">
<div class="hero">
<h2>Винни-Пух</h2>
<div class="left">
<img src="http://js.cx/clipart/winnie-mult.jpg" width="200" height="150">
<div>Кадр из советского мультфильма</div>
</div>
<p>Ви́нни-Пу́х (англ. Winnie-the-Pooh) — плюшевый мишка, персонаж повестей и стихов Алана Александра Милна (цикл не имеет общего названия и обычно тоже называется «Винни-Пух», по первой книге).</p>
<p>Один из самых известных героев детской литературы XX века.</p>
</div>
</body>
</html>

View file

@ -0,0 +1,45 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
.left {
float: left;
width: 200px;
/* для красоты */
margin: 5px 10px 5px 0;
text-align: center;
border: 1px solid black;
background: white;
}
.hero {
background: #D2B48C;
border: 1px solid red;
overflow: auto;
}
</style>
</head>
<body style="font-size:0.8em">
<div class="hero clearfix">
<h2>Винни-Пух</h2>
<div class="left">
<img src="http://js.cx/clipart/winnie-mult.jpg" width="200" height="150">
<div>Кадр из советского мультфильма</div>
</div>
<p>Ви́нни-Пу́х (англ. Winnie-the-Pooh) — плюшевый мишка, персонаж повестей и стихов Алана Александра Милна (цикл не имеет общего названия и обычно тоже называется «Винни-Пух», по первой книге).</p>
<p>Один из самых известных героев детской литературы XX века.</p>
</div>
</body>
</html>

View file

@ -0,0 +1,26 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
p { font-size: 80%; }
img {
border: 1px solid black;
opacity: 0.7;
}
</style>
</head>
<body>
<img src="http://js.cx/clipart/winnie-mult.jpg" style="position:absolute" width="200" height="150">
<p>Ви́нни-Пу́х (англ. Winnie-the-Pooh) — плюшевый мишка, персонаж повестей и стихов Алана Александра Милна (цикл не имеет общего названия и обычно тоже называется «Винни-Пух», по первой книге). Один из самых известных героев детской литературы XX века.</p>
<p>В 1960-е—1970-е годы, благодаря пересказу Бориса Заходера «Винни-Пух и все-все-все», а затем и фильмам студии «Союзмультфильм», где мишку озвучивал Евгений Леонов, Винни-Пух стал очень популярен и в Советском Союзе.</p>
</body>
</html>

View file

@ -0,0 +1,26 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
p { font-size: 80%; }
img {
border: 1px solid black;
opacity: 0.7;
}
</style>
</head>
<body>
<img src="http://js.cx/clipart/winnie-mult.jpg" style="position:absolute;right:0" width="200" height="150">
<p>Ви́нни-Пу́х (англ. Winnie-the-Pooh) — плюшевый мишка, персонаж повестей и стихов Алана Александра Милна (цикл не имеет общего названия и обычно тоже называется «Винни-Пух», по первой книге). Один из самых известных героев детской литературы XX века.</p>
<p>В 1960-е—1970-е годы, благодаря пересказу Бориса Заходера «Винни-Пух и все-все-все», а затем и фильмам студии «Союзмультфильм», где мишку озвучивал Евгений Леонов, Винни-Пух стал очень популярен и в Советском Союзе.</p>
</body>
</html>

View file

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
p { font-size: 80%; }
img {
border: 1px solid black;
}
</style>
</head>
<body>
<img src="http://js.cx/clipart/winnie-mult.jpg" style="float:right" width="200" height="150">
<p>Ви́нни-Пу́х (англ. Winnie-the-Pooh) — плюшевый мишка, персонаж повестей и стихов Алана Александра Милна (цикл не имеет общего названия и обычно тоже называется «Винни-Пух», по первой книге). Один из самых известных героев детской литературы XX века.</p>
<p>В 1960-е—1970-е годы, благодаря пересказу Бориса Заходера «Винни-Пух и все-все-все», а затем и фильмам студии «Союзмультфильм», где мишку озвучивал Евгений Леонов, Винни-Пух стал очень популярен и в Советском Союзе.</p>
</body>
</html>

Some files were not shown because too many files have changed in this diff Show more