простой пример анимации на css для border
<div class="pr">блок с фото например</div>и стили самого блока:
/* Контейнер .pr — база для анимации */ body div.pr { display: flex; justify-content: center; align-items: stretch; gap: 20px; width: auto; padding: 30px; box-sizing: content-box; /* Критично для псевдоэлементов */ position: relative; overflow: visible; /* Чтобы границы не обрезались при анимации */ /* Убираем обычные границы — их заменят анимированные псевдоэлементы */ border: none !important; } /* Правая граница (анимация сверху вниз) */ body div.pr::before { content: ""; position: absolute; top: 0; right: 0; width: 2px; height: 100%; background: #000; /* Цвет границы */ /* Начальное состояние: сжата по вертикали в точку */ transform: scaleY(0); transform-origin: top center; /* Рост сверху вниз */ /* Анимация */ animation: drawVertical 0.8s cubic-bezier(0.4, 0, 0.2, 1) 0.1s forwards; will-change: transform; } /* Нижняя граница (анимация слева направо) */ body div.pr::after { content: ""; position: absolute; bottom: 0; left: 0; width: 100%; height: 2px; background: #000; /* Цвет границы */ /* Начальное состояние: сжата по горизонтали в точку */ transform: scaleX(0); transform-origin: left center; /* Рост слева направо */ /* Анимация с небольшой задержкой после правой */ animation: drawHorizontal 0.8s cubic-bezier(0.4, 0, 0.2, 1) 0.4s forwards; will-change: transform; } /* Ключевые кадры */ @keyframes drawVertical { to { transform: scaleY(1); } } @keyframes drawHorizontal { to { transform: scaleX(1); } } /* Отключаем анимацию при повторной загрузке (опционально) */ /* Если хочешь, чтобы анимация срабатывала только 1 раз за сессию: */ @media (prefers-reduced-motion: reduce) { body div.pr::before, body div.pr::after { animation: none; transform: scale(1); /* Сразу видимые */ } }