Using spinner font with rotation - css

I'm using a spinner icon from a font set and rotating it. I must set the transform-origin to define the centre of rotation of the icon to avoid wobbling (as suggested here). However, if I change the font size, the wobbling effect comes again. The same happens if I change the browser resolution.
HTML:
<div>
<p>First icon</p>
<i id="first" class="fa fa-spinner rotation-animation"></i>
</div>
<div>
<p>Second icon</p>
<span id="second" class="fa fa-spinner rotation-animation"></span>
</div>
<div>
<p>Third icon</p>
<span id="third" class="fa fa-spinner rotation-animation"></span>
</div>
<div>
<p>Fourth icon</p>
<span id="fourth" class="fa fa-spinner rotation-animation"></span>
</div>
CSS:
.rotation-animation {
animation: div-rotate 0.7s infinite steps(8);
transform: translateZ(0);
-webkit-transform: translateZ(0);
transform-origin: 50% 51%;
-webkit-transform-origin: 50% 51%;
}
#keyframes div-rotate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
#-webkit-keyframes div-rotate {
0% {
-webkit-transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
}
}
#first {
font-size: 20px;
}
#second {
font-size: 30px;
}
#third {
font-size: 40px;
}
#fourth {
font-size: 50px;
}
https://jsfiddle.net/r944z1a6/
As you can see in the above link, the second icon is the only one which does not wobble. If you change the browser resolution, the second one will wobble too.
Why is it happening? The x and y percent offsets to the centre of rotation shouldn't change when changing the font size. Isn't it?
Is there any way to fix this and make the spinner not to wobble for any size/resolution?
Note: I've used font awesome for the example, but I'm actually using a custom font, which has the same effect.
EDIT:
Regardless of #vals answer, the only way that I've found which doesn't seem to wobble is using linear rotation:
animation: div-rotate 0.7s infinite linear;
It's not so cool, but works.

There is nothing wrong with the font-awesome icon, and spinning it.
Try setting it to 200px and you will see that it spins perfectly.
The wobbling that you see, and that you are trying to correct, arises from rounding px from the browser at small font sizes.
It's impossible to predict what will be the size rounding for any font size and browser zoom.
So, the only way to get a perfect solution is to make your effect at a larger scale, and then scale it
.rotation-animation {
animation: div-rotate 0.7s infinite steps(8);
transform: translateZ(0);
transform-origin: 50% 50%;
}
#keyframes div-rotate {
0% { transform: rotate( 0deg) scale(0.1);}
100% { transform: rotate(360deg) scale(0.1);}
}
#first {
font-size: 200px;
margin: -90px;
}
#second {
font-size: 300px;
margin: -140px;
}
#third {
font-size: 400px;
margin: -180px;
}
#fourth {
font-size: 500px;
margin: -230px;
}
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<div>
<p>First icon</p>
<i id="first" class="fa fa-spinner rotation-animation"></i>
</div>
<div>
<p>Second icon</p>
<span id="second" class="fa fa-spinner rotation-animation"></span>
</div>
<div>
<p>Third icon</p>
<span id="third" class="fa fa-spinner rotation-animation"></span>
</div>
<div>
<p>Fourth icon</p>
<span id="fourth" class="fa fa-spinner rotation-animation"></span>
</div>

Related

How to make this "scroll tape bar" with CSS

I would like to ask if you can show me how to make the "scroll tape bar" (I don't know the correct term for this object) that is in this store: https://thefutureofficial.eu/
"scroll tape bar here"
Thanks a lot guys.
Simone.
Use following Snippet to achieve this effect. You can style the text as per your choice.
.main {
background:#000;
padding:0.5rem;
overflow: hidden;
}
.text {
color:white;
animation : slide 10s linear infinite;
}
.gap{ margin-right:100px;}
#keyframes slide {
0% {
transform: translateX(100%)
}
100% {
transform: translateX(-100%)
}
}
<div class="main">
<div class="text">
<span class="gap">Text</span>
<span class="gap">Text</span>
<span class="gap">Text</span>
<span class="gap">Text</span>
</div>
</div>

How to make a loading icon

