CSS анимация обводки блоков
Интересные эффекты для границ блоков контента с анимацией, которые вам могут пригодиться при оформлении страниц сайта.
Представляю вам несколько, как я их назвал, "вкусняшек" на html5 и css с исходным кодом, которые пригодятся при разработке дизайна и вёрстке сайтов. Вы можете скачать CSS стили и использовать эти разработки в своих проектах. Уверен, они украсят дизайн страниц ваших сайтов и придадут им динамичность.
<ul class="slides">
<input type="radio" name="radio-btn" id="img-1" checked />
<li class="slide-container">
<div class="slide">
<img src="http://farm9.staticflickr.com/8072/8346734966_f9cd7d0941_z.jpg" />
</div>
<div class="nav">
<label for="img-6" class="prev">‹</label>
<label for="img-2" class="next">›</label>
</div>
</li>
<input type="radio" name="radio-btn" id="img-2" />
<li class="slide-container">
<div class="slide">
<img src="http://farm9.staticflickr.com/8504/8365873811_d32571df3d_z.jpg" />
</div>
<div class="nav">
<label for="img-1" class="prev">‹</label>
<label for="img-3" class="next">›</label>
</div>
</li>
<input type="radio" name="radio-btn" id="img-3" />
<li class="slide-container">
<div class="slide">
<img src="http://farm9.staticflickr.com/8068/8250438572_d1a5917072_z.jpg" />
</div>
<div class="nav">
<label for="img-2" class="prev">‹</label>
<label for="img-4" class="next">›</label>
</div>
</li>
<input type="radio" name="radio-btn" id="img-4" />
<li class="slide-container">
<div class="slide">
<img src="http://farm9.staticflickr.com/8061/8237246833_54d8fa37f0_z.jpg" />
</div>
<div class="nav">
<label for="img-3" class="prev">‹</label>
<label for="img-5" class="next">›</label>
</div>
</li>
<input type="radio" name="radio-btn" id="img-5" />
<li class="slide-container">
<div class="slide">
<img src="http://farm9.staticflickr.com/8055/8098750623_66292a35c0_z.jpg" />
</div>
<div class="nav">
<label for="img-4" class="prev">‹</label>
<label for="img-6" class="next">›</label>
</div>
</li>
<input type="radio" name="radio-btn" id="img-6" />
<li class="slide-container">
<div class="slide">
<img src="http://farm9.staticflickr.com/8195/8098750703_797e102da2_z.jpg" />
</div>
<div class="nav">
<label for="img-5" class="prev">‹</label>
<label for="img-1" class="next">›</label>
</div>
</li>
<li class="nav-dots">
<label for="img-1" class="nav-dot" id="img-dot-1"></label>
<label for="img-2" class="nav-dot" id="img-dot-2"></label>
<label for="img-3" class="nav-dot" id="img-dot-3"></label>
<label for="img-4" class="nav-dot" id="img-dot-4"></label>
<label for="img-5" class="nav-dot" id="img-dot-5"></label>
<label for="img-6" class="nav-dot" id="img-dot-6"></label>
</li>
</ul>
.slides {
padding: 0;
width: 609px;
height: 420px;
display: block;
margin: 0 auto;
position: relative;
}
.slides * {
user-select: none;
user-select: none;
user-select: none;
user-select: none;
user-select: none;
touch-callout: none;
}
.slides input { display: none; }
.slide-container { display: block; }
.slide {
top: 0;
opacity: 0;
width: 609px;
height: 420px;
display: block;
position: absolute;
transform: scale(0);
transition: all .7s ease-in-out;
}
.slide img {
width: 100%;
height: 100%;
}
.nav label {
width: 200px;
height: 100%;
display: none;
position: absolute;
opacity: 0;
z-index: 9;
cursor: pointer;
transition: opacity .2s;
color: #FFF;
font-size: 156pt;
text-align: center;
line-height: 380px;
font-family: "Varela Round", sans-serif;
background-color: rgba(255, 255, 255, .3);
text-shadow: 0px 0px 15px rgb(119, 119, 119);
}
.slide:hover + .nav label { opacity: 0.5; }
.nav label:hover { opacity: 1; }
.nav .next { right: 0; }
input:checked + .slide-container .slide {
opacity: 1;
transform: scale(1);
transition: opacity 1s ease-in-out;
}
input:checked + .slide-container .nav label { display: block; }
.nav-dots {
width: 100%;
bottom: 9px;
height: 11px;
display: block;
position: absolute;
text-align: center;
}
.nav-dots .nav-dot {
top: -5px;
width: 11px;
height: 11px;
margin: 0 4px;
position: relative;
border-radius: 100%;
display: inline-block;
background-color: rgba(0, 0, 0, 0.6);
}
.nav-dots .nav-dot:hover {
cursor: pointer;
background-color: rgba(0, 0, 0, 0.8);
}
input#img-1:checked ~ .nav-dots label#img-dot-1,
input#img-2:checked ~ .nav-dots label#img-dot-2,
input#img-3:checked ~ .nav-dots label#img-dot-3,
input#img-4:checked ~ .nav-dots label#img-dot-4,
input#img-5:checked ~ .nav-dots label#img-dot-5,
input#img-6:checked ~ .nav-dots label#img-dot-6 {
background: rgba(0, 0, 0, 0.8);
}
DEMO
<div class="gradient-background">
<div class="d-flex flex-column justify-content-center w-100 h-100">
<div class="d-flex flex-column justify-content-center align-items-center">
<h1 class="fw-light text-white m-0">Pure CSS Gradient Background Animation</h1>
<div class="btn-group my-5">
<a href="#" class="btn btn-outline-light" aria-current="page"><i class="fas fa-file-download me-2"></i> Какая-то кнопка </a>
<a href="#" class="btn btn-outline-light">Ещё кнопка <i class="fas fa-expand ms-2"></i></a>
</div>
</div>
</div>
</div>
.gradient-background {
background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);
background-size: 400% 400%;
animation: gradient 15s ease infinite;
height: 100vh;
}
@keyframes gradient {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}
<nav role="navigation">
<div id="menuToggle">
<!--
A fake / hidden checkbox is used as click reciever,
so you can use the :checked selector on it.
-->
<input type="checkbox" />
<!--
Some spans to act as a hamburger.
They are acting like a real hamburger,
not that McDonalds stuff.
-->
<span></span>
<span></span>
<span></span>
<!--
Too bad the menu has to be inside of the button
but hey, it's pure CSS magic.
-->
<ul id="menu">
<a href="#"><li>Home</li></a>
<a href="#"><li>About</li></a>
<a href="#"><li>Info</li></a>
<a href="#"><li>Contact</li></a>
<a href="https://erikterwan.com/" target="_blank"><li>Show me more</li></a>
</ul>
</div>
</nav>
#menuToggle
{
display: block;
position: relative;
top: 50px;
left: 50px;
z-index: 1;
user-select: none;
user-select: none;
}
#menuToggle a
{
text-decoration: none;
color: #232323;
transition: color 0.3s ease;
}
#menuToggle a:hover
{
color: tomato;
}
#menuToggle input
{
display: block;
width: 40px;
height: 32px;
position: absolute;
top: -7px;
left: -5px;
cursor: pointer;
opacity: 0; /* hide this */
z-index: 2; /* and place it over the hamburger */
touch-callout: none;
}
/*
* Just a quick hamburger
*/
#menuToggle span
{
display: block;
width: 33px;
height: 4px;
margin-bottom: 5px;
position: relative;
background: #cdcdcd;
border-radius: 3px;
z-index: 1;
transform-origin: 4px 0px;
transition: transform 0.5s cubic-bezier(0.77,0.2,0.05,1.0),
background 0.5s cubic-bezier(0.77,0.2,0.05,1.0),
opacity 0.55s ease;
}
#menuToggle span:first-child
{
transform-origin: 0% 0%;
}
#menuToggle span:nth-last-child(2)
{
transform-origin: 0% 100%;
}
/*
* Transform all the slices of hamburger
* into a crossmark.
*/
#menuToggle input:checked ~ span
{
opacity: 1;
transform: rotate(45deg) translate(-2px, -1px);
background: #232323;
}
/*
* But let's hide the middle one.
*/
#menuToggle input:checked ~ span:nth-last-child(3)
{
opacity: 0;
transform: rotate(0deg) scale(0.2, 0.2);
}
/*
* Ohyeah and the last one should go the other direction
*/
#menuToggle input:checked ~ span:nth-last-child(2)
{
transform: rotate(-45deg) translate(0, -1px);
}
/*
* Make this absolute positioned
* at the top left of the screen
*/
#menu
{
position: absolute;
width: 300px;
margin: -100px 0 0 -50px;
padding: 50px;
padding-top: 125px;
background: #ededed;
list-style-type: none;
font-smoothing: antialiased;
/* to stop flickering of text in safari */
transform-origin: 0% 0%;
transform: translate(-100%, 0);
transition: transform 0.5s cubic-bezier(0.77,0.2,0.05,1.0);
}
#menu li
{
padding: 10px 0;
font-size: 22px;
}
/*
* And let's slide it in from the left
*/
#menuToggle input:checked ~ ul
{
transform: none;
}
<!-- thumbnail image wrapped in a link -->
<a href="#img1">
<img src="https://picsum.photos/seed/9/500/300">
</a>
<!-- lightbox container hidden with CSS -->
<a href="#" class="lightbox" id="img1">
<span style="background-image: url('https://picsum.photos/seed/9/900/450')"></span>
</a>
.lightbox {
/* Default to hidden */
display: none;
/* Overlay entire screen */
position: fixed;
z-index: 999;
top: 0;
left: 0;
right: 0;
bottom: 0;
/* A bit of padding around image */
padding: 1em;
/* Translucent background */
background: rgba(0, 0, 0, 0.8);
}
/* Unhide the lightbox when it's the target */
.lightbox:target {
display: block;
}
.lightbox span {
/* Full width and height */
display: block;
width: 100%;
height: 100%;
/* Size and position background image */
background-position: center;
background-repeat: no-repeat;
background-size: contain;
}
<ul class="unstyled centered">
<li>
<input class="styled-checkbox" id="styled-checkbox-1" type="checkbox" value="value1">
<label for="styled-checkbox-1">Checkbox</label>
</li>
<li>
<input class="styled-checkbox" id="styled-checkbox-2" type="checkbox" value="value2" checked>
<label for="styled-checkbox-2">CSS Only</label>
</li>
<li>
<input class="styled-checkbox" id="styled-checkbox-3" type="checkbox" value="value3" disabled>
<label for="styled-checkbox-3">A disabled checkbox</label>
</li>
<li>
<input class="styled-checkbox" id="styled-checkbox-4" type="checkbox" value="value4">
<label for="styled-checkbox-4">Fourth option</label>
</li>
</ul>
.styled-checkbox {
position: absolute; // take it out of document flow
opacity: 0; // hide it
& + label {
position: relative;
cursor: pointer;
padding: 0;
}
// Box.
& + label:before {
content: '';
margin-right: 10px;
display: inline-block;
vertical-align: text-top;
width: 20px;
height: 20px;
background: white;
}
// Box hover
&:hover + label:before {
background: #f35429;
}
// Box focus
&:focus + label:before {
box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.12);
}
// Box checked
&:checked + label:before {
background: #f35429;
}
// Disabled state label.
&:disabled + label {
color: #b8b8b8;
cursor: auto;
}
// Disabled box.
&:disabled + label:before {
box-shadow: none;
background: #ddd;
}
// Checkmark. Could be replaced with an image
&:checked + label:after {
content: '';
position: absolute;
left: 5px;
top: 9px;
background: white;
width: 2px;
height: 2px;
box-shadow:
2px 0 0 white,
4px 0 0 white,
4px -2px 0 white,
4px -4px 0 white,
4px -6px 0 white,
4px -8px 0 white;
transform: rotate(45deg);
}
}
<section class="buttons">
<button class="draw">Draw</button>
<button class="draw meet">Draw Meet</button>
<button class="center">Center</button>
<button class="spin">Spin</button>
<button class="spin circle">Spin Circle</button>
<button class="spin thick">Spin Thick</button>
</section>
button {
background: none;
border: 0;
box-sizing: border-box;
margin: 1em;
padding: 1em 2em;
// Using inset box-shadow instead of border for sizing simplicity
box-shadow: inset 0 0 0 2px $red;
color: $red;
font-size: inherit;
font-weight: 700;
// Required, since we're setting absolute on pseudo-elements
position: relative;
vertical-align: middle;
&::before,
&::after {
box-sizing: inherit;
content: '';
position: absolute;
width: 100%;
height: 100%;
}
}
.draw {
transition: color 0.25s;
&::before,
&::after {
// Set border to invisible, so we don't see a 4px border on a 0x0 element before the transition starts
border: 2px solid transparent;
width: 0;
height: 0;
}
// This covers the top & right borders (expands right, then down)
&::before {
top: 0;
left: 0;
}
// And this the bottom & left borders (expands left, then up)
&::after {
bottom: 0;
right: 0;
}
&:hover {
color: $cyan;
}
// Hover styles
&:hover::before,
&:hover::after {
width: 100%;
height: 100%;
}
&:hover::before {
border-top-color: $cyan; // Make borders visible
border-right-color: $cyan;
transition:
width 0.25s ease-out, // Width expands first
height 0.25s ease-out 0.25s; // And then height
}
&:hover::after {
border-bottom-color: $cyan; // Make borders visible
border-left-color: $cyan;
transition:
border-color 0s ease-out 0.5s, // Wait for ::before to finish before showing border
width 0.25s ease-out 0.5s, // And then exanding width
height 0.25s ease-out 0.75s; // And finally height
}
}
// Inherits from .draw
.meet {
&:hover {
color: $yellow;
}
// Start ::after in same position as ::before
&::after {
top: 0;
left: 0;
}
// Change colors
&:hover::before {
border-top-color: $yellow;
border-right-color: $yellow;
}
&:hover::after {
border-bottom-color: $yellow;
border-left-color: $yellow;
transition: // Animate height first, then width
height 0.25s ease-out,
width 0.25s ease-out 0.25s;
}
}
// Does not inherit
.center {
&:hover {
color: $purple;
}
// Set up base styles, we're going to scale instead of animating width/height
&::before,
&::after {
top: 0;
left: 0;
height: 100%;
width: 100%;
transform-origin: center; // Ensure scaling is done from the center (expands outwards)
}
// scale3d(<scale-horizontal>, <scale-vertical>, <scale-depth>);
&::before {
border-top: 2px solid $purple;
border-bottom: 2px solid $purple;
transform: scale3d(0,1,1); // Shrink only width
}
&::after {
border-left: 2px solid $purple;
border-right: 2px solid $purple;
transform: scale3d(1,0,1); // Shrink only height
}
&:hover::before,
&:hover::after {
transform: scale3d(1,1,1); // Show full-size
transition: transform 0.5s;
}
}
// Border spins around element
// ::before holds three borders that appear separately, one at a time
// ::after holds one border that spins around to cover ::before's borders, making their appearance seem smooth
.spin {
width: 5em;
height: 5em;
padding: 0;
&:hover {
color: $blue;
}
&::before,
&::after {
top: 0;
left: 0;
}
&::before {
border: 2px solid transparent; // We're animating border-color again
}
&:hover::before {
border-top-color: $blue; // Show borders
border-right-color: $blue;
border-bottom-color: $blue;
transition:
border-top-color 0.15s linear, // Stagger border appearances
border-right-color 0.15s linear 0.10s,
border-bottom-color 0.15s linear 0.20s;
}
&::after {
border: 0 solid transparent; // Makes border thinner at the edges? I forgot what I was doing
}
&:hover::after {
border-top: 2px solid $blue; // Shows border
border-left-width: 2px; // Solid edges, invisible borders
border-right-width: 2px; // Solid edges, invisible borders
transform: rotate(270deg); // Rotate around circle
transition:
transform 0.4s linear 0s,
border-left-width 0s linear 0.35s; // Solid edge post-rotation
}
}
.circle {
border-radius: 100%;
box-shadow: none;
&::before,
&::after {
border-radius: 100%;
}
}
.thick {
color: $red;
&:hover {
color: #fff;
font-weight: 700;
}
&::before {
border: 2.5em solid transparent;
z-index: -1;
}
&::after {
mix-blend-mode: color-dodge;
z-index: -1;
}
&:hover::before {
background: $red;
border-top-color: $red;
border-right-color: $red;
border-bottom-color: $red;
transition:
background 0s linear 0.4s,
border-top-color 0.15s linear,
border-right-color 0.15s linear 0.15s,
border-bottom-color 0.15s linear 0.25s;
}
&:hover::after {
border-top: 2.5em solid $red;
border-left-width: 2.5em;
border-right-width: 2.5em;
}
}
/* Page styling */
html {
background: $background;
}
body {
background: $background;
color: $text;
font: 300 24px/1.5 Lato, sans-serif;
margin: 1em auto;
max-width: 36em;
padding: 1em 1em 2em;
text-align: center;
}
.buttons {
isolation: isolate;
}
<form>
<div class="group">
<input type="text" required>
<span class="highlight"></span>
<span class="bar"></span>
<label>Name</label>
</div>
<div class="group">
<input type="text" required>
<span class="highlight"></span>
<span class="bar"></span>
<label>Email</label>
</div>
</form>
.group {
position:relative;
margin-bottom:45px;
}
input {
font-size:18px;
padding:10px 10px 10px 5px;
display:block;
width:300px;
border:none;
border-bottom:1px solid #757575;
}
input:focus { outline:none; }
/* LABEL ======================================= */
label {
color:#999;
font-size:18px;
font-weight:normal;
position:absolute;
pointer-events:none;
left:5px;
top:10px;
transition:0.2s ease all;
transition:0.2s ease all;
transition:0.2s ease all;
}
/* active state */
input:focus ~ label, input:valid ~ label {
top:-20px;
font-size:14px;
color:#5264AE;
}
/* BOTTOM BARS ================================= */
.bar { position:relative; display:block; width:300px; }
.bar:before, .bar:after {
content:'';
height:2px;
width:0;
bottom:1px;
position:absolute;
background:#5264AE;
transition:0.2s ease all;
transition:0.2s ease all;
transition:0.2s ease all;
}
.bar:before {
left:50%;
}
.bar:after {
right:50%;
}
/* active state */
input:focus ~ .bar:before, input:focus ~ .bar:after {
width:50%;
}
/* HIGHLIGHTER ================================== */
.highlight {
position:absolute;
height:60%;
width:100px;
top:25%;
left:0;
pointer-events:none;
opacity:0.5;
}
/* active state */
input:focus ~ .highlight {
animation:inputHighlighter 0.3s ease;
animation:inputHighlighter 0.3s ease;
animation:inputHighlighter 0.3s ease;
}
/* ANIMATIONS ================ */
@-webkit-keyframes inputHighlighter {
from { background:#5264AE; }
to { width:0; background:transparent; }
}
@-moz-keyframes inputHighlighter {
from { background:#5264AE; }
to { width:0; background:transparent; }
}
@keyframes inputHighlighter {
from { background:#5264AE; }
to { width:0; background:transparent; }
}
Другие статьи по теме:
Интересные эффекты для границ блоков контента с анимацией, которые вам могут пригодиться при оформлении страниц сайта.
Обычное поле Поиска по сайту можно оформить более оригинально, чем просто инпут с лупой. Например, благодаря анимационным эффектам на CSS3 поле для ввода поисковой фразы можно скрыть, чтобы освободить место для другого контента...
Как сделать красивую градиентную обводку блока на одном только CSS? Для этого мы сделаем следующее:
1. Создадим div.linear-gradient с градиентным фоном;
2. Создадим внутренний блок div с небольшим отступом.
Рассмотрим в этой статье, как сделать фоновые волны на сайте, используя только возможности CSS3 и SVG файл. Т.е. без применения Javascript.
Первая статья в этом году будет полностью посвящена цитатам в тексте и такому замечательному CSS тегу, как <blockquote>, а также оформлению цитат с помощью CSS стилей.
CSS 2024 демонстрирует 17 революционных обновлений, которые повышают эффективность веб-разработки благодаря расширенным возможностям компоновки, более плавной анимации и улучшенному взаимодействию с пользователем. Эти функции позволяют разработчикам создавать более динамичные, доступные и визуально привлекательные веб-сайты, чем когда-либо прежде.