Поток документа | Flexbox | Float | inline-block в CSS
Привет, в этом уроке мы разберемся в том что такое нормальный поток документа, научимся его изменять с помощью CSS свойств, разберемся с тем как работать с inline-block, float и flexbox свойствами. Текстовая версия урок в полной версии статьи.
Поток документа
Поток документа - определяет то каким способом элементы будут располагаться на странице.
Normal flow - базовый поток описывает то как элементы располагаются на странице, когда к ним не применили ни одного CSS свойства.
Для того чтобы чтобы управлять потоком нашего документа с помощью CSS нам в первую очередь нужно выстроить правильный базовый поток документа в нашем HTML.
inline и inline-block
Задача: Необходимо выставить элементы .item друг возле друга по 2 в ряд.
Решение: Для начала выставим ширину элемента 50% и добавим inline-block чтобы они могли выстраиваться друг возле друга.
HTML File - link
.item {
width: 50%;
display: inline-block;
}
Проблема: Ширина наших элементов изменилась, но сами элементы не выстроились друг возле друга. Это происходит из-за того что браузер интерпретирует элементы .item как строчно-блочные, а значит учитывает пробельные символы которые мы ставим внутри нашего HTML документа и также отображает их на странице. Для того чтобы решить это проблему нам необходимо убрать эти пробельные символы которые находятся между нашими блоками .item . Для этого нам достаточно найти родителя блоков .item, а это блок .wrapper и выставить ему font-size: 0.
.wrapper {
font-size: 0;
}
Пробельный символ, это символ аналогичный любой букве, а это значит, что если мы выставим размер шрифта в 0 то он исчезнет и не будет занимать места, как и все остальные символы внутри этого блока.
Сейчас мы видим что элементы на странице выстроились друг возле друга, как мы и задумывали, но текст не отображается, это происходит из-за того что мы поставили размер шрифта для всего текста в блоке 0px. Для того чтобы вернуть текст внутри блоков .item на свое место, нам необходимо задать размер шрифта отдельно для них.
.item {
font-size: 16px;
}
Теперь все работает правильно и мы добились желаемого результата, самый главный недостаток такого способа - это то что нам постоянно нужно контролировать размер шрифта и это не всегда удобно. Именно из-за этих недостатков это способ практически не используется в современной верстке, а на замену ему пришли другие, более современные способы.
Float
Задача: Необходимо выставить элементы .item друг возле друга по 4 в ряд.
Решение: Для начала выставим ширину элемента 50% и добавим float: left чтобы элементы .item могли обтекать друг друга с левой стороны.
HTML File - link
.item {
width: 25%;
float: left;
}
Видим что такой способ достаточно хорош и все сразу стало как нам было нужно. Но есть проблема, если мы проинспектируем родительский элемент (.wrapper) наших .item блоков, то сразу увидим нечто странное, а именно то что высота этого элемента равна 0, как будто в нем нет никаких дочерних элементов, хотя они есть.
Для того чтобы решить эту проблему нам нужно растянуть .wrapper чтобы он занимал именно столько высоты сколько нужно.
Обычно для этого используются псевдо-элементы, он них мы будем говорить позднее, но используем их для того чтобы решить нашу проблему.
Вкратце, псевдо-элемент, это такой элемент который создается не через HTML, но через CSS, а браузер интерпретирует его как часть структуры сайта.
.wrapper:after {
content: '';
display: block;
clear: both;
}
Теперь все отображается правильно, вся суть в том что мы создаем еще один, полностью пустой, элемент и отменяем для него float , с помощью свойства clear: both. После чего этот, пустой, элемент располагается в самом конце нашего блока .wrapper и тем самым растягивает его высоту, и делает ее правильной.
Такое использование будет не слишком удобным, если у нам будет много элементов позиционированных через float, в таком случае на проще сделать отдельный класс который будет добавлять такие стили нужным для нас элементам. Обычно такой класс называется .clearfix.
.clearfix:after {
content: '';
display: block;
clear: both;
}
И добавим его для нашего блока wrapper, единственное что нам нужно делать, это добавлять класс .clearfix, для родительских элементов дети которых позиционированы с помощью свойств float.
Этот способ активно использовался раньше, но уже не так актуален и практически не используется в данный момент, но такой подход все еще можно встретить в реально жизни.
Flexbox
Задача: Необходимо выставить элементы .item друг возле друга по 2 в ряд.
Решение: Для начала выставим ширину элемента 50% и добавим display: flex чтобы элементы .item могли выстраиваться друг возле друга
HTML File - link
В таком случае flex прописываем для родительского элемента.
.wrapper {
display: flex;
}
.item {
width: 50%;
}
У нас появилась проблема, а именно то что сейчас все элементы встроены в ряд, это происходит по причине того что flex сам, автоматически пересчитывает ширину игнорируя заданную нами ширину для элементов. Для того чтобы это исправить, нам необходимо добавить свойство flex-wrap: wrap для родительского элемента .wrapper .
.wrapper {
flex-wrap: wrap;
}
Теперь мы сами можем контролировать контролировать ширину наших внутренних элементов через CSS, но не забывайте, что если вам подходит стандартное поведение flex и его автоматическая работа с шириной, то можете игнорировать flex-wrap: wrap
Другие возможности
Для того чтобы удобно работать с элементами у flex есть ряд других свойств которые помогают удобно позиционировать элементы.
Для наглядности изменю ширину элементов .item
.item {
width: 18%;
}
Свойство justify-content помогает нам позиционировать элементы по горизонтали Все его значение рассмотрим на странице в видео уроке.
.wrapper {
justify-content: space-evenly;
}
Свойство align-items помогает нам позиционировать элементы по вертикали, для наглядности я увеличу высоту блока .wrapper .
Все его значение рассмотрим на странице в видео уроке.
.wrapper {
border-top: 3px solid black;
border-bottom: 3px solid black;
background-color: #ccc;
height: 600px;
/* flex свойство */
align-items: center;
}
flex-direction
Свойство flex-direction определяет в каком направлении будут отображаться элементы. По умолчанию flex-direction равно значению row, в зависимости от направления отображения у нас будет изменяться и работа свойств justify-content и align-items
Для flex-direction: row и row-reverse:
justify-content - будет позиционировать по горизонтали
align-items - будет позиционировать по вертикали
Для flex-direction: column и column-reverse:
justify-content - будет позиционировать по вертикали
align-items - будет позиционировать по горизонтали
Все его значение рассмотрим на странице в видео уроке.
.wrapper {
height: initial;
/* flex свойство */
flex-direction: row;
}
Свойство order - позволяет нам, вручную, определять в котором будут отображаться элементы. Свойство order должно задаваться внутренним элементам, вложенным в .wrapper, а значит тем которые являются детьми первого уровня элемента у которой присутствует свойство display: flex.
В нашем случае это элементы .item так как они является детьми .wrapper у которого и прописано свойство display: flex.
.item:nth-child(1) {
order: 4
}
.item:nth-child(2) {
order: 1
}
.item:nth-child(3) {
order: 2
}
.item:nth-child(4) {
order: 3
}
Также существует еще больше flex-свойств, которые используются не так часто, о них можно почитать в документации.
Тип данных Object в JavaScript
Привет, в этом уроке мы основательно пройдемся по типу данных object, рассмотрим типы объектов, свойства, научимся создавать объекты и узнаем различия между ними, а также поговорим об операторе typeof и нюансах его работы. Текстовый урок в полной версии статьи.
Object
object - ссылочный тип данных, является то самостоятельной единицей, имеющей свойства и определённый тип.
У объекта есть свойства которые с ним ассоциируется. Свойство объекта можно понимать как переменные закрепленные за ним.
Для того чтобы создать объект у нас есть несколько способов.
Конструктор класса
// Вызов конструктора класса Object
let objectExample_1 = new Object();
// Далее наполняем его данными
objectExample_1.name = 'John';
objectExample_1.age = 22;
В примере выше мы создали внутри объекта свойства name и age и записали в них данные.
Литерал
Мы можем использовать более простой и удобный синтаксис для создания объектов.
let objectExample_2 = {}
// наполнение объекта данными
Если мы используем литеральный синтаксис, то можем создать объект сразу с значениями.
objectExample_2.name = 'Alice';
objectExample_2.age = 30;
console.log(objectExample_2)
let objectExample_3 = {Как видите, литеральный синтаксис намного удобнее нежели создание через конструктор класса. Его и будем использовать.
name: 'Vladimir',
age: 25
}
console.log(objectExample_3)
let user = {
firstName: 'John',
lastName: 'Doe',
age: 30,
gender: 'male'
}
Допустим я хочу получить имя данного пользователя.
console.log(user);
console.log(user.firstName);
Аналогичным образом я могу получить доступ ко всем значениям свойств объекта.
console.log(user.lastName);
console.log(user.age);
console.log(user.gender);
Синтаксис квадратных скобок - []
Ключи в объектах это всегда строки или Symbol, сосредоточимся пока на строках. Как мы знаем строки не всегда могу состоять из одного слова в котором нет пробелов и как быть если нам нужно создать свойство в объекте имя которого будет состоять из 2х слов разделенных пробелами или вообще будет являться выражением. Для этого будем использовать [ ].
let student = {Получить значения этих свойств у нас просто так не получится. Если мы будем использовать синтаксис точки '.' то получим ошибку. Вместо этого будем использовать квадратные скобки [ ].
firstName: 'John',
['last name']: 'Dou', // Имя свойства содержащее пробел
['student-' + 'age']: 30, // Вычисляемое имя свойства
}
console.log(student);
console.log(student.firstName) // Обычный способ
console.log(student['last name'])
console.log(student['student-age'])
Готово, теперь все работает!
Вложенные объекты
Также стоит понимать что если мы можем вкладывать примитивы в объекты, делая их значениями ключей, то аналогичным образом мы можем вкладывать и другим объекты.
const deepObject = {
name: 'Mazda',
model: '#1',
owner: {
firstName: 'John',
lastNam: 'Doe',
age: 12
}
}
console.log(deepObject)
Это простой пример, на самом деле вложенность может быть очень большой, важно понимать что так можно делать.
Array
array - массив данных, а также итерируемый объект, также относится к типу данных object. Ключи для элементов массива создаются автоматически и являются индексами, позицией элемента внутри массива.
Индексирование массива начинается с нуля.
const arr = ['John', 'Alice', 'Andrew', 'Antony'];
console.log(arr)
У массива есть длинна (length), это свойство содержит количество элементов массива.
console.log(arr.length);
Берем элементы по их индексу.
console.log(
arr[0], arr[1], arr[2], arr[3]
)
Если мы хотим гарантировано получить значение последнего элемента в массиве.
console.log(
arr[arr.length - 1]
)
В этом уроке мы не будем погружаться в массивы и их работу полностью, на данный момент стоит знать что массивы тоже относятся к типу данных object.
Функции
Функции - это участки кода которые можно переиспользовать, в этом уроке мы не будем их рассматривать подробно.
Для создания функции существует несколько способов ключевое слово function и стрелочный синтаксис.
function foo(a, b) {
return a + b;
}
const bar = (a, b) => {
return a - b;
}
console.log(foo);
console.log(bar);
Функции также являются объектами и относятся к типу данных object.
P.S. Подпишись на мой youtube и telegram канал чтобы регулярно получать новый контент.
Все о datalist, fieldset и button в HTML
Привет, в рамках этого урока мы разберемся оставшимися тегами формы, а именно: datalist, fieldset, legend, button. Также разберемся в нюансах и частоте использования этих тегов. Текстовая версия урока в полной версии этой статьи.
Datalist
<datalist> - содержит набор опций (<option>), доступных для выбора. Выбранное значение будет установлено для элемента <input>, с атрибутом list.
Не стоит использовать его вместо тега <select>, но можно использовать как вспомогательный тег для <input>. Причина в том что его сложнее обрабатывать через JavaScript.
<form action="">
<label for="ice-cream-choice">Choose a flavor:</label>
<input list="ice-cream-flavors" id="ice-cream-choice" name="ice-cream-choice" />
<datalist id="ice-cream-flavors">
<option value="Chocolate">
<option value="Coconut">
<option value="Mint">
<option value="Strawberry">
<option value="Vanilla">
</datalist>
</form>
Fieldset
<fieldset> - существует для группировки <input> внутри тега <form>, а также помогает удобно управлять группой полей.
<form action="#">
<h3>Registration form</h3>
<fieldset>
<div>
<label for="name_input">First name:</label>
<input id="name_input" type="text" placeholder="Email">
</div>
<div>
<label for="surname_input">Surname:</label>
<input id="surname_input" type="text" placeholder="Surname">
</div>
</fieldset>
<br>
<fieldset disabled>
<div>
<label for="email_input">Email:</label>
<input id="email_input" type="text" placeholder="Email">
</div>
<div>
<label for="password_input">Password:</label>
<input id="password_input" type="text" placeholder="Password">
</div>
</fieldset>
</form>
У <fieldset> также есть несколько атрибутов, которые помогают управлять сразу всей группой <input>.
name - задает общее имя для группы
disabled - делает группу недоступной для редактирования
form - если <fieldset> лежит вне тега <form> то этот атрибут позволит вам связать их.
<form action="" id="example_form">
<h3>Example form</h3>
<label>
<input type="text" placeholder="Some example input">
</label>
</form>
<fieldset form="example_form">
<div>
<label for="name_2_input">First name:</label>
<input id="name_2_input" type="text" placeholder="Email">
</div>
<div>
<label for="surname_2_input">Surname:</label>
<input id="surname_2_input" type="text" placeholder="Surname">
</div>
</fieldset>
Legend
<legend> - Является заголовком для группы элементов, сгруппированных через <fieldset>
<form action="">
<h3>Another Example Form</h3>
<fieldset>
<legend>User info</legend>
<div>
<label for="name_3_input">First name:</label>
<input id="name_3_input" type="text" placeholder="Email">
</div>
<div>
<label for="surname_3_input">Surname:</label>
<input id="surname_3_input" type="text" placeholder="Surname">
</div>
</fieldset>
<br>
<fieldset disabled>
<legend>User credentials</legend>
<div>
<label for="email_3_input">Email:</label>
<input id="email_3_input" type="text" placeholder="Email">
</div>
<div>
<label for="password_3_input">Password:</label>
<input id="password_3_input" type="text" placeholder="Password">
</div>
</fieldset>
Button
<button> - Парный тег, который предназначен для создания кнопки, имеет схожие атрибуты с тегом <input>. Может использовать как внутри <form> заменяя собой <input type="button">, так и просто как отдельный элемент на странице.
<form action="">
<h3>Another Example Form</h3>
<fieldset>
<legend>User info</legend>
<div>
<label for="name_3_input">First name:</label>
<input id="name_3_input" type="text" placeholder="Email">
</div>
<div>
<label for="surname_3_input">Surname:</label>
<input id="surname_3_input" type="text" placeholder="Surname">
</div>
</fieldset>
<br>
<fieldset disabled>
<legend>User credentials</legend>
<div>
<label for="email_3_input">Email:</label>
<input id="email_3_input" type="text" placeholder="Email">
</div>
<div>
<label for="password_3_input">Password:</label>
<input id="password_3_input" type="text" placeholder="Password">
</div>
</fieldset>
<fieldset>
<legend>Form Controls</legend>
<button type="submit">Submit</button>
<button type="reset">Clear Form</button>
</fieldset>
</form>
Вес селекторов в CSS
Привет, в этом уроке мы на примерах рассмотрим как работает вес и приоритетность селекторов. Текстовое описание урока в полной версии статьи.
Вес селектора - так как у нас в CSS есть огромное количество способов обращения к элементу по селектору, а селектор мы придумываем сами, внутри браузер разделяет их по весу, и отдает приоритет тем стилям вес селектора которых 'тяжелее'.
Селекторы по весу:
1. inline стили (те которые мы пишем внутри атрибута style для тега)
2. #id (селектор id)
3. .class (селектор class и любых других атрибутов кроме id)
4. <tagName> (название тега)
Так как мы можем комбинировать селекторы то и их вес тоже будет складываться.
Пример #1
Пытаемся изменить цвет текста у которого уже написаны inline стили
#p1 {
color: red;
}
Как видим цвет этого элемента не изменился, так происходит потому что у селектора inline стилей селектор тяжелее чем у селектора id, а значит браузер отдаст приоритет селектору inline стилей, а стили которые связаны с id этого элемента будут проигнорированы.
Аналогично будет происходить если мы будем пробовать обратится по классу, тегу или каким-то другим образом.
.p1 {
color: red;
}
Как видим, ни одно из перечисленных css правил не сработало.
[title="p1"] {
color: red;
}
Пример #2
Работаем с элементов #p2 у которого нет inline стилей.
Задам ему цвет через селектор id.
#p2 {
color: deeppink;
}
Пробуем изменить стили через селектор class
.p2 {
color: blueviolet;
}
и другие селекторы
[title="p2"] {
color: blueviolet;
}
p {
color: blueviolet;
}
Как видим цвет элемента не изменился, а остался таким как был задан в селекторе через id это происходит потому что id имеет больше вес чем остальные селекторы, а на текущем элементе нет никаких inline стилей которые могли бы изменять его цвет.
Пример #3
Что делать если наши селекторы одинаковые по весу?
Представим себе ситуацию, у нас есть элемент p3 у которого есть несколько классов и для каждого и этих классов написаны свои стили.
.p3-first {Так как вес этих селекторов одинаковый то в приоритете будут те стили что написаны ниже в файле .css
color: red;
}
.p3-second {
color: green;
}
Файлы с урока - ссылка
Мой youtube
Опять баг в CSS
upd. CSS-скрипт → CSS
Теги select и textarea в HTML5
Select
<select> - элемент содержащий меню опций <option> или меню групп опций <optgroup>. Имеет схожие с <input> атрибуты, а также атрибуты multiple и size. Обычно select располагается внутри тега <form> или связывается с ним атрибутом form.
<form action="">
<select name="some_list"></select>
</form>
<option> - тег, который используется для определения пункта списка внутри тега <select>, но также его можно встретить и в тегах. Атрибуты: selected - позволяет пред-выбрать элемент. disabled - работает как всегда. и другие.
<form action="">
<label for="select">Select item</label>
<select name="list" id="select">
<option value="item-1">Item #1</option>
<option value="item-2">Item #2</option>
<option value="item-3">Item #3</option>
<option value="item-4">Item #4</option>
</select>
</form>
<optgroup> - позволяет группировать опции внутри <select>. Имеет атрибуты - name и disabled. name - задает имя группы. disabled - исключает возможность выбора элементов из группы. label - Задает имя группы которое видно пользователю.
<form action="">
<label for="select2">Select item</label>
<select name="list" id="select2">
<optgroup label="Veggie">
<option value="item-1" selected>Mushrooms</option>
<option value="item-2">Carrot</option>
</optgroup>
<optgroup label="Meat" disabled>
<option value="item-3">Pork</option>
<option value="item-4">Chicken</option>
</optgroup>
</select>
</form>
Атрибут multiple тега <select> позволяет выбирать не один, а сразу несколько <option> если зажата клавиша CTRL (для windows или linux) или COMMAND (для macOS)
<form action="">
<label for="select3">Select item</label>
<select name="list" id="select3" multiple>
<optgroup label="Veggie">
<option value="item-1" selected>Mushrooms</option>
<option value="item-2">Carrot</option>
</optgroup>
<optgroup label="Meat" disabled>
<option value="item-3">Pork</option>
<option value="item-4">Chicken</option>
</optgroup>
</select>
</form>
Textarea
<textarea> - позволяет добавить поле для ввода большого количества текста, обычно располагается внутри тега <form>. Имеет атрибуты схожие с <input>, а также cols и rows.
cols - определяет ширину <textarea>
rows - определяет высоту <textarea>
<form action="">
<label for="message">Your massage</label>
<textarea
name="user_message"
id="message"
cols="30"
rows="10"
placeholder="Your message..."
></textarea>
</form>
У тега <textarea> нет атрибута value, а если вы ходите установить ему какое-то значение по-умолчанию, нужно писать его между открывающим и закрывающим тегами.
<form action="">
<label for="message2">Your massage</label>
<textarea
name="user_message"
id="message2"
cols="30"
rows="10"
placeholder="Your message..."
>Some predefined data goes here</textarea>
</form>
Файлы с урока
P.S. Подписывайся на мой youtube и telegram каналы чтобы получать больше контента )