CSS Works Everywhere Except In Safari - css

I am using css to animate a div that contains text. The animation works as expected in Chrome, Firefox, and Edge, but not in Safari. The css 1) centers the div, 2) grows the font size from 0 to 200px while simultaneously 3) rotating the div 360deg around the Y axis.
I've "decorated" the presentation so as to make it easier to see what is happening: 1) a small, red square in the center of the window, and 2) a red border around the div.
Here is the HTML:
<html>
<head>
<title>Text Animation</title>
<link href="./style.css" rel="stylesheet">
</head>
<body>
<div id="myText">Hello World!</div>
<div id="decoration" style="width:10px; height:10px; background-color:red; position: fixed; top:50%; left:50%; transform: translate(-50%, -50%);"></div>
</body>
<script>
/* Initiating the animation via javascript makes it easier to try things */
window.onload = function() { setTimeout(initiateAnimation, 200) }
function initiateAnimation() {
let rotate = "rotateText 2s linear 0s 1 normal none running"
let grow = "growText 2s linear 0s 1 normal forwards running"
let myText = jQuery("#myText")
myText.css("animation", rotate + ", " + grow)
//myText.css("animation", grow)
//myText.css("width", 300)
//myText.css("height", 100)
//myText.css("animation", rotate)
}
</script>
</html>
Here is the css:
#keyframes growText {
from { font-size: 0px; }
to { font-size: 100px; }
}
#keyframes rotateText {
from { transform: rotateY(0deg) translate(-50%, -50%); }
to { transform: rotateY(360deg) translate(-50%, -50%); }
}
#myText {
/* Center the div */
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
/* Put the axis of rotation back to the center of the div (ie. compensate for the translation) */
transform-origin: left top;
white-space: nowrap;
overflow: hidden;
font-size: 0px;
border: 2px solid;
border-color: red;
}
Here it is running correctly in Chrome:
Here it is running errantly in Safari:
Note that the axis of rotation is on the left hand edge of the div. So, Safari is honoring the value of the transform-origin. But, Safari is not honoring the translate 50% 50% transform. It is as though Safari does not allow multiple properties to be modified in a keyframe.
You can see it in a browser using this link.
Any ideas? Thanks.
Update 1: If, in Safari, I run only one of the keyframe animations (either rotateText or growText) then it works as desired - everything is properly centered.

Related

How to make a zoom in function when the website opens

How can i make a code where if you open my webpage then this happens: https://www.youtube.com/watch?v=tGsKzZtRwxw using css?
But what i want instead is for the logo to first zoom in (faster, maybe 5 sec until the animation is over) to show the logo, then it goes to the top left where it stays there when you browse through my page. It is for a school project with the theme star wars.
You can do something like in below snippet (using animation) :
Use styles and decoration according to need , this is only a demo.
As known font-size is for text so this animation will work only for text . If you want animation for other stuffs than change accordingly like can use width height higher values or can use transform: scale() property
function zoom() {
var reed = document.getElementById("demo");
reed.classList.add("animation");
}
.animation {
animation: zoomer 5s linear;
}
#keyframes zoomer {
0% {
font-size: 300px;
}
100% {
font-size: 30px;
}
}
.color {
color: red;
font-size:30px;
}
<body onload="zoom()">
<h1 id="demo" class="color">content</h1>
</body>
You can try the CSS zoom rule:
<script type="text/javascript">
function zoom() {
document.body.style.zoom = "300%"
}
</script>
<body onload="zoom()">
<h6>content</h6>
</body>
Note: It just makes everything on the page bigger😃
I would suggest that when the page is fully loaded you set the logo style to have an animation which starts with transform with a scale from 1 to something and then moves to top 0 left 0 (or whatever is suitable).
Without seeing your actual code it is difficult to advise further but something like:
#keyframes logo {
0% {
top: 50%;
left: 50%;
transform: scale(1) translate(-50%, -50%);
}
50% {
top: 50%;
left: 50%;
transform: scale(2) translate(-50%, -50%);
}
100% {
top: 0;
left: 0;
transform: scale(1) translate(0, 0);
}

