See this video
(HD video here)
I was wondering whether there is an easier way to implement this in Javascript/CSS.
I know that there is some CSS3 attributes like transition
, animation
, transform
and so on, but as I know, none of these attributes can transform one icon into another and provide delicate effect like the top-left and top-right ones in the video above.
Does anyone have ideas about what may be a good solution to implement this?
See this video
(HD video here)
I was wondering whether there is an easier way to implement this in Javascript/CSS.
I know that there is some CSS3 attributes like transition
, animation
, transform
and so on, but as I know, none of these attributes can transform one icon into another and provide delicate effect like the top-left and top-right ones in the video above.
Does anyone have ideas about what may be a good solution to implement this?
Share Improve this question edited Jun 4, 2015 at 10:19 Ruddy 9,9235 gold badges48 silver badges68 bronze badges asked Jun 4, 2015 at 8:05 Hanfei SunHanfei Sun 47.1k41 gold badges132 silver badges251 bronze badges 4- The answer to your question is YES, all of that is possible. SVG maybe better for the top right. – Ruddy Commented Jun 4, 2015 at 8:13
- Of course it is possible. JavaScript is turing plete which means it can output anything other programs output. – Derek 朕會功夫 Commented Jun 4, 2015 at 8:15
- @odedta If any demo or library could be provided, it will be much more helpful.. – Hanfei Sun Commented Jun 4, 2015 at 8:24
- @hanfeisun, You can see an example at the answer below, here: jsfiddle/apaul34208/5Bz8g/63. There's animate.css: daneden.github.io/animate.css - basically there are a lot of libraries that contain partials of what you're looking for, I don't know of a jQuery plugin that creates a whole solution for this, just look a specific thing on google. – odedta Commented Jun 4, 2015 at 8:28
3 Answers
Reset to default 13Right, I have e up with a similar look to show that this sort of thing is possible via CSS only. You will notice some differences, some of which maybe the way I coded this but you get the point.
So here it is!
Note: Stackoverflow's code snippets don't like some CSS
properties and will not run them. This will be best viewed on Codepen here.
@import url(http://fonts.googleapis./css?family=Lato:100,300,400,700);
body {
font-family: 'Lato', sans-serif;
background: #222;
}
.grid {
width: 600px;
height: 600px;
border: 1px solid;
margin: 0 auto;
}
.box {
width: 50%;
height: 50%;
float: left;
position: relative;
}
.box:nth-child(1) {
background: #01FF70;
}
.box:nth-child(2) {
background: #FFDC00;
}
.box:nth-child(3) {
background: #0074D9;
}
.box:nth-child(4) {
background: #FF4136;
line-height: 300px;
}
/* Ham Burger */
.hamBurger {
width: 110px;
height: 16px;
background: #fff;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
animation: spin 5s infinite;
}
.hamBurger:before,
.hamBurger:after {
content: "";
width: 110px;
height: 16px;
background: #fff;
position: absolute;
left: 0;
}
.hamBurger:before {
top: -42px;
animation: translateBefore 5s infinite;
}
.hamBurger:after {
bottom: -42px;
animation: translateAfter 5s infinite;
}
@keyframes translateBefore {
20% {
transform: rotate(45deg);
width: 60px;
left: 52px;
top: -24px;
}
40% {
transform: rotate(45deg);
width: 60px;
left: 52px;
top: -24px;
}
60% {
transform: rotate(0deg);
width: 110px;
left: 0;
top: -42px;
}
}
@keyframes translateAfter {
20% {
transform: rotate(-45deg);
width: 60px;
left: 52px;
bottom: -24px;
}
40% {
transform: rotate(-45deg);
width: 60px;
left: 52px;
bottom: -24px;
}
60% {
transform: rotate(0deg);
width: 110px;
left: 0;
bottom: -42px;
}
}
@keyframes spin {
20% {
transform: rotate(180deg);
}
40% {
transform: rotate(180deg);
}
60% {
transform: rotate(360deg);
}
100% {
transform: rotate(360deg);
}
}
/* End of Ham Burger */
/* Refresh */
.refresh {
width: 100px;
height: 100px;
border: 16px solid transparent;
border-top-color: #fff;
border-left-color: #fff;
border-radius: 50%;
position: relative;
transform: rotate(-45deg);
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
animation: refreshSpin 1s infinite linear;
}
.refresh:before {
content: "";
width: 0;
height: 0;
border-left: 30px solid #fff;
border-top: 30px solid transparent;
border-bottom: 30px solid transparent;
position: absolute;
top: -16px;
left: 80%;
transform: rotate(45deg);
}
@keyframes refreshSpin {
100% {
transform: rotate(315deg);
}
}
/* End of Refresh */
/* Numbers */
.plus,
.num1,
.num2 {
display: inline-block;
font-size: 100px;
color: #fff;
}
.plus {
animation: plusSpin 5s infinite;
margin-left: 30%;
}
.num1 {
position: relative;
animation: num1Effect 5s infinite;
padding-left: 20px;
}
.num2 {
position: absolute;
top: 0;
background: #FF4136;
clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
animation: num2Effect 5s infinite;
}
@keyframes num2Effect {
30% {
clip-path: polygon(100% 100%, 100% 0%, 100% 100%, 0% 100%);
}
70% {
clip-path: polygon(100% 100%, 100% 0%, 100% 100%, 0% 100%);
}
}
@keyframes num1Effect {
30% {
padding-left: 0px;
}
70% {
padding-left: 0px;
}
}
@keyframes plusSpin {
20% {
transform: rotate(90deg);
}
70% {
transform: rotate(90deg);
}
90% {
transform: rotate(0deg);
}
}
/* End of Numbers */
/* Icons */
.icons {
width: 120px;
height: 120px;
background: #fff;
position: absolute;
top: 27%;
left: 27%;
animation: spinIcon 5s infinite;
}
.icons:after {
content: "";
display: block;
height: 100%;
width: 0px;
background: #FFDC00;
margin: 0 auto;
animation: spinIconMiddle 5s infinite;
}
@keyframes spinIconMiddle {
33% {
width: 0;
}
66% {
width: 30px;
}
100% {
width: 0px;
}
}
@keyframes spinIcon {
33% {
transform: rotate(90deg);
}
66% {
transform: rotate(180deg);
}
100% {
transform: rotate(270deg);
}
}
/* End of Icons */
<script src="https://cdnjs.cloudflare./ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class="grid">
<div class="box">
<div class="hamBurger"></div>
</div>
<div class="box">
<div class="icons"></div>
</div>
<div class="box">
<div class="refresh"></div>
</div>
<div class="box">
<div class="plus">+</div>
<div class="num1">
<div class="num2">2</div>1
</div>
</div>
</div>
If there are any questions please asked.
Further notes:
- I couldn't think of a good way to create the triangle in the top right without using SVG. So I left that part out.
- This is using
clip-path
, this is not very well support as of yet. see more here. - The script added is to make this prefix free.
- Created in Chrome, therefore it is best viewed in Chrome. This is nowhere near perfect, it is just to prove this can be done.
Your designs are all fully possible with css. All of which will require slightly different approaches (as you can see in my demo), but all are fully possible.
For example,
- the top left part can be made with two pseudo elements, and rotated and borders altered on hover.
- the top right can be created with a border-hack, altering the borders and width on hover
- the bottom left can be created as shown here
- the bottom right can be created using multiple pseudo elements and a change in
data-attr
. (if, for example, you then wanted +3, you would have to alter thedata-start
attr through javascript)
img {
height: 200px;
width: 200px;
}
div {
height: 200px;
width: 200px;
position: relative;
display: inline-block;
}
.one {
background: lightgreen;
}
*:before,
*:after,
a {
content: "";
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
transition: all 0.6s;
}
.one:before {
height: 40px;
width: 60px;
border: 10px solid white;
border-left: 0px solid white;
border-right: 0px solid white;
}
.one:after {
height: 10px;
width: 60px;
background: white;
}
.one:hover:before {
transform: translate(-50%, -50%) rotate(135deg);
border-bottom: 10px solid white;
border-right: 10px solid white;
border-top: 0px solid white;
width: 40px;
}
.one:hover:after {
transform: translate(-50%, -50%) rotate(180deg);
}
.two {
background: orange;
}
.three {
background: steelblue;
}
.four {
background: tomato;
}
.two:before {
width: 0;
border-left: 50px solid white;
border-top: 30px solid transparent;
border-bottom: 30px solid transparent;
}
.two:hover:before {
border: 0px solid transparent;
width: 50px;
height: 50px;
background: white;
}
.four:before {
content: attr(data-start);
color: white;
font-size: 30px;
opacity: 1;
}
.four:after {
content: attr(data-end);
color: white;
font-size: 30px;
opacity: 0;
}
.four:hover:before {
opacity: 0;
}
.four:hover:after {
opacity: 1;
}
<div class="one"></div>
<div class="two"></div><br/>
<div class="three"><a href="https://stackoverflow./a/30049464/3436942">See here</a>
</div>
<div class="four" data-start="+1" data-end="+2"></div>
You can always try some css filters bined with some transitions No need for javascript. But you could use javascript to attach and remove classes so you can have different animations in different situations.
.showbox {
float: left;
margin: 4em 1em;
width: 100px;
height: 60px;
border: 2px solid green;
background-color: #fff;
line-height: 60px;
text-align: center;
-webkit-transition: 1s ease-in-out;
-moz-transition: 1s ease-in-out;
-o-transition: 1s ease-in-out;
transition: 1s ease-in-out;
}
.showbox.slideright:hover {
-webkit-transform: translate(3em,0) rotate(360deg);
-moz-transform: translate(3em,0) rotate(360deg);
-o-transform: translate(3em,0) rotate(360deg);
-ms-transform: translate(3em,0) rotate(360deg);
transform: translate(3em,0) rotate(360deg);
}
<div class="showbox slideright">box 1</div>