Почему при position:absolute, top:50%, left:50% нужно использовать transform: translate(-50%, -50%)
Что проверяют
Понимаете ли вы, от чего считаются проценты в CSS. Вопрос выглядит рецептом для центрирования, но за ним стоит разница баз отсчёта у разных свойств, и по ответу видно, разбираетесь ли вы в вёрстке или помните готовый приём.
Как отвечать
top и left в процентах считаются от содержащего блока, то есть от ближайшего позиционированного предка. top: 50% ставит верхнюю границу элемента на середину контейнера, left: 50% левую. В итоге с центром контейнера совпадает левый верхний угол элемента, и он свисает вправо и вниз ровно на половину собственного размера.
Отнять эту половину можно, только зная размер элемента. Проценты у transform считаются как раз от самого элемента, поэтому translate(-50%, -50%) сдвигает его назад на половину его ширины и высоты, какими бы они ни были: размер задавать не нужно, содержимое может расти.
.dialog {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}Хорошо назвать и альтернативы: display: grid с place-items: center у родителя либо inset: 0 вместе с margin: auto при заданном размере. Отдельное свойство translate делает то же самое и не спорит с анимацией transform.
Где спотыкаются
Забывают position: relative у родителя. Тогда отсчёт идёт от начального содержащего блока размером с окно, и элемент встаёт по центру страницы, а не по центру карточки.
Не знают побочных эффектов transform. Элемент становится содержащим блоком для потомков с position: fixed, и такой потомок перестаёт прилипать к окну, а ещё создаётся свой контекст наложения, из-за чего ломается ожидаемый порядок слоёв.
Теряют сдвиг, назначив элементу другой transform, например scale при наведении: свойство перезаписывается целиком, и функции надо перечислять вместе. Плюс при нечётной ширине половина даёт дробный пиксель и текст местами размывается.