I'm using Semantic UI and trying to create an animated icon for example with the spinner icon.
https://semantic-ui.com/elements/icon.html#spinners
With font-awesome it is pretty simple, as described here : https://fontawesome.com/how-to-use/on-the-web/styling/animating-icons*
Is there an equivalent of fa-spin for semantic UI?
There is a class called loader out of the box but you can always use custom CSS like below for your purposes.
.loading {
animation: rotation 2s infinite linear;
}
#keyframes rotation {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
/* Loading styles */
.loading {
animation: rotation 2s infinite linear;
}
#keyframes rotation {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
/* Additional styles for snippet */
.ui.container {
margin-top: 1em;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/components/icon.min.css" rel="stylesheet" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.css" rel="stylesheet" />
<link rel="stylesheet" type="text/css" href="https://semantic-ui.com//stylesheets/docs.css">
<div class="ui container">
<div class="ui raised segment">
<div class="ui doubling five column grid center aligned">
<div class="column"><i class="circle notch icon huge loading"></i></div>
<div class="column"><i class="cog icon huge loading"></i></div>
<div class="column"><i class="compass icon huge loading"></i></div>
<div class="column"><i class="compass outline icon huge loading"></i></div>
<div class="column"><i class="crosshairs icon huge loading"></i></div>
<div class="column"><i class="life ring icon huge loading"></i></div>
</div>
</div>
At current version of Semantic UI (in 2022) you can just add "loading" class for icon`s i-tag:
Static icon:
<i class="cog icon"></i>
Rotating icon :
<i class="loading cog icon"></i>
( https://www.geeksforgeeks.org/semantic-ui-icon-loading-state/ )

ng-show doesn't keep up with ng-animation for scaling down in a dropdown

I have a dropdown that I want a scaling down animation to show when the dropdown opens and closes. I have a CODEPEN here with the code for you to experiment in.
I slowed it down to a 10 sec animation (not the final speed obviously) just for you to see what I mean. The items are scaling down at the speed I instructed (10 sec) but the items below won't come down until the ng-animation is completed. This causes overlap.
This is what I have in my HTML
<div class="cnt">
<md-list ng-click="menuIsOpen = 1" layout="row" layout-padding="" class="layout-row" layout-align="start center" flex>
<span class="title flex" flex=""> Menu Item</span>
<i class="fa fa-chevron-down"></i>
</md-list>
<div class="sub-menu" ng-show="menuIsOpen===1" ng-animate="'animate'" >
<md-menu-item ng-repeat="item in data" >
<md-button>
<div layout="row" flex="">
<a ui-sref="{{item.link}}">
<p flex=""><i class="fa fa-{{item.icon}}"></i> {{item.title}}</p>
</a>
</div>
</md-button>
</md-menu-item>
</div>
<md-list ng-click="menuIsOpen = 2" layout="row" layout-padding="" class="layout-row" layout-align="start center" flex>
<span class="title flex" flex=""> Menu Item 2</span>
<i class="fa fa-chevron-down"></i>
</md-list>
<div class="sub-menu" ng-show="menuIsOpen===2" ng-animate="'animate'" >
<md-menu-item ng-repeat="item in data">
<md-button>
<div layout="row" flex="">
<a ui-sref="{{item.link}}">
<p flex=""><i class="fa fa-{{item.icon}}"></i> {{item.title}}</p>
</a>
</div>
</md-button>
</md-menu-item>
</div>
</div>
And the CSS
.ng-hide-remove {
-webkit-animation:2s scaleIn ease;
animation:2s scaleIn ease;
}
#-webkit-keyframes scaleIn {
From {
transform-origin: top;
-webkit-transform: scaleY(0);
-moz-transform: scaleY(0);
-ms-transform: scaleY(0);
-o-transform: scaleY(0);
transform: scaleY(0);
}
To {
transform-origin: top;
-webkit-transform: scaleY(1);
-moz-transform: scaleY(1);
-ms-transform: scaleY(1);
-o-transform: scaleY(1);
transform: scaleY(1);
}
}
#keyframes scaleIn {
From {
transform-origin: top;
-webkit-transform: scaleY(0);
-moz-transform: scaleY(0);
-ms-transform: scaleY(0);
-o-transform: scaleY(0);
transform: scaleY(0);
}
To {
transform-origin: top;
-webkit-transform: scaleY(1);
-moz-transform: scaleY(1);
-ms-transform: scaleY(1);
-o-transform: scaleY(1);
transform: scaleY(1);
}
}
I am essentially trying to reproduce the same animation as in the angular material website seen here
p.s. any different approach or idea that doesn't require too much change overall, I am open to it. I am hoping for a css modification, but I know that it may not be that easy after all. I am hopeful though :)
Thanks for the help.
UPDATE:
After a litte bit trial and error I think I found a SOLUTION.
If you animate not the div around (sub-menu) your md-menu-items but the item itself, it will work.
I just added ng-if="menuIsOpen===1" to your md-menu-item (deleted the ng-show="menuIsOpen===1 from the sub-menu) and changed the animation as follows:
md-menu-item.ng-enter{
-webkit-animation:3s move ease;
animation:3s move ease;
}
#-webkit-keyframes move {
From {
margin-bottom:-50px;
}
To {
margin-bottom:0px;
}
}
#keyframes move {
From {
margin-bottom:-50px;
}
To {
margin-bottom:0px;
}
}
Now the size of every item in the menu is animated.
I cheated a little bit with margin-bottom, but height was still not working.
I think you have two options. ( At least I can't think of anything more.)
Or maybe three, see above.
1.You can change the height and add transform-origin: top; like here:
#keyframes scaleIn {
From {
transform-origin: top;
-webkit-transform: scaleY(0);
-moz-transform: scaleY(0);
-ms-transform: scaleY(0);
-o-transform: scaleY(0);
transform: scaleY(0);
height: 0px;
}
To {
transform-origin: top;
-webkit-transform: scaleY(1);
-moz-transform: scaleY(1);
-ms-transform: scaleY(1);
-o-transform: scaleY(1);
transform: scaleY(1);
height: 190px;
}
}
With transform-origin it will scale from the top and not from the middle.
BUT then you have to adjust the height every time you change the number of menu items.
You write it new (is probably nothig for you because you wont change much). I think there are definitely easier solutions like your posted example. e.g. see HERE
Only the styles are missing and everything works.
I tried to change the height to % too, but that just never worked.
Even add some divs and change some positions nothing happens.
So maybe someone else has a better solution.
Hopefully I wasn't to slow only just got time to look at this properly.
Edited Codepen
Now to start your main problem was using CSS animations rather then transitions. With transitions being better for this as you are transitioning from one state(open) to another(closed). Rather then a complex animation with no defined start or end state.
So what I've done is change your classes:
.sub-menu{
background: #333;
max-height: 500px;
position: relative;
display: block;
overflow:hidden;
}
.sub-menu.ng-hide{
max-height: 0;
}
.sub-menu.ng-hide-remove {
transition: max-height 700ms cubic-bezier(0.35, 0, 0.25, 1);
}
.sub-menu.ng-hide-add {
transition: max-height 600ms cubic-bezier(0.35, 0, 0.25, 1);
}
They now use transisiton. As well as max-height rather than height so that no specific height value needs to be given to the submenu to fully show it. Also using cubic-bezier for smoother transitioning.
Also I removed the ng-animate="'animate'" directives on elements as it isn't needed, it is the old way of adding animations. All classes are now managed by the ng-show directive and there is no ng-animate directive. The current ngAnimate docs can give more info about the classes.
The only other change made was to move the ng-show to the div with the submenu class, which was just so an extra class didn't need to be created for the <ul>.

CSS transition inner div elements on div hover

I want to change the opacity of some text in my div when hover over happens :
currently my transition looks like this, and it just moved the box up a bit:
.bg-onebyone {
transition: all 0.5s ease;
background: #17B6A4 none repeat scroll 0% 0% !important;
}
.bg-onebyone:hover {
margin-top: -8px;
}
In my div.bg-onebyone I have another div holding some text like this
.bg-onebyone .widget-stats .stats-icon {
color: #FFF;
opacity: 0.5;
}
And what I want to do is just when the main div is hovered over I want to also increased the above opacity in the transition. How can I do this ?
<a href="/url">
<div class="widget widget-stats bg-onebyone">
<div class="stats-icon stats-icon-lg">
<i class="fa fa-search fa-fw"></i>
</div>
<div class="stats-desc">Creating Grouped Unmatched Aliases</div>
</div>
</a>
You need to use the :hover pseudo-class on parent and then select the child element.
.bg-onebyone:hover .stats-icon {
opacity: 0.8;
}
Also .bg-onebyone .widget-stats .stats-icon is incorrect for your HTML markup since it targets .stats-icon as a grand-child of .bg-onebyone which does not exist.
Output:
.bg-onebyone {
width: 300px;
height: 100px;
transition: all 0.5s ease;
background: #17B6A4 none repeat scroll 0% 0% !important;
}
.bg-onebyone:hover {
margin-top: -8px;
}
.bg-onebyone .stats-icon {
color: #FFF;
opacity: 0.5;
}
.bg-onebyone:hover .stats-icon {
opacity: 0.8;
}
<div class="widget widget-stats bg-onebyone">
<div class="stats-icon stats-icon-lg">Test text for opacity
<i class="fa fa-search fa-fw"></i>
</div>
<div class="stats-desc">Creating Grouped Unmatched Aliases</div>
</div>
Via JavaScript, use jQuery .hover() and .css(), like this:
$( "mainDiv" ).hover(
function() {
$("whereToChangeTheOpacity").css( "opacity", "0.5" );
},
function() {
$("whereToChangeTheOpacity").css( "opacity", "0" );
}
);

How would i make an element inside of a div rotate repeatedly?

I have a div and can neither use ID nor class.
I can only use names like so:
<div name="picture">
<img src="http://i.imgur.com/p0Fu5UZ.jpg" />
</div>
<div name="info">
<p>- Insert information here</p>
</div>
CSS:
div{
-webkit-animation: name 4s infinite linear
}
#-webkit-keyframes name {
0% {
-webkit-transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
}
What's the appropriate way to select any particular div, because [name=picture] doesn't work with the crammed code nor the non-crammed code. What can i do to fix this?
It should work for you:
CSS:
div[name="picture"] {
-webkit-animation: name 4s infinite linear
}
#-webkit-keyframes name {
0% {
-webkit-transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
}
HTML:
<div name="picture">
<img src="http://i.imgur.com/p0Fu5UZ.jpg" />
</div>
<div name="info">
<p>- Insert information here</p>
</div>
Demo: http://jsfiddle.net/srnug/121/
If you need the elements inside the div to rotate, then you can modify the selector as div[name="picture"] img or div[name="picture"] p

Resources