Ты хочешь поставить несколько кнопок в ряд, но они почему-то стоят столбиком. Или пытаешься задать ширину ссылке, но ничего не меняется. Это поведение определяет свойство display — одно из самых фундаментальных в CSS.
Блочный элемент занимает всю доступную ширину и начинается с новой строки.
display: block;Блочные по умолчанию: div, p, h1–h6, ul, ol, li, header, section, article.
width, height, margin, padding со всех сторонСтрочный элемент — ведёт себя как слово в тексте: встаёт в поток строки.
display: inline;Строчные по умолчанию: span, a, strong, em, img, button, input.
width и height не работаютmargin не работает, горизонтальный — работаетЛучшее из двух миров: стоит в строке как inline, но принимает все свойства блочного.
display: inline-block;width, height, вертикальный marginПрименяется для: кнопок в ряд, плашек-тегов, значков.
Полностью скрывает элемент — он не занимает место и не отрисовывается.
.hidden { display: none; }Применяется для: скрыть меню до клика, убрать элемент на мобильных, переключение вкладок.
.invisible { visibility: hidden; }Элемент скрыт, но место сохраняется. Сосед не двигается.
display: none → элемент исчезает, место освобождается
visibility: hidden → элемент невидим, но место занятоПревращает элемент в flex-контейнер. Дети автоматически встают в ряд и их легко выравнивать.
.nav {
display: flex;
gap: 16px;
align-items: center;
}Flex — основа современных layouts. Подробно разберём в следующих уроках.
/* Сделать ссылки блочными (для вертикального меню) */
nav a { display: block; padding: 12px 16px; }
/* Сделать li в ряд (горизонтальное меню) */
nav li { display: inline-block; }
/* Скрыть кнопку на мобильных */
@media (max-width: 768px) {
.desktop-only { display: none; }
}Ошибка 1: Задать width inline-элементу
span { width: 200px; } /* Не сработает — span это inline */
span { display: inline-block; width: 200px; } /* Работает */Ошибка 2: Перепутать display:none и visibility:hidden
/* Хочешь скрыть, но не освобождать место (анимации, placeholder) */
.loading-spinner { visibility: hidden; } /* Правильно */
/* Хочешь убрать элемент полностью */
.modal { display: none; } /* Правильно */Ошибка 3: Лишние пробелы между inline-block элементами
<div class="tag">CSS</div>
<div class="tag">HTML</div>
<!-- Между тегами есть пробел в HTML → щель между элементами в браузере -->Решение — flexbox (там нет этой проблемы).
В современном CSS inline-block почти полностью вытеснен flexbox — flex решает те же задачи лучше. Но понимать block и inline обязательно: это основа того, как браузер строит страницу. Знание того, какие элементы блочные, а какие строчные — база, без которой невозможно понять, почему вёрстка ведёт себя именно так.
block, inline, inline-block — в чём разница
// Добавляем стили
const style = document.createElement('style')
style.textContent = `
.demo-block { background: #bee3f8; margin: 4px 0; padding: 8px; }
.demo-inline { background: #fbb6ce; padding: 4px 8px; }
.demo-inline-block { background: #c6f6d5; padding: 8px 16px; margin: 4px; }
`
document.head.appendChild(style)
const section = document.createElement('div')
document.body.appendChild(section)
// === BLOCK ===
const blockLabel = document.createElement('p')
blockLabel.textContent = 'display: block — каждый занимает всю строку:'
section.appendChild(blockLabel)
;['Блок 1', 'Блок 2', 'Блок 3'].forEach(text => {
const div = document.createElement('div')
div.className = 'demo-block'
div.textContent = text
section.appendChild(div)
})
// === INLINE ===
const inlineLabel = document.createElement('p')
inlineLabel.textContent = 'display: inline — все в одну строку:'
section.appendChild(inlineLabel)
;['Тег1', 'Тег2', 'Тег3'].forEach(text => {
const span = document.createElement('span')
span.className = 'demo-inline'
span.textContent = text
// inline по умолчанию для span
section.appendChild(span)
section.appendChild(document.createTextNode(' '))
})
// === INLINE-BLOCK ===
const ibLabel = document.createElement('p')
ibLabel.style.marginTop = '12px'
ibLabel.textContent = 'display: inline-block — в ряд, но с размерами:'
section.appendChild(ibLabel)
;['Кнопка A', 'Кнопка B', 'Кнопка C'].forEach(text => {
const btn = document.createElement('div')
btn.className = 'demo-inline-block'
btn.style.display = 'inline-block'
btn.style.width = '100px' // width работает у inline-block!
btn.textContent = text
section.appendChild(btn)
})
// === DISPLAY: NONE vs VISIBILITY: HIDDEN ===
const gone = document.createElement('div')
gone.textContent = 'Я скрыт через display:none'
gone.style.display = 'none'
gone.style.backgroundColor = '#fed7d7'
section.appendChild(gone)
const invisible = document.createElement('div')
invisible.textContent = 'Я скрыт через visibility:hidden (место занято)'
invisible.style.visibility = 'hidden'
invisible.style.backgroundColor = '#fef3c7'
invisible.style.padding = '8px'
section.appendChild(invisible)
const after = document.createElement('div')
after.textContent = '← Я следую после скрытых блоков'
after.style.backgroundColor = '#e0e7ff'
after.style.padding = '8px'
section.appendChild(after)
// Читаем display
console.log('display:none — computed display:', window.getComputedStyle(gone).display)
// none
console.log('visibility:hidden — computed visibility:', window.getComputedStyle(invisible).visibility)
// hidden
console.log('visibility:hidden — место занято (display):', window.getComputedStyle(invisible).display)
// block (элемент есть, просто невидим)Ты хочешь поставить несколько кнопок в ряд, но они почему-то стоят столбиком. Или пытаешься задать ширину ссылке, но ничего не меняется. Это поведение определяет свойство display — одно из самых фундаментальных в CSS.
Блочный элемент занимает всю доступную ширину и начинается с новой строки.
display: block;Блочные по умолчанию: div, p, h1–h6, ul, ol, li, header, section, article.
width, height, margin, padding со всех сторонСтрочный элемент — ведёт себя как слово в тексте: встаёт в поток строки.
display: inline;Строчные по умолчанию: span, a, strong, em, img, button, input.
width и height не работаютmargin не работает, горизонтальный — работаетЛучшее из двух миров: стоит в строке как inline, но принимает все свойства блочного.
display: inline-block;width, height, вертикальный marginПрименяется для: кнопок в ряд, плашек-тегов, значков.
Полностью скрывает элемент — он не занимает место и не отрисовывается.
.hidden { display: none; }Применяется для: скрыть меню до клика, убрать элемент на мобильных, переключение вкладок.
.invisible { visibility: hidden; }Элемент скрыт, но место сохраняется. Сосед не двигается.
display: none → элемент исчезает, место освобождается
visibility: hidden → элемент невидим, но место занятоПревращает элемент в flex-контейнер. Дети автоматически встают в ряд и их легко выравнивать.
.nav {
display: flex;
gap: 16px;
align-items: center;
}Flex — основа современных layouts. Подробно разберём в следующих уроках.
/* Сделать ссылки блочными (для вертикального меню) */
nav a { display: block; padding: 12px 16px; }
/* Сделать li в ряд (горизонтальное меню) */
nav li { display: inline-block; }
/* Скрыть кнопку на мобильных */
@media (max-width: 768px) {
.desktop-only { display: none; }
}Ошибка 1: Задать width inline-элементу
span { width: 200px; } /* Не сработает — span это inline */
span { display: inline-block; width: 200px; } /* Работает */Ошибка 2: Перепутать display:none и visibility:hidden
/* Хочешь скрыть, но не освобождать место (анимации, placeholder) */
.loading-spinner { visibility: hidden; } /* Правильно */
/* Хочешь убрать элемент полностью */
.modal { display: none; } /* Правильно */Ошибка 3: Лишние пробелы между inline-block элементами
<div class="tag">CSS</div>
<div class="tag">HTML</div>
<!-- Между тегами есть пробел в HTML → щель между элементами в браузере -->Решение — flexbox (там нет этой проблемы).
В современном CSS inline-block почти полностью вытеснен flexbox — flex решает те же задачи лучше. Но понимать block и inline обязательно: это основа того, как браузер строит страницу. Знание того, какие элементы блочные, а какие строчные — база, без которой невозможно понять, почему вёрстка ведёт себя именно так.
block, inline, inline-block — в чём разница
// Добавляем стили
const style = document.createElement('style')
style.textContent = `
.demo-block { background: #bee3f8; margin: 4px 0; padding: 8px; }
.demo-inline { background: #fbb6ce; padding: 4px 8px; }
.demo-inline-block { background: #c6f6d5; padding: 8px 16px; margin: 4px; }
`
document.head.appendChild(style)
const section = document.createElement('div')
document.body.appendChild(section)
// === BLOCK ===
const blockLabel = document.createElement('p')
blockLabel.textContent = 'display: block — каждый занимает всю строку:'
section.appendChild(blockLabel)
;['Блок 1', 'Блок 2', 'Блок 3'].forEach(text => {
const div = document.createElement('div')
div.className = 'demo-block'
div.textContent = text
section.appendChild(div)
})
// === INLINE ===
const inlineLabel = document.createElement('p')
inlineLabel.textContent = 'display: inline — все в одну строку:'
section.appendChild(inlineLabel)
;['Тег1', 'Тег2', 'Тег3'].forEach(text => {
const span = document.createElement('span')
span.className = 'demo-inline'
span.textContent = text
// inline по умолчанию для span
section.appendChild(span)
section.appendChild(document.createTextNode(' '))
})
// === INLINE-BLOCK ===
const ibLabel = document.createElement('p')
ibLabel.style.marginTop = '12px'
ibLabel.textContent = 'display: inline-block — в ряд, но с размерами:'
section.appendChild(ibLabel)
;['Кнопка A', 'Кнопка B', 'Кнопка C'].forEach(text => {
const btn = document.createElement('div')
btn.className = 'demo-inline-block'
btn.style.display = 'inline-block'
btn.style.width = '100px' // width работает у inline-block!
btn.textContent = text
section.appendChild(btn)
})
// === DISPLAY: NONE vs VISIBILITY: HIDDEN ===
const gone = document.createElement('div')
gone.textContent = 'Я скрыт через display:none'
gone.style.display = 'none'
gone.style.backgroundColor = '#fed7d7'
section.appendChild(gone)
const invisible = document.createElement('div')
invisible.textContent = 'Я скрыт через visibility:hidden (место занято)'
invisible.style.visibility = 'hidden'
invisible.style.backgroundColor = '#fef3c7'
invisible.style.padding = '8px'
section.appendChild(invisible)
const after = document.createElement('div')
after.textContent = '← Я следую после скрытых блоков'
after.style.backgroundColor = '#e0e7ff'
after.style.padding = '8px'
section.appendChild(after)
// Читаем display
console.log('display:none — computed display:', window.getComputedStyle(gone).display)
// none
console.log('visibility:hidden — computed visibility:', window.getComputedStyle(invisible).visibility)
// hidden
console.log('visibility:hidden — место занято (display):', window.getComputedStyle(invisible).display)
// block (элемент есть, просто невидим)Напиши HTML-страницу с горизонтальным навигационным меню из трёх ссылок: "Главная", "Каталог", "Контакты". Используй теги <a> с display: inline-block, padding: 8px 16px, фиолетовым фоном (#7b2ff7) и белым текстом. Добавь четвёртую скрытую ссылку "Секрет" с display: none.
display: inline-block позволяет ссылкам стоять в ряд и принимать padding. display: none полностью убирает элемент — он не занимает место. Ссылка "Секрет" добавляет класс nav-secret поверх nav-link — правило с display: none перекрывает inline-block.