How to move a skewed div

I am trying to move a skewed div from top left off screen, through the screen, to bottom right off screen. The effect I am trying to get is that it looks like a parallelogram appears from somewhere up and to the left, and it slowly moves through the screen in a downwards and rightwards motion and then off the screen to the bottom.
Right now I have this index.html:
<html>
<head>
<link rel="stylesheet" href="index.css" />
</head>
<body>
<div class="div1" id="one"></div>
</body>
</html>
And here is my index.css:
div {
animation: rotate-all 2s 0 infinite linear alternate;
}
.div1 {
width: 100px;
height: 1000px;
transform: skew(20deg);
background-color: gray;
position: relative;
margin: auto;
animation-name: down;
animation-duration: 4s;
animation-iteration-count: infinite ;
}
#one {
top: 150px;
}
#keyframes down {
0% {
transform: translate(-200px, -1000px);
transform: skew(20deg);
}
100% {
transform: translate(250px, 750px);
}
}
I have two problems:
First, it is changing shape from the skewed shape (looks like a "\") to a unskewed one (looks like a "|"). If I try to add a skew in my 100% keyframe, then it does not move any more, it just stays in the same place. I tried both orders skew then translate / translate then skew.
Second, it does not seem to start above the screen, but right in the middle of the screen.
Appreciate any advice.
You were overwriting the transform property. Transform accepts multiple styles, separated by spaces. If you add the transform property twice, it will overwrite the first one. Just put the translate and skew on the same line both times and it will work.
For the second part, translate it by percents (relative to itself) rather than pixels (absolute measures).
div {
animation: rotate-all 2s 0 infinite linear alternate;
}
.div1 {
width: 100px;
height: 1000px;
transform: skew(20deg);
background-color: gray;
position: relative;
margin: auto;
animation-name: down;
animation-duration: 4s;
animation-iteration-count: infinite ;
}
#one {
top: 150px;
}
#keyframes down {
0% {
transform: translate(-200%, -200%) skew(20deg);
}
100% {
transform: translate(250px, 750px) skew(20deg);
}
}
<div class="div1" id="one"></div>

Flip image and stop at a certain angle

I have this CSS:
-moz-transform: scaleY(-1);
-o-transform: scaleY(-1);
-webkit-transform: scaleY(-1);
transform: scaleY(-1);
filter: FlipV;
-ms-filter: "FlipV";
that flips and image upside down.
All I want is the image to stop when has flipped 90° and so it's invisible.
Is that possible in any way?
If your need is to flip and image by 90 degrees such that it becomes invisible then you should look at using rotate(90deg) transforms (rotateX(90deg) in this case) like in the below snippet.
I am not sure on when you would be making the element become invisible (like :hover, click etc) but if you make it invisible on :hover then put the :hover selector on a container element instead of the image itself. This is because once the image is hovered and becomes invisible due to rotation then the mouse pointer is technically no longer over the image (in other words, hover is no longer applicable). This would mean that the image immediately reverts back to original state automatically.
div {
border: 1px solid #777;
height: 100px;
width: 200px;
}
img {
transition: all 1s;
}
div:hover img {
transform: rotateX(90deg);
}
<div>
<img src="http://lorempixel.com/200/100/nature/1" />
</div>
On the other hand if you are insistent on using scaleY() transform to achieve this effect, then you would have to use scaleY(0) in-order to make the element invisible. scaleY(-1) will always end up at -180deg and there is no way to stop this in the middle.
div {
border: 1px solid #777;
height: 100px;
width: 200px;
}
img {
transition: all 1s;
}
div:hover img {
transform: scaleY(0);
}
<div>
<img src="http://lorempixel.com/200/100/nature/1" />
</div>
http://davidwalsh.name/demo/css-flip.php
Take a look at this demo from great David Walsh :)
I think for you the vertical flip is more interesting
Just change the .front and .back # :hover to 90deg and you get the result you want!

