Урок 05. Формы, особенности стилизации форм

  • Методы центрирования. Формы

Методы центрирования. Формы

Для центрирования важно знать свойство display центрируемого объекта, и display и position его родителя.

Центрирование строчных (display: inline) и строчно-блочных (display: inline-block) объектов происходит за счёт придания предку свойства text-align: center. Из элементов, которые являются строчно-блочными и которые необходимо центрировать, вспомню, пожалуй лишь «пагинацию». Пагинация — это нумерация страниц из гиперссылок. Создайте новую папку и в ней стандартный набор из index.html и css/style.css. Теперь в наш style.css мы будем включать код, ответственный за выведение секций.

* {
	box-sizing:border-box;
}
html, body {
	min-width:320px;
	font-size:16px;
	margin:0;
	padding:0;
	height:100%;
}
body {
	font-family:Roboto, Calibri, Arial, sans-serif;
	color:#252525;
}
h1 {
	font-size:36px;
	line-height:48px;
	text-align:center;
	margin-bottom:12px;
}

.section {
	width:100%;
	position:relative;
	margin:0 0 40px 0;
}

.section:after {
	content:"";
	display:block;
	clear:both;
}

.section .inner {
	max-width: 1160px;
	padding:0 15px;
	margin:0 auto;
}

В index.html скопируем обычный код, но теперь с одной секцией.

<html lang="ru">

<head>

	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
	<meta name="viewport" content="width=device-width, initial-scale=1.0" />
	<meta name="author" content="" />
	<title>Вёрстка - введение</title>
	<link rel="stylesheet" href="css/style.css" />

</head>

<body>

<div class="section">
	<div class="inner">
		<h2>Заголовок секции</h2>
		
	</div>
</div>


</body>

</html>

Теперь нам надо сформировать пагинацию. Она будет примером центрирование строчно-блочного элемента и заодно полезным паттерном на будущее. Кстати, традиционно строчно-блочной её делают неспроста. Как правило, у каждой кнопки разная ширина и в целом ширину пагинации точно мы никогда не знаем. А значит, если она будет блочная, то центрировать её будет тяжелее (но тоже возможно). Более того, дизайн некоторых страниц сайта в будущем может потребовать сместить пагинацию влево или вправо. Для этого достаточно будет у блока-обёртки изменить значение text-align. Т.е. строчно-блочная пагинация больше соответствует принципу переиспользования.

Подобные элементы (пагинация, меню, «хлебные крошки») логически представляют из себя список, а значит для их представления в HTML мы будем использовать элемент <ul>.

		<p>Повседневная практика <!-- много текста из предыдущего примера --> новых предложений.</p>

		<div class="pagination-outer">
			<ul class="pagination">
			<li><a href="#"><<</a></li>
			<li><a href="#"><</a></li>
			<li><a href="#">1</a></li>
			<li><span>2</span></li>
			<li><a href="#">3</a></li>
			<li><a href="#">4</a></li>
			<li><span>...</span></li>
			<li><a href="#">71</a></li>
			<li><a href="#">72</a></li>
			<li><a href="#">></a></li>
			<li><a href="#">>></a></li>
			</ul>
		</div>

Обратите внимание на последние числа в кнопках пагинации. Они могут быть одно- двух- и даже трёхчимвольными, они-то и задают неопределённость ширины блока пагинации, из-за которой её приходится центрировать. Теперь зададим стили, которые позволят пагинации центрироваться и отображаться горизонтальным блоком, а не списком.

.pagination-outer {
	text-align:center;
}
.pagination {
	list-style-type:none;
	display:inline-block;
}
.pagination li {
	float:left;
}

Результат:

Теперь нам следует стилизовать этот виджет.

