I've been trying to create a simple css spinner which is shown while my page is loading by using a pseudo element overlaying a div where content will be shown.
It uses border-radius and transform: rotate() to achieve this effect but as you can see it wobbles strangely while rotating. The effect is more or less obvious depending on the screen size, zoom level and browser. I find it's most visible in MS Edge.
Example fiddle
.loading {
width: 75vh;
height: 100vh;
margin: auto;
background: white;
position: relative;
}
.loading::after {
border: 6vmin solid lightblue;
border-top: 6vmin solid darkblue;
position: absolute;
margin-top: 5vmin;
margin-left: 5vmin;
width: 15vmin;
height: 15vmin;
content: "";
border-radius: 50%;
animation: spin .5s linear infinite;
}
#keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
<div class="loading"></div>
There's some weird cut going on with the border-radius
Change it to border-radius: 1000px and see what happens
Changing the width and height to a pixel value seems to fix the issue. It may not be the best solution, but hey, it works.
To make this appropriate for all screen sizes, you need to use #media. In the bottom of the css I have added one that changes the size if the screen size is smaller than 700px just to show you how to do it, and if you want to change the numbers around or something, you at least know how #media can be used :)
Here is the code for changing the size depending on the screen-size of the users device.
#media (max-width: 700px){
.loading::after {
width: 100px;
height: 100px;
}
}
If you want to make it different on large screens too, just swap out "max-width: 700px" with "min-width: 1500px" or a value of your choice :)
http://jsfiddle.net/hfsqebsn/5/
Again, there are probably better ways, but this works :)
Edit: I think I may have changed around some other stuff in the fiddle I linked for testing purposes, so just beware of that :P
This issue was driving me crazy all day. I was able to solve it personally by making the ring thicker than desired and then masking over its inner and outer portions to hide the wobble from the viewer.
Solution.
https://codepen.io/corbinmosher/pen/GRWmYjy
Solution with background coloring to help with understanding it.
https://codepen.io/corbinmosher/pen/bGqWmEj
<div class="spinner__container">
<div class="spinner__ring"></div>
<div class="spinner__outline"></div>
</div>
.spinner__container {
position: relative;
width: 58px;
height: 58px;
background-color: white;
}
.spinner__ring {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: calc(100% - 8px);
height: calc(100% - 8px);
border-radius: 50%;
}
.spinner__ring:before {
position: absolute;
top: -1px;
left: -1px;
width: calc(100% + 2px);
height: calc(100% + 2px);
border: 10px solid lightblue;
border-top: 10px solid blue;
box-sizing: border-box;
content: '';
border-radius: 50%;
animation: rotate-spinner 1s linear infinite;
}
.spinner__ring:after {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: calc(100% - 8px);
height: calc(100% - 8px);
box-sizing: border-box;
content: '';
border-radius: 50%;
background-color: white;
}
.spinner__outline {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: calc(100% - 8px);
height: calc(100% - 8px);
border-radius: 50%;
border: solid 2px white;
}
#keyframes rotate-spinner {
0% {
transform: rotate(405deg);
}
100% {
transform: rotate(765deg);
}
}
#-webkit-keyframes rotate-spinner {
0% {
transform: rotate(405deg);
}
100% {
transform: rotate(765deg);
}
}
Related
here is the shape i want to do enter link description here
P.S.I am still learning the front-end stuff so could you pls help me with this assignment.
Here is the HTML code <div>Elzero</div>
here is the CSS code i tried to do with
* {
box-sizing: border-box;
}
div {
width: 200px;
height: 200px;
background-color: #eee;
margin: 80px auto;
color: black;
font-size: 50px;
font-weight: bold;
text-align: center;
line-height: 200px;
border-radius: 50%;
}
::after {
content: "";
width: 200px;
height: 200px;
background-color: #03a9f4;
margin: 80px auto;
border-radius: 50%;
position: absolute;
transform: translate(-190px, -80px);
z-index: -1;
}
::before {
content: "";
width: 200px;
height: 200px;
background-color: #e91e63;
margin: 80px auto;
border-radius: 50%;
position: absolute;
top: 0px;
z-index: -2;
}
div:hover {
transition: all 0.5s;
transform: rotate(180deg);
}
As you are constrained to use just one div, this snippet builds on your idea of having the pseudo elements but creating them with conic-gradient backgrounds and the 'main' div having the light gray circular background created using a radial gradient. That way it creates these 3 shapes.
and overlays them to give the impression of 3/4 circles. It then uses CSS animation to rotate them on hover.
Obviously you will want to play with the dimensions, the animations timings and directions to get exactly what you want but this should give a start.
* {
box-sizing: border-box;
}
div {
width: 200px;
height: 200px;
background-image: radial-gradient(#eee 0 55%, transparent 55% 100%);
margin: 80px auto;
color: black;
font-size: 50px;
font-weight: bold;
text-align: center;
line-height: 200px;
border-radius: 50%;
position: relative;
}
div::after {
content: "";
width: 200px;
height: 200px;
border-radius: 50%;
position: absolute;
top: 0;
left: 0;
z-index: -2;
background-image: conic-gradient(#03a9f4 0deg 45deg, white 45deg 135deg, #03a9f4 135deg 360deg);
}
div::before {
content: "";
width: calc(100% - 10%);
height: calc(100% - 10%);
position: absolute;
border-radius: 50%;
position: absolute;
top: 5%;
left: 5%;
z-index: -1;
background-image: conic-gradient(#e91e63 0, #e91e63 225deg, white 225deg, white 315deg, #e91e63 315deg, #e91e63 360deg);
}
div:hover::after {
animation: rot .4s linear;
}
div:hover::before {
animation: rot .4s linear;
animation-delay: .1s;
animation-direction: reverse;
}
#keyframes rot {
0% {
transform: rotate(0);
}
25% {
transform: rotate(180deg);
}
50% {
transform: rotate(180deg);
}
75% {
transform: rotate(0);
}
100% {}
}
<div>Elzero
</div>
also here is example in less:
https://codepen.io/nikitahl/pen/XooBXd
if you want to use css here is a converter:
https://jsonformatter.org/less-to-css
I am working a project on my favorite science stories animated using HTML. While I was working on it By just changing the position to fixed or nothing position of all my objects was changing. If you remove the position property from #Guy, you will notice that the image of Galileo will shift drastically. I just want to know why this happens.
:root {
--initX: 280px;
--initY: 70px;
--finalY: 600px;
}
body {
background-color: aqua;
padding: 0px;
margin: 0px;
}
#Guy {
z-index: 4;
height: 200px;
position: fixed;
width: auto;
transform: translate(800px, 450px);
}
#Galilo {
height: 50px;
width: auto;
z-index: -1;
transform: translate(290px, 5px) rotateZ(4deg);
}
#tower {
height: 650px;
width: 150px;
z-index: 0;
transform: translate(250px, 50px) rotateZ(4deg);
position: absolute;
background-color: grey;
}
#Lball {
height: 40px;
width: 40px;
z-index: 2;
border-radius: 50%;
transform: translate(var( --initX), var(--initY));
background-color: blue;
position: absolute;
animation: lite 2s linear 1s infinite forwards;
}
#Hball {
height: 50px;
width: 50px;
z-index: 3;
transform: translate(calc(var( --initX) + 75px), var(--initY));
border-radius: 50%;
background-color: red;
position: absolute;
animation: heavy 2s linear 1s infinite forwards;
}
#floor {
height: 25%;
width: 100%;
background-color: green;
position: absolute;
z-index: -1;
transform: translate(0px, 565px);
}
#hide {
height: 12%;
width: 100%;
background-color: green;
position: absolute;
z-index: 1;
transform: translate(0px, 650px);
}
#keyframes lite {
0% {
transform: translate(var( --initX), var(--initY))
}
90% {
transform: translate(var(--initX), calc(var(--finalY) + 12.5px))
}
100% {
transform: translate(var(--initX), calc(var(--finalY) + 12.5px))
}
}
#keyframes heavy {
0% {
transform: translate(calc(var( --initX) + 75px), var(--initY))
}
90% {
transform: translate(calc(var( --initX) + 75px), var(--finalY))
}
100% {
transform: translate(calc(var( --initX) + 75px), var(--finalY))
}
}
<div id="tower"></div>
<div id="Hball"></div>
<div id="Lball"></div>
<div id="floor"></div>
<div id="hide"></div>
<img src="stick fidure.png" alt="Dude thinking" id="Guy">
<img src="galileo-galilei.png" alt="gallilo" id="Galilo">
P.S.
The link for the image of Galileo is https://cdn.images.express.co.uk/img/dynamic/109/590x/galileo-galilei-819977.jpg and the stick figure was made in Paint 3D
position: fixed takes the element out of the document flow and places it in relation to the viewport/window. Usually that also causes this element to overlap other elements. The other elements however will be rearranged in a way like the fixed element wouldn't be there (it's not in the document flow). So adding/removing position: fixed to/from an element will have all these effects on the overall document.
Is there any way to animate transform: translate, height and width at same time in Safari? I have a bug. After transition is finished, element will jump a few pixels away. Here is fiddle.
div {
background-color: green;
height: 100px;
left: 200px;
position: absolute;
top: 200px;
transition: transform 1s, height 1s, width 1s;
width: 100px;
}
div:hover {
height: 150px;
width: 150px;
transform: translate(-50%, -50%);
}
<div></div>
The jump happens because your height- and width values are pixel-based, and your transform is percentages, which results in sub-pixels. Try changing your approach by animating scale instead (it's always a good idea to try to keep your animations restricted to transforms and opacity anyway. See this article for reference). Use transform-origin to define the origin point of the transformation.
div {
background-color: green;
height: 100px;
left: 200px;
position: absolute;
top: 200px;
transition: transform 1s;
width: 100px;
transform-origin: right bottom;
}
div:hover {
transform: scale(1.5);
}
<div></div>
I think the problem is caused by the absolute positioning of your element to the body. After the transition is done, the browser recalculate the absolute position to the parent element and translate is coming in the way. The solution might be easier than you think.
Create an outer container which "safes" the place for the inner container to grow in left/top direction. I think the example below will explain the rest. (tested in safari aswell!)
body {
/* just for better looks */
margin: 2rem;
}
/* out container zone */
.outer {
border: 1px solid #222;
width: 150px;
height: 150px;
position: relative;
}
/* inner element aligned to the right */
.inner {
background-color: green;
width: 100px;
height: 100px;
transition: all .5s;
position: absolute;
right: 0;
bottom: 0;
}
/* no translate, no problems */
.inner:hover {
width: 150px;
height: 150px;
}
<div class="outer">
<div class="inner">
</div>
</div>
Try this. I changed the definition of the transition.
div {
background-color: green;
height: 100px;
left: 200px;
position: absolute;
top: 200px;
transition: all 1s;
width: 100px;
}
div:hover {
height: 150px;
width: 150px;
transform: translate(-50%, -50%);
}
<div></div>
It's working on Safari
You need to use -webkit- with transition and transform
div {
background-color: green;
height: 100px;
left: 200px;
position: absolute;
top: 200px;
-webkit-transition: all 1s;
width: 100px;
}
div:hover {
height: 150px;
width: 150px;
height: 150px;
width: 150px;
-webkit-transform: translate(-50%, -50%);
}
<div></div>
Perspective animation
I was playing around with the css perspective() animation. However, when testing it in Chrome and Opera, I came across some weird behavior.
Chrome and Opera are acting very weird when repeatedly hovering fast over the animation. The animation gets triggered on :hover. Perhaps this is causing the behavior? How can i stop Chrome and Opera having this behavior.
Fiddle
I reproduced the problem within a fiddle. Just do like the red dot is showing.
body {
text-align: center;
}
.container {
position: relative;
height: 200px;
width: 200px;
margin: 0 auto;
border: 2px solid red;
}
.perspective {
background: blue;
height: 200px;
width: 200px;
transition: transform .33s;
}
.perspective:hover {
transform: perspective( 800px ) rotateY(15deg);
}
.perspective p {
margin: 0;
color: #fff;
text-align: center;
line-height: 200px;
}
.mouse-helper {
position: absolute;
height: 90px;
width: 15px;
left: 50%;
-webkit-transform: translate(-50%, -50%);
-moz-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
-o-transform: translate(-50%, -50%);
}
.mouse-helper .animated {
background: red;
position: absolute;
bottom: 0px;
height: 15px;
width: 15px;
border-radius: 50%;
animation: up-down .29s infinite;
}
#keyframes up-down {
0% {bottom: 0;top: calc(100% - 15px);}
50% {top: 0;bottom: calc(100% - 15px);}
100% { bottom: 0;top: calc(100% - 15px); }
}
<h2>Move with you mouse over the box like the red DOT does.</h2>
<p>You will see that the `perspective` animation will act very wierd on Chrome and Opera. On firefox and IE it works fine.</p>
<p>NOTE: Don't do it over the red dot itself, do it near the dot or any other size of the shape.</p>
<div class="container">
<div style="overflow: hidden;">
<div class="perspective">
<p>TEXT</p>
</div>
</div>
<div class="mouse-helper">
<div class="animated"></div>
</div>
</div>
My guess, but it's only a guess, is that this is related to the response in this issue thread, where some transforms are hardware accelerated and some are not, and that can cause things to get out of sync briefly.
If you explicitly add transform: perspective(0px) rotateY(0deg); to your (non-hovered) .perspective, it doesn't happen:
body {
text-align: center;
}
.container {
position: relative;
height: 200px;
width: 200px;
margin: 0 auto;
border: 2px solid red;
}
.perspective {
background: blue;
height: 200px;
width: 200px;
transition: transform .33s;
transform: perspective(0px) rotateY(0deg);
}
.perspective:hover {
transform: perspective( 800px ) rotateY(15deg);
}
.perspective p {
margin: 0;
color: #fff;
text-align: center;
line-height: 200px;
}
.mouse-helper {
position: absolute;
height: 90px;
width: 15px;
left: 50%;
-webkit-transform: translate(-50%, -50%);
-moz-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
-o-transform: translate(-50%, -50%);
}
.mouse-helper .animated {
background: red;
position: absolute;
bottom: 0px;
height: 15px;
width: 15px;
border-radius: 50%;
animation: up-down .29s infinite;
}
#keyframes up-down {
0% {bottom: 0;top: calc(100% - 15px);}
50% {top: 0;bottom: calc(100% - 15px);}
100% { bottom: 0;top: calc(100% - 15px); }
}
<h2>Move with you mouse over the box like the red DOT does.</h2>
<p>You will see that the `perspective` animation will act very wierd on Chrome and Opera. On firefox and IE it works fine.</p>
<p>NOTE: Don't do it over the red dot itself, do it near the dot or any other size of the shape.</p>
<div class="container">
<div style="overflow: hidden;">
<div class="perspective">
<p>TEXT</p>
</div>
</div>
<div class="mouse-helper">
<div class="animated"></div>
</div>
</div>
So there's your fix; as to the "why?", once again a guess: The Chromium issue linked above has this from a Chromium dev:
Alternatively we may be able to pull transform animations back to the main thread in this case.
We already do this (at least in M33) for animations where keyframes reference both accelerated and non-accelerated properties:
Maybe the same is now true for transitions (the issue is from 2014), but because the non-hover state does not have any transforms, this logic won't be triggered in your case.
I'm trying to achieve this shape in css, tried in several different ways, checked online for examples but looks like this shape is kind of tricky to accomplish.
Anyone that could have an idea of how to do this? Not sure if it's even possible with css only technique.
Thank you!
Yes, it is possible and it's very simple.
demo
Result:
:
I'm using just one element and a pseudo for the bottom left corner so the HTML is simply:
<div class='shape'></div>
Relevant CSS:
.shape {
overflow: hidden; /* to hide the top right corner
of the parallelogram formed by the pseudo */
position: relative;
width: 20em; height: 10em; /* any values really */
}
.shape:before {
position: absolute;
bottom: 0; left: 0;
width: 150%; height: 150%;
transform-origin: 0 100%;
transform: rotate(-3deg) skewX(-10deg);
background: black;
content: '';
}
You can get a lot of shapes using CSS transforms. And they are real shapes, you can have any kind of background behind.
I think it is perfect solution to your question...
#trapezoid {
height: 0;
width: 120px;
border-bottom: 80px solid #05ed08;
border-left: 45px solid transparent;
border-right: 5px solid transparent;
padding: 10 8px 5 5;
}
You could also use :before, :after pseudo and transform property. Here's an example.
#box {
width: 400px;
height: 200px;
background-color: #212121;
position: relative;
}
#box:after, #box:before {
display: block;
content: "\0020";
color: transparent;
width: 411px;
height: 45px;
background: white;
position: absolute;
bottom: -20px;
-moz-transform: rotate(-2deg);
-webkit-transform: rotate(-2deg);
-o-transform: rotate(-2deg);
-ms-transform: rotate(-2deg);
transform: rotate(-2deg);
}
#box:before {
bottom: 80px;
left: -200px;
-moz-transform: rotate(92deg);
-webkit-transform: rotate(92deg);
-o-transform: rotate(92deg);
-ms-transform: rotate(92deg);
transform: rotate(92deg);
}
You may have to change some values to get the shape you want.