Position AFTER transform in CSS?

Consider the following attempt to rotate a paragraph 90 degrees and position it so that the corner that was initially its top-left corner (and which therefore becomes its top-right corner after the rotation) ends up located at the top-right corner of the parent block.
HTML:
<!DOCTYPE html>
<html>
<body>
<div id="outer">
<p id="text">Foo bar</p>
</div>
</body>
</html>
CSS:
#outer {
border: solid 1px red;
width:600px;
height: 600px;
position: relative;
}
#text {
transform: rotate(90deg);
position: absolute;
top: 0;
right: 0;
}
In Firefox 19.0.2 on OS X 10.6.8, it fails. This appears to be because, despite the order in which the CSS properties were given, the transformation is applied after the positioning. In other words, the browser:
places #text such that its top-right corner is located at the top-right corner of the parent block, but only then
rotates it, with the result that what is now its top-right corner is not located at the top-right corner of the parent block.
As a result, the transform-origin property isn't much use here. If, for instance, one used transform-origin: top right; then #text would need to be moved downwards by the width it had before it was rotated.
My question: is there a way to tell the browser to apply the CSS positioning properties after the rotation; and if not, then is there instead a way to move #text downwards (e.g. using top:) by the width it had before it was rotated?
NB. Ideally the solution should not require setting a fixed width: for #text, and must not require JavaScript.
You can apply more than one transform to an element, and the order does matter. This is the simplest solution: http://jsfiddle.net/aNscn/41/
#outer {
border: solid 1px red;
width:600px;
height: 600px;
position: relative;
}
#text {
background: lightBlue;
position: absolute;
top: 0;
left: 0;
right: 0;
transform: translate(100%) rotate(90deg);
transform-origin: left top;
-webkit-transform: translate(100%) rotate(90deg);
-webkit-transform-origin: left top;
}
The transform origin is the point around which a transformation is applied. For example, the transform origin of the rotate() function is the center of rotation - https://developer.mozilla.org/en-US/docs/Web/CSS/transform-origin
Rotating -90deg.
.rotate {
position:absolute;
-webkit-transform-origin: left top;
/* Safari */
-webkit-transform: rotate(-90deg) translateX(-100%);
/* Firefox */
-moz-transform: rotate(-90deg) translateX(-100%);
/* IE */
-ms-transform: rotate(-90deg) translateX(-100%);
/* Opera */
-o-transform: rotate(-90deg) translateX(-100%);
}
Solved: here
This is the code I've added:
left: 100%;
width: 100%;
-webkit-transform-origin: left top;
I've also added some prefixed transform properties so it will be cross browser
-webkit-transform:rotate(90deg);
-moz-transform:rotate(90deg);
-ms-transform:rotate(90deg);
-o-transform:rotate(90deg);
transform:rotate(90deg);
How I did it:
I've found this question and, as the name of the website says, "fiddled" with the code to obtain this behavior. I guess the solution is left: 100%; instead of right: 0;.
(the width: 100%; is there because for some reason it wasn't 100% and the text would overflow to the next line)
You may want to try using CSS3 #keyframes animation. It will allow you to rotate and reposition in any order you like. Here is a tutorial that may help: [CSS-Tricks][1]
.container {
position: relative;
width: 200px;
height: 200px;
border: 1px solid red;
}
p {
border: 1px solid blue;
position: absolute;
top: auto;
right: 0;
display: inline-block;
margin: 0;
animation: 1s rotate 1s both;
}
#keyframes rotate {
0% {
transform-origin: top left;
transform: rotate(0deg);
right:0;
}
50% {
right:0;
}
100% {
transform-origin: top left;
transform: rotate(90deg);
right: -64px;
}
}
<div class="container">
<p>some text</p>
</div>
You might want to play around with the translate option which you can apply as the second transform function after rotate and place your element at the exact position that you want to.
There is no other way I guess to tell the browser to use the position properties after the transform function is used using plain css.
See this demo - http://codepen.io/anon/pen/klImq
Place "!important" at the end of the transform line.

