I'm having trouble on how to achieve making the X stay at the middle during transform. It looks like the issue only occur in Firefox browser between Chrome and FF.
I'm using FF Quantum 58.0.2 and the X moves to the top, in Chrome I have no issues.
I tried to add top: 50%; in the pseudo element selector but during rotation the X moves few pixels to the bottom. Is there any other way to achieve this in Firefox like it does in Chrome?
.close >.x-button{
width: 0.5em;
height: 0.5em;
position: relative;
background-color: #343a40;
border-radius: 50%;
display: flex;
flex-direction: column;
justify-content: center;
margin: 0.5em 0em;
transition: all 500ms ease-out;
-moz-transition: all 500ms ease-out;
transform-origin: center center;
}
.close >.x-button::before,
.close >.x-button::after{
position: absolute;
content: '';
width: 100%;
height: 0.08em;
}
.close:hover >.x-button{
border-radius: 0;
background-color: transparent;
-ms-transform: scale(1.8) rotateZ(-360deg);
-o-transform: scale(1.8) rotateZ(-360deg);
-webkit-transform: scale(1.8) rotateZ(-360deg);
-moz-transform: scale(1.8) rotateZ(-360deg);
transform: scale(1.8) rotateZ(-360deg);
}
.close:hover >.x-button::before,
.close:hover >.x-button::after {
background-color: #FD0030;
}
.close >.x-button::before{
-ms-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-o-transform: rotate(45deg);
-webkit-transform: rotate(45deg);
transform: rotate(45deg);
}
.close >.x-button::after{
-ms-transform: rotate(-45deg);
-moz-transform: rotate(-45deg);
-o-transform: rotate(-45deg);
-webkit-transform: rotate(-45deg);
transform: rotate(-45deg);
}
<button class="close">
<span class="x-button"></span>
</button>
You could also add bottom: 0.20em on
.close >.x-button::before,
.close >.x-button::after
to fix it on all browsers.
Why .20em? .25em is half the icon's dimension and .5em is half the top and bottom margin.
Firefox:
Snippet:
.close>.x-button {
width: 0.5em;
height: 0.5em;
position: relative;
background-color: #343a40;
border-radius: 50%;
display: flex;
flex-direction: column;
justify-content: center;
margin: 0.5em 0em;
transition: all 500ms ease-out;
-moz-transition: all 500ms ease-out;
transform-origin: center center;
}
.close>.x-button::before,
.close>.x-button::after {
position: absolute;
content: '';
width: 100%;
height: 0.08em;
/* new */
bottom: .20em;
}
.close:hover>.x-button {
border-radius: 0;
background-color: transparent;
-ms-transform: scale(1.8) rotateZ(-360deg);
-o-transform: scale(1.8) rotateZ(-360deg);
-webkit-transform: scale(1.8) rotateZ(-360deg);
-moz-transform: scale(1.8) rotateZ(-360deg);
transform: scale(1.8) rotateZ(-360deg);
}
.close:hover>.x-button::before,
.close:hover>.x-button::after {
background-color: #FD0030;
}
.close>.x-button::before {
-ms-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-o-transform: rotate(45deg);
-webkit-transform: rotate(45deg);
transform: rotate(45deg);
}
.close>.x-button::after {
-ms-transform: rotate(-45deg);
-moz-transform: rotate(-45deg);
-o-transform: rotate(-45deg);
-webkit-transform: rotate(-45deg);
transform: rotate(-45deg);
}
<button class="close">
<span class="x-button"></span>
</button>
You can vertically center the before and after like you do with any position absolute elements
Give it a top: 50% and transform: translateY(-50%)
I verified this on Mac FF
.close >.x-button{
width: 0.5em;
height: 0.5em;
position: relative;
background-color: #343a40;
border-radius: 50%;
display: flex;
flex-direction: column;
justify-content: center;
margin: 0.5em 0em;
transition: all 500ms ease-out;
-moz-transition: all 500ms ease-out;
transform-origin: center center;
}
.close >.x-button::before,
.close >.x-button::after{
position: absolute;
content: '';
width: 100%;
height: 0.08em;
top: 50%;
}
.close:hover >.x-button{
border-radius: 0;
background-color: transparent;
-ms-transform: scale(1.8) rotateZ(-360deg);
-o-transform: scale(1.8) rotateZ(-360deg);
-webkit-transform: scale(1.8) rotateZ(-360deg);
-moz-transform: scale(1.8) rotateZ(-360deg);
transform: scale(1.8) rotateZ(-360deg);
}
.close:hover >.x-button::before,
.close:hover >.x-button::after {
background-color: #FD0030;
}
.close >.x-button::before{
-ms-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-o-transform: rotate(45deg);
-webkit-transform: rotate(45deg);
transform: rotate(45deg) translateY(-50%);
}
.close >.x-button::after{
-ms-transform: rotate(-45deg);
-moz-transform: rotate(-45deg);
-o-transform: rotate(-45deg);
-webkit-transform: rotate(-45deg);
transform: rotate(-45deg) translateY(-50%);
}
<button class="close">
<span class="x-button"></span>
</button>
Related
I have never done animations in CSS, what I'm trying to get is something like cog's animations two circles spinning, one to the right and the other to the left without overlapping...
I think I got the animation(sort of) but not the drawing I think..
I have this demo: https://jsfiddle.net/Tankers/8dxh94zp/9/
the "figures" are correct and the location also correct but the animation is not.
when they spin it overlaps may be is because the object are not 100% squares?, what need to be visible is just half circles just the way that is in my demo..
HTML
<div class="wrap">
<div class="top"></div>
<div class="bott"></div>
</div>
CSS
#keyframes half_spin {
0% {
-ms-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
}
40% {
-ms-transform: rotate(20deg);
-moz-transform: rotate(20deg);
-webkit-transform: rotate(20deg);
-o-transform: rotate(20deg);
transform: rotate(20deg);
}
60% {
-ms-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
}
80% {
-ms-transform: rotate(-20deg);
-moz-transform: rotate(-20deg);
-webkit-transform: rotate(-20deg);
-o-transform: rotate(-20deg);
transform: rotate(-20deg);
}
100% {
-ms-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
}
}
.wrap {
display: block;
overflow: hidden;
position: relative
}
.top {
width: 300px;
height: 150px;
border: 1px solid red;
border-bottom-left-radius: 151px;
border-bottom-right-radius: 151px;
position: relative;
animation: half_spin 5000ms ease-in-out infinite;
}
.top:before {
position: absolute;
width: 100%;
height: 1px;
background: red;
content: " ";
top: 0;
left: 0;
}
.bott {
width: 300px;
height: 150px;
border: 1px solid black;
border-top-left-radius: 151px;
border-top-right-radius: 151px;
animation: half_spin 5000ms ease-in-out infinite reverse;
position: relative;
}
.bott:before {
position: absolute;
width: 100%;
height: 1px;
background: black;
content: " ";
bottom: 0;
left :0;
}
If I understand your question correctly, this code snippet is what you're looking for. I added a transform-origin property to both the top and bottom half-circles to specify the point that we're rotating around.
Both divs should rotate around the midpoint of their flat edge, for the top that is transform-origin: 50% 0%; and for the bottom it is transform-origin: 50% 100%;
#keyframes half_spin {
0% {
-ms-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
}
40% {
-ms-transform: rotate(20deg);
-moz-transform: rotate(20deg);
-webkit-transform: rotate(20deg);
-o-transform: rotate(20deg);
transform: rotate(20deg);
}
60% {
-ms-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
}
80% {
-ms-transform: rotate(-20deg);
-moz-transform: rotate(-20deg);
-webkit-transform: rotate(-20deg);
-o-transform: rotate(-20deg);
transform: rotate(-20deg);
}
100% {
-ms-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
}
}
.wrap {
display: block;
overflow: hidden;
position: relative
}
.top {
width: 300px;
height: 150px;
border: 1px solid red;
border-bottom-left-radius: 151px;
border-bottom-right-radius: 151px;
position: relative;
animation: half_spin 5000ms ease-in-out infinite;
transform-origin: 50% 0%;
}
.top:before {
position: absolute;
width: 100%;
height: 1px;
background: red;
content: " ";
top: 0;
left: 0;
}
.bott {
width: 300px;
height: 150px;
border: 1px solid black;
border-top-left-radius: 151px;
border-top-right-radius: 151px;
animation: half_spin 5000ms ease-in-out infinite;
position: relative;
transform-origin: 50% 100%;
}
.bott:before {
position: absolute;
width: 100%;
height: 1px;
background: black;
content: " ";
bottom: 0;
left :0;
}
<div class="wrap">
<div class="top">
</div>
<div class="bott">
</div>
</div>
I created an octagon clipped style using CSS transform rotate and scale as the code snippet below.
However, when looking in Chrome 52.0.2743.116 (64-bit) on El Capitan, the image looks blurry. On the contrary, the image looks sharp in Firefox.
I have tried all kinds of solutions such as backface-visibility: hidden; transform: translateZ(0); filter: blur(0); image-rendering: -webkit-optimize-contrast;. Yet the image is still blurry.
Is there any webkit specific rules that I can use to fix this?
div.octagon {
display: inline-block;
position: relative;
overflow: hidden;
-webkit-transform: rotate(22.5deg) scale(0.9) translateY(-4px) translateZ(0);
-moz-transform: rotate(22.5deg) scale(0.9) translateY(-4px) translateZ(0);
-ms-transform: rotate(22.5deg) scale(0.9) translateY(-4px) translateZ(0);
-o-transform: rotate(22.5deg) scale(0.9) translateY(-4px) translateZ(0);
transform: rotate(22.5deg) scale(0.9) translateY(-4px) translateZ(0);
margin-top: 1em;
margin-bottom: 1em;
}
div.octagon > * {
position: relative;
overflow: hidden;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
background: transparent;
border: 4px solid;
margin: 0;
background-color: black;
}
div.octagon > *:after {
position: absolute;
/* There needs to be a negative value here to cancel
* out the width of the border. It's currently -3px,
* but if the border were 5px, then it'd be -5px.
*/
top: -4px;
right: -4px;
bottom: -4px;
left: -4px;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
content: '';
border: inherit;
}
div.octagon > * > img {
display: block;
-webkit-transform: rotate(-67.5deg) scale(1.1) translateZ(0);
-moz-transform: rotate(-67.5deg) scale(1.1) translateZ(0);
-ms-transform: rotate(-67.5deg) scale(1.1) translateZ(0);
-o-transform: rotate(-67.5deg) scale(1.1) translateZ(0);
transform: rotate(-67.5deg) scale(1.1) translateZ(0);
max-width: 100%;
height: auto;
image-rendering: -webkit-optimize-contrast;
}
.col-6 {
display: inline-block;
width: 49%;
}
.col-6 > .octagon {
width: 100%;
}
<div class="col-6">
<div class="octagon">
<p>
<img src="https://placeimg.com/300/300/people" width="500" height="500" />
</p>
</div>
</div>
<div class="col-6">
<img src="https://placeimg.com/300/300/people" width="300" height="300" />
</div>
I just tested this on my comp, and it looks better when I applied image rendering pixelated instead the -webkit-optimize-contrast.
div.octagon > * > img {
image-rendering: pixelated;
}
.arrow {
display: inline-block;
height: 8px;
width: 8px;
margin-top: 20px;
border-top: solid black 2.5px;
border-left: solid black 2.5px;
-ms-transform: rotate(-45deg);
-webkit-transform: rotate(-45deg);
transform: rotate(-45deg);
-webkit-transition: transform 1s;
-moz-transition: transform 1s;
transition: transform 1s;
cursor: pointer;
}
.arrow::before {
content: "";
display: inline-block;
width: 18px;
margin-left: -3px;
margin-bottom: 7px;
border-top: solid black 1.8px;
-ms-transform: rotate(45deg);
-webkit-transform: rotate(45deg);
transform: rotate(45deg);
}
.arrow:hover {
-ms-transform: scale(1.2);
-webkit-transform: scale(1.2);
-moz-transform: scale(1.2);
transform: scale(1.2);
}
<span class="arrow"></span>
I draw an arrow using css and try to create a hover scale up effect by using css :hover and transform:scale. However the codes rotate the arrow first and then scale it up later. I am wondering why is rotating happening and how do I fix it? Thanks in advance!
.arrow {
display: inline-block;
height: 8px;
width: 8px;
margin-top: 20px;
border-top: solid black 2.5px;
border-left: solid black 2.5px;
-ms-transform: rotate(-45deg);
-webkit-transform: rotate(-45deg);
transform: rotate(-45deg);
-webkit-transition: transform 1s;
-moz-transition: transform 1s;
transition: transform 1s;
cursor: pointer;
}
.arrow::before {
content: "";
display: inline-block;
width: 18px;
margin-left: -3px;
margin-bottom: 7px;
border-top: solid black 1.8px;
-ms-transform: rotate(45deg);
-webkit-transform: rotate(45deg);
transform: rotate(45deg);
}
.arrow:hover {
-ms-transform: rotate(-45deg) scale(1.2);
-webkit-transform: rotate(-45deg) scale(1.2);
-moz-transform: rotate(-45deg) scale(1.2);
transform: rotate(-45deg) scale(1.2);
}
<span class="arrow"></span>
the problem is that transform properties don't sum up, if you override a property and want to keep it's original value you need to repeat it.
Use this CSS for hover:
.arrow:hover {
-ms-transform: scale(1.2) rotate(-45deg);
-webkit-transform: scale(1.2) rotate(-45deg);
-moz-transform: scale(1.2) rotate(-45deg);
transform: scale(1.2) rotate(-45deg);
}
Rotate was set on the entire element and was not accounted for during the hover transform.
here is a working example
You can give transform only to :before so it won't rotate on hover.
.arrow {
display: inline-block;
height: 1px;
width: 18px;
border-top: solid black 1.8px;
-webkit-transition: transform 1s;
-moz-transition: transform 1s;
transition: transform 1s;
cursor: pointer;
}
.arrow:before {
content: "";
display: inline-block;
margin-top: -10px;
height: 8px;
width: 8px;
border-top: solid black 2.5px;
border-left: solid black 2.5px;
-ms-transform: rotate(-45deg);
-webkit-transform: rotate(-45deg);
transform: rotate(-45deg);
-webkit-transition: transform 1s;
-moz-transition: transform 1s;
transition: transform 1s;
cursor: pointer;
position: relative;
top: -9px;
}
.arrow:hover {
-ms-transform: scale(1.2);
-webkit-transform: scale(1.2);
-moz-transform: scale(1.2);
transform: scale(1.2);
}
<span class="arrow"></span>
I want to create something like this via CSS.
Just want to use only CSS to create this custom shape with border radius. Any ideas please?
You can overlap a few div tags and use the skew effect.
HTML
<div class="container">
<div class="shape shape1"></div>
<div class="shape shape2"></div>
<div class="shape shape3"></div>
</div>
CSS
.container {
position: relative;
padding: 30px;
}
.shape {
position: absolute;
text-align: center;
padding: 12px;
height: 60px;
width: 200px;
}
.shape:after {
border-radius: 5px;
content: '';
position: absolute;
height: 100%;
width: 100%;
background: green;
top: 0;
left: 0;
}
.shape1:after {
-webkit-transform: skew(-5deg, -3deg);
-moz-transform: skew(-5deg, -3deg);
-ms-transform: skew(-5deg, -3deg);
-o-transform: skew(-5deg, -3deg);
transform: skew(-5deg, -3deg);
}
.shape2:after {
-webkit-transform: skew(0deg, -1deg);
-moz-transform: skew(0deg, -1deg);
-ms-transform: skew(0deg, -1deg);
-o-transform: skew(0deg, -1deg);
transform: skew(0deg, -1deg);
top: 4px;
left: 3px;
}
.shape3:after {
-webkit-transform: skew(3deg, -2deg);
-moz-transform: skew(2deg, -2deg);
-ms-transform: skew(2deg, -2deg);
-o-transform: skew(2deg, -2deg);
transform: skew(2deg, -2deg);
top: 2px;
left: -5px;
}
.set2 {
margin-top: 80px;
}
.set2 .shape2:after {
background: red;
}
.set2 .shape3:after {
background: blue;
}
Here's a jsFiddle
You may want to look into CSS3 2D Transforms. It's possible to do similar things, but there are limitations as well. I tried to do something similar to the referenced shape :)
// CSS
#shape {
position: relative;
text-align: center;
padding: 12px;
margin-bottom: 6px;
height: 60px;
width: 200px;
margin:30px;
}
#shape:after {
border-radius: 5px;
content: '';
position: absolute;
top: 0;
right: 0;
height: 100%;
width: 100%;
background: green;
-webkit-transform: skew(-5deg, -3deg);
-moz-transform: skew(-5deg, -3deg);
-ms-transform: skew(-5deg, -3deg);
-o-transform: skew(-5deg, -3deg);
transform: skew(-5deg, -3deg);
}
// HTML
<div id="shape"></div>
Check the jsFiddle
I have a couple divs, I want to rotate them to look like diamonds, but I don't want their background images to rotate, how can i achieve this? This is my code right now
<div id="diamonds">
<div class="diamond-big diamond-tiesto"><img src="<?php echo $images_url; ?>dj-1-overlay.png" /></div>
</div>
and my CSS:
#diamonds div {
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-o-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
float:left;
}
.diamond-tiesto {background-image:url('images/dj-1.jpg'); background-size:cover; width:212px; height:212px; margin-left:160px; margin-right:120px;}
.diamond-tiesto img {margin-top:80px; margin-left:-20px;
-webkit-transform: rotate(-45deg);
-moz-transform: rotate(-45deg);
-o-transform: rotate(-45deg);
-ms-transform: rotate(-45deg);
transform: rotate(-45deg);
}
Basically I am trying to achieve this http://mqchen.github.io/jquery.diamonds.js/ without the jquery, anyone have any suggestions
Heres a fiddle just incase:
http://jsfiddle.net/7qj8h/1/
You could use the techniques described in this article and apply the transformation to a background image pseudo-element.
Demo/Code here: http://jsfiddle.net/7qj8h/4/
HTML:
<div id="diamonds">
<div class="diamond-big diamond-tiesto">
<img src="http://solarismusicfestival.com/new/wp-content/themes/default-blank/images/dj-1-overlay.png" />
</div>
</div>
CSS:
.diamond-big
{
position: relative;
overflow: hidden;
width: 200px;
height: 200px;
/* rotate diamond */
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
}
.label {
/* counter rotate label */
-webkit-transform: rotate(-45deg);
-moz-transform: rotate(-45deg);
-ms-transform: rotate(-45deg);
-o-transform: rotate(-45deg);
transform: rotate(-45deg);
/* position label */
margin-top:80px;
margin-left:-20px;
}
.diamond-big:before
{
content: "";
position: absolute;
width: 200%;
height: 200%;
top: -50%;
left: -50%;
z-index: -1;
/* counter rotate bg */
-webkit-transform: rotate(-45deg);
-moz-transform: rotate(-45deg);
-ms-transform: rotate(-45deg);
-o-transform: rotate(-45deg);
transform: rotate(-45deg);
}
/* set bg for different DJs */
.diamond-tiesto:before {
background: url(http://solarismusicfestival.com/new/wp-content/themes/default-blank/images/dj-1.jpg) 0 0 repeat;
}
Set the .diamond to rotate 45 degrees
Set the background on a .diamond-inner child div, and rotate it back -45 degrees to counter the parent's transformation.
Set overflow: hidden; on the .diamond div to clip the edges.
Adjust the positioning on the inner diamond and image.
The result: http://jsfiddle.net/7qj8h/3/
The CSS:
#diamonds > div {
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-o-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
float:left;
overflow: hidden;
}
.diamond-tiesto {
width:212px;
height:212px;
}
.diamond-tiesto .diamond-inner {
background-image: url("http://solarismusicfestival.com/new/wp-content/themes/default-blank/images/dj-1.jpg");
background-size: cover;
height: 305px;
left: 2px;
margin: 0 0 0 -49px;
position: absolute;
top: -45px;
transform: rotate(-45deg);
width: 305px;
-webkit-transform: rotate(-45deg);
-moz-transform: rotate(-45deg);
-o-transform: rotate(-45deg);
-ms-transform: rotate(-45deg);
transform: rotate(-45deg);
}
.diamond-tiesto img {
margin-left: 22px;
margin-top: 123px;
}