border или outline — в чём разница и почему от рамки при наведении всё прыгает

Ты делаешь сетку карточек. Хочешь, чтобы при наведении карточка подсвечивалась рамкой:
.card:hover { border: 2px solid #D4A373; }
Наводишь мышку — и вся строка дёргается. Карточка стала на 4 пикселя шире и выше, соседи разъехались. Убираешь мышку — всё прыгает обратно.
А теперь замени одно слово:
.card:hover { outline: 2px solid #D4A373; }
Подсветка та же. Ничего не прыгает. Смотри, в чём фокус: border — часть самого элемента, а outline рисуется поверх страницы и места не занимает.
Главное отличие в одной фразе
border — это стенка коробки. Она входит в размер элемента и раздвигает соседей.
outline — это обводка маркером вокруг коробки. Её видно, но раскладка о ней не знает.
Это прямо следует из блочной модели: у элемента есть контент, отступы padding, рамка border и внешние отступы margin. outline в этот список не входит вообще.
«Но у меня же box-sizing: border-box!» — скажешь ты. С ним внешний размер карточки и правда не меняется: рамка встаёт внутрь заданной ширины. Только места внутри стало меньше на те же 4 пикселя. Текст, который еле влезал в одну строку, перепрыгивает на вторую — и карточка вырастает в высоту. Прыжок никуда не делся, он просто переехал внутрь. outline не трогает ни снаружи, ни внутри.
Сравнение по пунктам
1. Влияет ли на размер и соседей
border— да. Добавил 2 пикселя — элемент вырос на 4 по каждой оси.outline— нет. Можно включать и выключать хоть каждый кадр, ничего не сдвинется.
2. Можно ли задать только одну сторону
border— да:border-bottom,border-leftи так далее. Подчёркивание у вкладки — этоborder-bottom.outline— нет. Только вся обводка целиком, со всех четырёх сторон.
3. Скругление углов
border— повторяетborder-radiusвсегда.outline— тоже повторяет, но только в свежих браузерах: Chrome и Edge с версии 94, Firefox с 88, Safari с 16.4. На старых устройствах у круглой кнопки будет квадратный контур.
4. Отступ от элемента
border— вплотную кpadding, отодвинуть нельзя.outline— двигается свойствомoutline-offset. Положительное значение отодвигает наружу, отрицательное — заводит внутрь элемента.
5. Может ли обрезаться
border— внутри элемента, родитель сoverflow: hiddenего не тронет.outline— снаружи. Если родитель обрезает содержимое, контур у края пропадёт. Тогда помогает отрицательныйoutline-offset.
6. Для чего придуман
border— для дизайна: разделители, карточки, поля ввода.outline— для временной подсветки. Прежде всего — для фокуса с клавиатуры.
Кому что подойдёт
Вердикт простой.
Рамка, которая видна всегда, — это border. Карточка в покое, поле ввода, разделитель между пунктами меню. Это часть дизайна, и место под неё должно быть заложено.
Подсветка, которая появляется и исчезает, — это outline. Наведение, фокус, «выбранный» элемент в списке. Она не должна двигать вёрстку.
Если очень нужна именно рамка при наведении — например, только снизу — заложи её заранее прозрачной:
.tab { border-bottom: 2px solid transparent; }
.tab:hover { border-bottom-color: #D4A373; }
Место под рамку зарезервировано с самого начала. Меняется только цвет, поэтому ничего не прыгает. Цвет удобно держать в CSS-переменной, чтобы не копировать его по всему файлу.
Главная ошибка с outline
Многим не нравится синяя обводка вокруг кнопки после клика, и они пишут outline: none. Это ломает навигацию с клавиатуры: человек нажимает Tab и не видит, где он. Подробный разбор — в статье почему пропал контур фокуса.
Правильный ход — не убирать, а показывать только для клавиатуры:
button:focus { outline: none; }
button:focus-visible { outline: 2px solid #D4A373; outline-offset: 2px; }
:focus-visible браузер включает тогда, когда фокус пришёл с клавиатуры. После клика мышкой обводки не будет, после Tab — будет.
Можно ли сделать рамку только сверху через outline?
Нет, у outline нет отдельных сторон. Для одной стороны бери border с прозрачным цветом по умолчанию или box-shadow со смещением.
А box-shadow — это третий вариант?
Да. Тень тоже не занимает места и повторяет скругление во всех браузерах. Её часто используют вместо outline, но в режиме высокой контрастности Windows тени могут не отображаться, а outline остаётся.
Почему outline у кнопки квадратный, хотя углы круглые?
Скорее всего, браузер старый — например, Safari до 16.4. Новые версии ведут контур по border-radius сами.
Короткие уроки-истории, симулятор агента и ежедневная практика — в нашем мобильном приложении. Бесплатно.