How to rotate the background image in the container?

I want to rotate the image which is placed in the button of scrollbar in Chrome. Now I have a CSS with this content:
::-webkit-scrollbar-button:vertical:decrement {
background-image: url(images/arrowup.png);
-webkit-transform: rotate(120deg);
-moz-transform: rotate(120deg);
background-repeat: no-repeat;
background-position: center;
background-color: #ECEEEF;
border-color: #999;
}
I wish to rotate the image without rotating its content.
Very well done and answered here – http://www.sitepoint.com/css3-transform-background-image/
#myelement:before {
content: "";
position: absolute;
width: 200%;
height: 200%;
top: -50%;
left: -50%;
z-index: -1;
background: url(background.png) 0 0 repeat;
transform: rotate(30deg);
}
Very easy method, you rotate one way, and the contents the other. Requires a square though
#element{
background : url('someImage.jpg');
}
#element:hover{
transform: rotate(-30deg);
}
#element:hover >*{
transform: rotate(30deg);
}
Update 2020, May:
Setting position: absolute and then transform: rotate(45deg) will provide a background:
div {
height: 200px;
width: 200px;
outline: 2px dashed slateBlue;
overflow: hidden;
}
div img {
position: absolute;
transform: rotate(45deg);
z-index: -1;
top: 40px;
left: 40px;
}
<div>
<img src="https://placekitten.com/120/120" />
<h1>Hello World!</h1>
</div>
Original Answer:
In my case, the image size is not so large that I cannot have a rotated copy of it. So, the image has been rotated with photoshop. An alternative to photoshop for rotating images is online tool too for rotating images. Once rotated, I'm working with the rotated-image in the background property.
div.with-background {
background-image: url(/img/rotated-image.png);
background-size: contain;
background-repeat: no-repeat;
background-position: top center;
}
Good Luck...
CSS:
.reverse {
transform: rotate(180deg);
}
.rotate {
animation-duration: .5s;
animation-iteration-count: 1;
animation-name: yoyo;
animation-timing-function: linear;
}
#keyframes yoyo {
from { transform: rotate( 0deg); }
to { transform: rotate(360deg); }
}
Javascript:
$(buttonElement).click(function () {
$(".arrow").toggleClass("reverse")
return false
})
$(buttonElement).hover(function () {
$(".arrow").addClass("rotate")
}, function() {
$(".arrow").removeClass("rotate")
})
PS: I've found this somewhere else but don't remember the source
I was looking to do this also. I have a large tile (literally an image of a tile) image which I'd like to rotate by just roughly 15 degrees and have repeated. You can imagine the size of an image which would repeat seamlessly, rendering the 'image editing program' answer useless.
My solution was give the un-rotated (just one copy :) tile image to psuedo :before element - oversize it - repeat it - set the container overflow to hidden - and rotate the generated :before element using css3 transforms. Bosh!
try making a div for the image only and then flipping it with transform: scaleY(-1); or transform: scaleX(-1);
if you want to have the navbar in front of the image you can make an overlapping div and set its opacity property to 0;
I tried all solutions but none helped, below is what was my problem and how I solved it:
Problem: we have an image for desktops with landscape orientation but To show the same image but rotated (portrait) for mobile screens.
How: I just rotated the actual image in my assets folder the way I wanted (portrait), and then just used media queries to call that image for my background for mobiles, and that's it.
(this was the easiest and quick solution I did.)
Update Dec 2021
Since the original question is
"..rotate the background image .."
The best answer looks to be here
https://stackoverflow.com/a/62135576/3446280

Resources