.pagination-outer {
	text-align:center;
}
.pagination {
	list-style-type:none;
	display:inline-block;
	padding:0;
	border:1px solid #636363;
	border-radius:3px;
	overflow:hidden;
}
.pagination li {
	float:left;
	font-size:14px;
	line-height:16px;
}
.pagination a,
.pagination span {
	display:block;
	padding:8px 12px;
	text-decoration:none;
	color:#252525;
	border-right:1px solid #636363;
	color:#303030;
}
.pagination>li:last-child a,
.pagination>li:last-child span {border-right:0;}
.pagination a{ /* Стилизация ссылки */
	background: #ffffff;
	background: -moz-linear-gradient(top,  #ffffff 0%, #eaeaea 50%, #dbdbdb 50%, #d8d8d8 100%);
	background: -webkit-linear-gradient(top,  #ffffff 0%,#eaeaea 50%,#dbdbdb 50%,#d8d8d8 100%);
	background: linear-gradient(to bottom,  #ffffff 0%,#eaeaea 50%,#dbdbdb 50%,#d8d8d8 100%);
	filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#d8d8d8',GradientType=0 );
}
.pagination span.active { /* Стилизация текущей страницы */
	background: #dbdbdb;
	background: -moz-linear-gradient(top,  #dbdbdb 0%, #ffffff 15%, #ffffff 50%, #ffffff 50%, #ffffff 85%, #d8d8d8 100%);
	background: -webkit-linear-gradient(top,  #dbdbdb 0%,#ffffff 15%,#ffffff 50%,#ffffff 50%,#ffffff 85%,#d8d8d8 100%);
	background: linear-gradient(to bottom,  #dbdbdb 0%,#ffffff 15%,#ffffff 50%,#ffffff 50%,#ffffff 85%,#d8d8d8 100%);
	filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#dbdbdb', endColorstr='#d8d8d8',GradientType=0 );
}
.pagination a:hover { /* Стилизация ссылки по наведению мыши на неё */
	background: #ffffff;
	background: -moz-linear-gradient(top,  #ffffff 0%, #eaeaea 50%, #dbdbdb 50%, #f7f7f7 50%, #c9c9c9 100%);
	background: -webkit-linear-gradient(top,  #ffffff 0%,#eaeaea 50%,#dbdbdb 50%,#f7f7f7 50%,#c9c9c9 100%);
	background: linear-gradient(to bottom,  #ffffff 0%,#eaeaea 50%,#dbdbdb 50%,#f7f7f7 50%,#c9c9c9 100%);
	filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#c9c9c9',GradientType=0 );
}

CSS-градиенты делаются при помощи специальных сервисов, ссылки будут в конце материала.

Позиционирование. Центрирование блоков

С самым первым вариантом центрирования блока мы уже познакомились на практике. Блок c заданной шириной центрируется инструкцией margin:0 auto; относительно внешнего блока. Именно так центрируется .inner внутри .section.

Другой вариант центрирования базируется на знании свойства position. position отвечает, как можно догадаться, за позиционирование элемента на странице. По умолчанию оно у всех элементов имеет значение static. Всего же возможны 5 значений:

  • absolute
  • fixed
  • relative
  • static
  • inherit

absolute — элемент выводится из общего потока DOM и начинает позиционироваться заданными абсолютно значениями свойств top, right, bottom или left относительно элемента-родителя, у которого свойство position установлено в absolute, fixed или relative. Если такового родителя нет, то элемент позиционируется относительно окна браузера.

fixed — элемент позиционируется относительно видимой части окна браузера, не прокручивается. Управляется свойствами top, right, bottom или left. Применяется для создания непрокручиваемых элементов, в частности, фиксированных панелей в верхней или нижней части окна браузера.

relative — элемент позиционируется относительно своего изначального положения. Управляется свойствами top, right, bottom или left. Остальное содержимое документа отображается так, как будто элемент остался на месте. Применяется для pixel perfect вёрстки.

static — позиционирование по умолчанию. Изменение свойств top, right, bottom или left не приводит к каким-либо результатам.

inherit — позиционирование наследуется от родителя.

Теперь применим знания на практике. Нужно по центру страницы вывести затемнение и на фоне затемнения форму логина. Для решения этой задачи будем использовать position:absolute;. HTML-код всплывающих форм (любых) обычно добавляют в самом конце страницы, перед закрывающим тегом </body>. То, что мы будем писать сейчас, можно добавлять в конец уже созданной страницы с пагинацией.

<div class="overshadow"></div>
<div class="form-block form-block_positioning login">
	<!-- Здесь будет код формы -->
</div>

Блок с классом .overshadow будет выступать у нас затемнением, он должен быть растянут на весь экран. Блок с тремя классами будет содержать в себе форму. Три класса ему дано в связи с использованием методологии БЭМ (Блок-элемент-модификатор). Классы .form-block и .login являются блоками. Класс .form-block_positioning (один символ «_» , это важно) это класс-модификатор. Через символ «_» указываем, что именно модифицируем. Если использовать БЭМ строго, то ещё и значение свойства модификатора должно быть указано: .form-block_position-absolute, но в данном случае это сильно загромождает код и я назвал класс .form-block_positioning, чтобы любой другой верстальщик понял, что CSS, отвечающий за позиционирование блока .form-block хранится здесь.

<div class="overshadow"></div>
<div class="form-block form-block_positioning login">
	<form method="post" name="login-form" action="#">
		<div class="form-block__inner"> <!-- Элемент inner блока form-block -->
			<!-- Здесь будут собственно поля ввода -->
		</div>
	</form>
</div>

Тег <form> оборачивает форму, самые его важные параметры (не все):

  • method — параметр указывает метод передачи данных серверу. Значение get добавляет параметры в адресную строку, после отправки URL будет выглядеть так: http://site.ru/index.php?param1=value1&param2=value2. param1 и param2 это атрибуты name тегов <input>, которые внутри данной формы. Метод передачи post не изменяет URL.
  • name — «имя» формы, чтобы к ней и к её элементам было проще обращаться из JavaScript. Необязательный параметр.
  • action — страница, которой надо передать значения формы, после клика по кнопке отправки.

.form-block__inner — это элемент-родитель, который оборачивает другие элементы формы. Название класса дано по методолгии БЭМ. Два символа «_» означают, что это элемент блока .form-block. Элементы могут быть только у блоков. Если бы у этого элемента был модификатор, то он добавлялся бы отдельным классом, например так (эти изменения не надо вносить в ваш код):

<div class="overshadow"></div>
<div class="form-block form-block_positioning login">
	<form method="post" name="login-form" action="#">
		<div class="form-block__inner form-block__inner_border-1 form-block__inner_margin-20-40"> <!-- Элемент inner блока form-block -->
			<!-- Здесь будут собственно поля ввода -->
		</div>
	</form>
</div>

Теперь добавим заголовок и собственно поля ввода. Конечный вариант HTML-кода:

<div class="overshadow"></div>
<div class="form-block form-block_positioning login">
	<form method="post" name="login-form" action="#">
		<div class="form-block__inner">
			<div class="h3">Авторизация</div><!-- Вместо элемента <h3> используем класс, который имеет стили, как у заголовка <h3> -->
			<div class="inputs">
				<div class="inputs__row">
					<label class="label">
						<span class="label__text">Логин:</span>
						<input type="text" name="username" placeholder="Логин" />
					</label>
				</div>
				<div class="inputs__row">
					<label class="label">
						<span class="label__text">Пароль:</span>
						<input type="password" name="password" placeholder="Пароль" />
					</label>
				</div>
				<div class="inputs__row">
					<input type="submit" value="Войти" />
				</div>
			</div>
		</div>
	</form>
</div>

Тег <label> делает содержимое относящимся к тегу <input>, который в него вложен. Другими словами, если кликнуть по содержимому этого тега, то вложенное в него поле получит фокус.

Тег <input> — это поле ввода. Параметр type уточняет, какого именно вида. Пока что в форме у нас встречается три типа: text, password и submit. text — это же значение по умолчанию, обычное текстовое поле. password — для ввода пароля, вместо символов при вводе там будут точки и из него нельзя скопировать введённый текст. submit — один из способов создать кнопку, по клику на которой будет осуществляться отправка.

Теперь напишем стили, которые осуществят позиционирование и отображение элементов.

Вариант центрирования №1. position:absolute; и отрицательные margin

Этот метод наиболее кроссбраузерный, но требует, чтобы вы знали ширину и высоту блока, который центрируете.

/* Всплывающая форма логина */
.overshadow {
	/* Обратите внимание, как мы растягиваем затемнитель фона, это не то же самое, что width:100%; и height:100%; */
	position:absolute;
	top:0;
	right:0;
	bottom:0;
	left:0;
	background:#000;
	opacity:.8;
}
.form-block {
	width:400px;
	height:300px;
	background:#fff;
}
.form-block_positioning {
	position:absolute;
	padding:20px;
	left:50%;
	top:50%;
	margin:-150px 0 0 -200px; /* За счёт маргинов смещаем на половину величины */
}

Вариант центрирования №2. position:absolute; и CSS3 transform

Этот вариант поддерживают более-менее современные браузеры.

/* Всплывающая форма логина */
.overshadow {
	/* Обратите внимание, как мы растягиваем затемнитель фона, это не то же самое, что width:100%; и height:100%; */
	position:absolute;
	top:0;
	right:0;
	bottom:0;
	left:0;
	background:#000;
	opacity:.8;
}
.form-block {
	width:400px;
	height:300px;
	background:#fff;
}
.form-block_positioning {
	position:absolute;
	padding:20px;
	left:50%;
	top:50%;
	transform: translate(-50%, -50%);
	/* Если нужно центрировать блок только по одной оси, то так:
	transform: translateX(-50%);
	transform: translateY(-50%);
	*/
}

В современных браузерах оба вариант дают одинаковый эффект.

Теперь немного стилизуем форму. Конечный вариант стилей:

/* Всплывающая форма логина */
.overshadow {
	position:absolute;
	top:0;
	right:0;
	bottom:0;
	left:0;
	background:#000;
	opacity:.8;
}
.form-block {
	width:400px;
	height:220px; /* после того, как стилизовали содержимое, убираем лишнюю высоту */
	background:#fff;
}
.form-block_positioning {
	position:absolute;
	padding:20px;
	left:50%;
	top:50%;
	transform: translate(-50%, -50%);
}
h3, .h3 {
	display:block;
	text-align:center;
	font-weight:bold;
	font-size:24px;
	line-height:30px;
	margin:0 0 12px 0;
}
.inputs {
	width:100%;
	position:relative; /* Источник возможного позиционирования для каких-либо элементов в будущем */
}
.inputs:after { /* Возможно внутри будут колонки, такое часто бывает в всплывающих формах, тоже на будущее */
	content:"";
	display:block;
	clear:both;
}
.inputs__row {
	width:100%;
	display:block;
	font-size:14px;
	line-height:30px;
	min-height:30px;
	margin:0 0 12px 0;
}
.inputs__row:after {
	content:"";
	display:block;
	clear:both;
}
.inputs > .inputs__row:last-child {
	margin-bottom:0; /* У последней строчки отменяем нижний margin */
}
.label {
	width:100%;
	display:block;
}

/* конструкция ниже означает, что выбираем теги input с атрибутом type равным text и password */
.label input[type=text], 
.label input[type=password] {
	width:60%;
	float:right;
	height:30px;
	padding:4px 8px;
}
.login .label__text {
	width:40%;
	float:left;
	text-align:right;
	padding:0 20px;
}
.login input[type=submit] {
	float:right;
	width:40%;
	height:45px;
	line-height:45px;
}

Результат: