Hôm nay mình sẽ hướng dẫn các bạn cách thức tạo một nút loading hay progress button với hiệu ứng độc đáo và sáng tạo bằng CSS3 và HTML5. Với phong cách thiết kế phẳng (flat style) và 3D, những thiết kế bên dưới sẽ góp phần đem lại sự sáng tạo, hiện đại và không kém phần hấp dẫn trong thiết kế tổng quát của bạn.
Lưu ý: Chúng ta sẽ sử dụng mã transitions dựa trên pseudo-elements, mã này hiện vẫn chưa được hỗ trợ đầy đủ bởi tất cả các trình duyệt (ví dụ như Safari và Mobile Safari). Ngoài ra cũng cần chú ý thêm rằng ở đây chúng ta sử dụng mã transform-style: preserve-3d mà hiện tại thì chưa được hỗ trợ đầy đủ trên trình duyệt IE10 và IE11.
<button class="progress-button" data-horizontal="" data-perspective="" data-style="rotate-angle-bottom">Submit</button>
Và chuyển đổi thành cấu trúc như bên dưới: <button class="progress-button" data-style="rotate-angle-bottom" data-perspective data-horizontal>
<span class="progress-wrap">
<span class="content">Submit</span>
<span class="progress">
<span class="progress-inner"></span>
</span>
</span>
</button>
Nếu như bạn không thích sử dụng thuộc tính data-perspective thì có thể sử dụng mã bên dưới: <button class="progress-button" data-style="fill" data-horizontal>
<span class="content">Submit</span>
<span class="progress">
<span class="progress-inner"></span>
</span>
</button>
Nếu các bạn mong muốn tạo ra hiệu ứng theo chiều thẳng đứng (vertical) hoặc chiều ngang (horizontal) thì phải khai báo theo 2 kiểu khác nhau trong mã CSS. Đoạn mã CSS bên dưới dùng chung cho tất các nút để tạo hiệu ứng, với hiệu ứng tùy chỉnh từng nút thì ta chỉnh mã CSS khác nhau như đã nói ở trên. *, *:after, *::before { box-sizing: border-box; }
@font-face {
font-weight: normal;
font-style: normal;
font-family: 'icomoon';
src:url('../fonts/icomoon/icomoon.eot');
src:url('../fonts/icomoon/icomoon.eot?#iefix') format('embedded-opentype'),
url('../fonts/icomoon/icomoon.ttf') format('truetype'),
url('../fonts/icomoon/icomoon.woff') format('woff'),
url('../fonts/icomoon/icomoon.svg#icomoon') format('svg');
}
.progress-button {
position: relative;
display: inline-block;
padding: 0 60px;
outline: none;
border: none;
background: #1d9650;
color: #fff;
text-transform: uppercase;
letter-spacing: 1px;
font-size: 1em;
line-height: 4;
}
.progress-button[disabled],
.progress-button[disabled].state-loading {
cursor: default;
}
.progress-button .content {
position: relative;
display: block;
}
.progress-button .content::before,
.progress-button .content::after {
position: absolute;
right: 20px;
color: #0e7138;
font-family: "icomoon";
opacity: 0;
transition: opacity 0.3s 0.3s;
}
.progress-button .content::before {
content: "\e600"; /* Checkmark for success */
}
.progress-button .content::after {
content: "\e601"; /* Cross for error */
}
.progress-button.state-success .content::before,
.progress-button.state-error .content::after {
opacity: 1;
}
.notransition {
transition: none !important;
}
.progress-button .progress {
background: #148544;
}
.progress-button .progress-inner {
position: absolute;
left: 0;
background: #0e7138;
}
.progress-button[data-horizontal] .progress-inner {
top: 0;
width: 0;
height: 100%;
transition: width 0.3s, opacity 0.3s;
}
.progress-button[data-vertical] .progress-inner {
bottom: 0;
width: 100%;
height: 0;
transition: height 0.3s, opacity 0.3s;
}
/* Necessary styles for buttons with 3D transforms */
.progress-button[data-perspective] {
position: relative;
display: inline-block;
padding: 0;
background: transparent;
perspective: 900px;
}
.progress-button[data-perspective] .content {
padding: 0 60px;
background: #1d9650;
}
.progress-button[data-perspective] .progress-wrap {
display: block;
transition: transform 0.2s;
transform-style: preserve-3d;
}
.progress-button[data-perspective] .content,
.progress-button[data-perspective] .progress {
outline: 1px solid rgba(0,0,0,0); /* Smoothen jagged edges in FF */
}
Chúng ta sẽ sử dụng mã pseudo-elements ::before và ::after để hiển thị biểu tượng thông báo thành công hoặc thất bại sau khi quá trình loading hoàn tất.Lưu ý với những nút sử dụng hiệu ứng 3D, chúng ta sẽ sử dụng button như là 1 lớp “vỏ” bao bọc lấy các thành phần tạo hiệu ứng bên trong. Quá trình transform sẽ diễn ra với thuộc tính background color, padding, và hầu hết các thuộc tính liên quan sẽ được mình bọc trong 1 thẻ span với class progress-wrap.
Ví dụ cụ thể với hiệu ứng 3D cho một button:
/* Rotate bottom 3d */
/* ====================== */
.progress-button[data-style="rotate-angle-bottom"] .progress {
position: absolute;
top: 100%;
left: 0;
width: 100%;
height: 20px;
box-shadow: 0 -1px 0 #148544; /* fix the blurriness that causes a gap */
transform: rotateX(-90deg);
transform-origin: 50% 0%;
}
.progress-button[data-style="rotate-angle-bottom"].state-loading .progress-wrap {
transform: rotateX(45deg);
}
Nút loading của chúng ta sẽ có 3 trạng thái hoạt động: state-loading, state-success và state-error.Với những trình duyệt chưa hỗ trợ đầy đủ các hiệu ứng thì mặc định sẽ được trả về hiệu ứng đầu tiên trong phần demo (fill horizontal).
Phần mã chi tiết từng hiệu ứng các bạn vui lòng xem trong phần code Demo nhé !
Icons được sử dụng là IcoMoon được thiết kế bởi IcoMoon app.
Hy vọng bài viết này thực sự hữu ích và truyền thêm cảm hứng thiết kế cho các bạn.
Demo
Nguồn bài viết: Codrops