Circle text animation bugfixing - css

I worked with this tutorial, and coded this:
Splitting();
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: monospace;
}
body {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background: grey;
}
.circle {
transform-style: preserve-3d;
animation: animate 8s linear infinite;
}
.circle .char {
position: absolute;
top: 0;
left: 0;
background: blue;
color: red;
font-size: 4em;
padding: 5px 12px;
border-top: 4px solid black;
border-bottom: 4px solid black;
transform-style: preserve-3d;
transform-origin: center;
transform: rotateY(calc(var(--char-index) * 12deg)) translateZ(250px);
}
#keyframes animate {
0% {
transform: perspective(1000px) rotateY(360deg) rotateX(15deg);
}
100% {
transform: perspective(1000px) rotateY(0deg) rotateX(15deg);
}
}
<script src="https://unpkg.com/splitting/dist/splitting.min.js"></script>
<div class="circle" data-splitting>
Circle-Text-Animation-Effects-
</div>
Unfortunately, I realized that it doesn't work with Chrome and Firefox. They don't show the curvature. I tried to fix it with Autoprefixer, but it didn't help. Has anyone an idea how to solve this issue?
Here is how it should look like, and how it looks like with Safari:

There is an extra span around your letters that need to have transform-style: preserve-3d;
Splitting();
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: monospace;
}
body {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background: grey;
}
.circle {
transform-style: preserve-3d;
animation: animate 8s linear infinite;
}
/* added this */
.circle > span {
transform-style: preserve-3d;
display: block;
}
/**/
.circle .char {
position: absolute;
top: 0;
left: 0;
background: blue;
color: red;
font-size: 4em;
padding: 5px 12px;
border-top: 4px solid black;
border-bottom: 4px solid black;
transform-style: preserve-3d;
transform-origin: center;
transform: rotateY(calc(var(--char-index) * 12deg)) translateZ(250px);
}
#keyframes animate {
0% {
transform: perspective(1000px) rotateY(360deg) rotateX(15deg);
}
100% {
transform: perspective(1000px) rotateY(0deg) rotateX(15deg);
}
}
<script src="https://unpkg.com/splitting/dist/splitting.min.js"></script>
<div class="circle" data-splitting>
Circle-Text-Animation-Effects-
</div>

Related

Reversing CSS transition after unhover

I made this simple animation. But when I "unhover" the transitioned spans just "disappear". Is there any easy way to slide the spans back, aka. reverse the transition after unhover.
Or if necessary any complicated way?
If possible it would be great if the solution is CSS only.
Thanks in advance!
#container {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
#wrapper {
position: relative;
font-family: 'Courier New', Courier, monospace;
}
#wrapper h2 {
font-size: 8rem;
margin: 0px;
}
#wrapper:hover span:first-of-type {
visibility: visible;
transform: translate(0%, 0%);
}
#wrapper:hover span:last-of-type {
transform: translate(0%, 0%);
visibility: visible;
}
#wrapper span {
font-size: 8rem;
font-weight: bold;
transition: transform 1s;
}
#wrapper span:first-of-type {
position: absolute;
top: 0%;
left: 0%;
z-index: 1;
transform: translate(-10%, -100%);
visibility: hidden;
background: linear-gradient(45deg, #00ff00, #00ff80);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
#wrapper span:last-of-type {
position: absolute;
top: 0%;
left: 50%;
z-index: 1;
transform: translate(10%, 100%);
visibility: hidden;
background: linear-gradient(45deg, #00ff80, aqua);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
<div id="container">
<div id="wrapper">
<h2>Hi</h2>
<span>H</span>
<span>i</span>
</div>
</div>
Because visibilty cannot be animated smoothly, thus it is recommended to use a scalable value for visibility animation such as opacity.
#container {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
#wrapper {
position: relative;
font-family: 'Courier New', Courier, monospace;
}
#wrapper h2 {
font-size: 8rem;
margin: 0px;
}
#wrapper:hover span:first-of-type {
opacity: 1;
transform: translate(0%, 0%);
}
#wrapper:hover span:last-of-type {
transform: translate(0%, 0%);
opacity: 1;
}
#wrapper span {
font-size: 8rem;
font-weight: bold;
transition: transform 1s, opacity 1s;
}
#wrapper span:first-of-type {
position: absolute;
top: 0%;
left: 0%;
z-index: 1;
transform: translate(-10%, -100%);
opacity: 0;
background: linear-gradient(45deg, #00ff00, #00ff80);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
#wrapper span:last-of-type {
position: absolute;
top: 0%;
left: 50%;
z-index: 1;
transform: translate(10%, 100%);
opacity: 0;
background: linear-gradient(45deg, #00ff80, aqua);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
<div id="container">
<div id="wrapper">
<h2>Hi</h2>
<span>H</span>
<span>i</span>
</div>
</div>
But if you have to animate visibility for some reason, you may specify the animation-timing-function of visibility to step-end to make it disappear at the last moment:
#wrapper:not(:hover) span {
transition: transform 1s, visibility 1s step-end;
}
#container {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
#wrapper {
position: relative;
font-family: 'Courier New', Courier, monospace;
}
#wrapper h2 {
font-size: 8rem;
margin: 0px;
}
#wrapper:hover span:first-of-type {
visibility: visible;
transform: translate(0%, 0%);
}
#wrapper:hover span:last-of-type {
transform: translate(0%, 0%);
visibility: visible;
}
#wrapper span {
font-size: 8rem;
font-weight: bold;
transition: transform 1s;
}
#wrapper span:first-of-type {
position: absolute;
top: 0%;
left: 0%;
z-index: 1;
transform: translate(-10%, -100%);
visibility: hidden;
background: linear-gradient(45deg, #00ff00, #00ff80);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
#wrapper span:last-of-type {
position: absolute;
top: 0%;
left: 50%;
z-index: 1;
transform: translate(10%, 100%);
visibility: hidden;
background: linear-gradient(45deg, #00ff80, aqua);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
/* added */
#wrapper:not(:hover) span {
transition: transform 1s, visibility 1s step-end;
}
<div id="container">
<div id="wrapper">
<h2>Hi</h2>
<span>H</span>
<span>i</span>
</div>
</div>

backface-visibilty in rounded corners of a css cube

I'm trying a simple css cube and applying rounded corners shows that the box is empty and transparent, applying backface-visibility: hidden; makes it like filled with white color and the question is, if is there a way to style the appereance of colors and other properties to the behavior of the mentioned property backface-visibility?
backface-visibility: visible
backface-visibility: hidden
.welcome {
color:green;
font-size:36px;
font-family:cursive;
text-align:center;
padding:20px;
}
.* {
background-color: black;
}
h2 {
background-color: aliceblue;
box-shadow: 2px 2px 10px #666;
padding: 0.25em;
text-align:center;
}
div.space3D {
width: 300px;
height: 300px;
margin: 3em auto 0 auto;
border: 1px solid rgb(0,255,0);
position: relative;
perspective-origin: center -50%;
perspective: 300px;
transform: scale(0.75);
transform-style: preserve-3d;
}
div.cube {
width: 100%;
height: 100%;
position: absolute;
transform-style: preserve-3d;
transform: translateZ(-150px);
animation-name: gira;
animation-duration: 15000ms;
animation-iteration-count: infinite;
box-sizing: border-box;
}
div.base {
position: absolute;
width: 150px;
height: 150px;
background-color: rgba(0,0,0,0.15);
transform: translateX(75px) translateY(75px) rotateX(90deg) translateZ(-200px);
box-shadow: 0 0 50px 100px rgba(0,0,0,0.15);
transform-style: preserve-3d;
}
div.cara {
position: absolute;
width: 298px;
height: 298px;
background-color: #c2ffef;
border: 3px solid red;
border-radius: 2em;
font-size: 3em;
color: black;
text-align: center;
line-height: 298px;
box-shadow: 0px 0px 5px rgba(255,150,0,0.25);
transform-style: preserve-3d;
/*backface-visibility:hidden;*/
}
div.cara1 { /* Frente */
transform: translateZ(150px);
}
div.cara2 { /* AtrĂ¡s */
transform: rotateY(180deg) translateZ(150px);
}
div.cara3 { /* Izquierda */
transform: rotateY(-90deg) translateZ(150px);
}
div.cara4 { /* derecha */
transform: rotateY(90deg) translateZ(150px);
}
div.cara5 { /* abajo */
transform: rotateX(-90deg) translateZ(150px);
}
div.cara6 { /* arriba */
transform: rotateX(90deg) translateZ(150px);
}
#keyframes gira {
0% {
transform: translateZ(-150px) rotateY(0deg);
}
100% {
transform: translateZ(-150px) rotateY(360deg);
}
}
<h2>Cubo 3D con puro HTML5 y CSS3</h2>
<div class="space3D">
<div class="cube">
<div class="base"></div>
<div class="cara cara1">rubik</div>
<div class="cara cara2"></div>
<div class="cara cara3"></div>
<div class="cara cara4"></div>
<div class="cara cara5"></div>
<div class="cara cara6"></div>
</div><!-- termina cubo 3d -->
</div><!-- termina espacio 3d -->
</body>
</html>

Reduce the size of an icon during the animation

I'm trying to reduce the size of the icon-container (from 110px in 0% to 50px in 100%) when the animation "slide-bck-top" is on focus. I tried to pass &__icon-container {} inside #keyframes but it didnt work.
here is my scss file:
.button {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
border: none;
height: 150px;
width: 230px;
background-color: transparent;
outline: none;
&__icon-container {
width: 100px;
height: 100px;
border-radius: 50%;
color: color(white-0);
background-color: color(blue-150);
box-shadow: 0px 4px 4px color(black-0, 0.25);
padding: 20px;
cursor: pointer;
}
&__icon {
fill: currentColor;
width: 50px;
height: 50px;
}
&:focus {
animation: slide-bck-top 0.3s 1.5s cubic-bezier(0.47, 0, 0.745, 0.715) forwards;
}
#keyframes slide-bck-top {
0% {
transform: translateZ(0) translateY(0);
}
100% {
transform: translateZ(-400px) translateY(-200px);
}
}
}
The issue is #keyframes won't allow you to pass a selector, since it's meant for properties and SCSS won't compile it correctly nested. It would be like passing the selector in the color: attribute.
What you could do is pass the .button__icon-container into the :focus and move the #keyframes outside of the .button, since #keyframes is really a global scope item and SCSS/SASS will still render it outside of the .button anyway.
.button {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
border: none;
height: 150px;
width: 230px;
background-color: transparent;
outline: none;
&__icon-container {
width: 100px;
height: 100px;
border-radius: 50%;
color: color(white-0);
background-color: color(blue-150);
box-shadow: 0px 4px 4px color(black-0, 0.25);
padding: 20px;
cursor: pointer;
}
&__icon {
fill: currentColor;
width: 50px;
height: 50px;
}
&:focus {
animation: slide-bck-top 0.3s 1.5s cubic-bezier(0.47, 0, 0.745, 0.715) forwards;
.button__icon-container {
animation: make-small 0.3s 1.5s cubic-bezier(0.47, 0, 0.745, 0.715) forwards;
}
}
}
#keyframes slide-bck-top {
0% {
transform: translateZ(0) translateY(0);
}
100% {
transform: translateZ(-400px) translateY(-200px);
}
}
#keyframes make-small {
0% {
width: 110px;
height: 110px;
}
100% {
width: 50px;
height: 50px;
}
}
It compiles to this:
.button {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
border: none;
height: 150px;
width: 230px;
background-color: transparent;
outline: none;
}
.button__icon-container {
width: 100px;
height: 100px;
border-radius: 50%;
color: color(white-0);
background-color: color(blue-150);
box-shadow: 0px 4px 4px color(black-0, 0.25);
padding: 20px;
cursor: pointer;
}
.button__icon {
fill: currentColor;
width: 50px;
height: 50px;
}
.button:focus {
animation: slide-bck-top 0.3s 1.5s cubic-bezier(0.47, 0, 0.745, 0.715) forwards;
}
.button:focus .button__icon-container {
animation: make-small 0.3s 1.5s cubic-bezier(0.47, 0, 0.745, 0.715) forwards;
}
#keyframes slide-bck-top {
0% {
transform: translateZ(0) translateY(0);
}
100% {
transform: translateZ(-400px) translateY(-200px);
}
}
#keyframes make-small {
0% {
width: 110px;
height: 110px;
}
100% {
width: 50px;
height: 50px;
}
}
try using the max-height property.
#keyframes slide-bck-top {
0% {
transform: translateZ(0) translateY(0);
max-height:110px;
}
100% {
transform: translateZ(-400px) translateY(-200px);
max-height:50px
}
}

overflow absolute positioned psuedo element of a relative positioned parent set to overflow:hidden

I'm making a skull wearing a hat via CSS (jolly roger) which can be found at this codepen.
In the hat section, the lower edge of it has to be overflowed out of the parent div while the stripe in hat has to have overflow:hidden.
You may open the codepen link in both firefox and chrome to spot the difference.
While my code works fine in Firefox, this doesn't seem to work in chrome. I've tried many solutions that tells about how to position absolute items in a relative parent with overflow:hidden but none of those seem to work. Maybe I'm missing something important.
HTML
<div class="skull">
<div class="skull__face skull__face--animate">
<div class="skull__upper">
<div class="skull__hat"></div>
<div class="skull__nose"></div>
</div>
<div class="skull__lower">
<div class="skull__jaw"></div>
</div>
</div>
<div class="skull__bone skull__bone--left"></div>
<div class="skull__bone skull__bone--right"></div>
</div>
CSS
.skull__upper, .skull__lower {
background-color: white;
border: 7px solid black;
display: flex;
}
.skull__lower::before, .skull__jaw::before, .skull__jaw::after {
content: "";
width: 7px;
height: 6rem;
background-color: black;
display: inline-block;
position: absolute;
bottom: -1.6rem;
left: 0px;
right: 0px;
margin: auto;
}
#-webkit-keyframes boneDance {
0% {
-webkit-transform-origin: 49% 0%;
transform-origin: 49% 0%;
}
50% {
-webkit-transform-origin: 50% 0%;
transform-origin: 50% 0%;
}
100% {
-webkit-transform-origin: 51% 0%;
transform-origin: 51% 0%;
}
}
#keyframes boneDance {
0% {
-webkit-transform-origin: 49% 0%;
transform-origin: 49% 0%;
}
50% {
-webkit-transform-origin: 50% 0%;
transform-origin: 50% 0%;
}
100% {
-webkit-transform-origin: 51% 0%;
transform-origin: 51% 0%;
}
}
#-webkit-keyframes skullDance {
0% {
-webkit-transform: rotate(1deg);
transform: rotate(1deg);
}
50% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(-1deg);
transform: rotate(-1deg);
}
}
#keyframes skullDance {
0% {
-webkit-transform: rotate(1deg);
transform: rotate(1deg);
}
50% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(-1deg);
transform: rotate(-1deg);
}
}
#-webkit-keyframes blink {
from {
opacity: 0.4;
}
to {
opacity: 1;
}
}
#keyframes blink {
from {
opacity: 0.4;
}
to {
opacity: 1;
}
}
body {
background-color: #191919;
}
#media only screen and (max-width: 600px) {
body {
font-size: 12px;
}
}
.skull {
display: flex;
justify-content: center;
align-items: center;
margin-top: 10vh;
}
.skull__face {
display: flex;
flex-direction: column;
align-items: center;
z-index: 50;
position: relative;
}
.skull__face::after {
content: "";
width: 13rem;
border-radius: 50%;
box-shadow: 0px 0px 12rem 0 white;
position: absolute;
display: block;
height: 100%;
opacity: 0;
transition: opacity 1s ease-in-out;
}
.skull__face--animate:hover {
-webkit-animation: skullDance 1s steps(3) infinite alternate;
animation: skullDance 1s steps(3) infinite alternate;
cursor: none;
}
.skull__face--animate:hover::after {
opacity: 1;
-webkit-animation: blink 1s linear infinite alternate;
animation: blink 1s linear infinite alternate;
}
.skull__face--animate:hover ~ .skull__bone {
-webkit-animation: boneDance 1s steps(3) infinite alternate;
animation: boneDance 1s steps(3) infinite alternate;
}
.skull__upper {
width: 20rem;
height: 20rem;
border-radius: 50%;
z-index: 50;
position: relative;
}
.skull__upper::before, .skull__upper::after {
content: "";
display: block;
}
.skull__upper::before {
position: absolute;
border-radius: 50%;
box-shadow: 5.5rem 13.5rem 0px 2.8rem black, 14.5rem 13.5rem 0px 2.8rem black;
width: 1px;
height: 1px;
background-color: transparent;
}
.skull__hat {
justify-content: center;
background-color: #FFD020;
width: 20rem;
height: 10rem;
z-index: 45;
border-top-left-radius: calc(10rem + 7px);
border-top-right-radius: calc(10rem + 7px);
overflow: hidden;
}
.skull__hat::before, .skull__hat::after {
content: "";
display: block;
left: 0px;
right: 0px;
margin: auto;
}
.skull__hat::after {
height: 1rem;
background-color: #FFD020;
position: absolute;
border: 7px solid black;
border-radius: 1rem;
width: 30rem;
left: -5.5rem;
}
.skull__hat::before {
width: 18.5rem;
height: 0;
position: relative;
border-bottom: 3rem solid #FF0012;
border-left: 0.75rem solid transparent;
border-right: 0.75rem solid transparent;
margin-top: 5.35rem;
box-shadow: 0px 0px 0px 0px #191919, 0px -7px 0px 0px black;
}
.skull__lower {
width: 14rem;
height: 16rem;
border-radius: 50% 50% 50% 50% / 60% 60% 40% 40%;
z-index: 49;
margin-top: -7rem;
overflow: hidden;
position: relative;
}
.skull__lower::before {
bottom: 4.5rem;
z-index: 40;
}
.skull__nose {
width: 3rem;
height: 2rem;
background: black;
border-radius: 50%;
position: absolute;
bottom: 2rem;
left: 0px;
right: 0px;
margin: auto;
}
.skull__jaw {
width: 21rem;
height: 21rem;
border-radius: 50%;
border: 7px solid black;
position: absolute;
margin: auto;
top: -12.5rem;
left: -4rem;
box-shadow: 0px 1.8rem 0px 0px white, 0px 2.2rem 0px 0px black;
}
.skull__jaw::before {
margin-left: 6.6rem;
-webkit-transform: rotate(10deg);
transform: rotate(10deg);
}
.skull__jaw::after {
margin-right: 6.6rem;
-webkit-transform: rotate(-10deg);
transform: rotate(-10deg);
}
.skull__bone {
background: white;
height: 3rem;
width: 36rem;
position: absolute;
border: 7px solid black;
-webkit-transform-origin: 50% 0%;
transform-origin: 50% 0%;
}
.skull__bone::before, .skull__bone::after {
content: "";
position: absolute;
border-radius: 50%;
top: -1.5rem;
width: 3rem;
height: 3rem;
background: white;
}
.skull__bone::before {
left: -1.5rem;
}
.skull__bone::after {
right: -1.5rem;
}
.skull__bone--left {
-webkit-transform: rotate(-45deg);
transform: rotate(-45deg);
}
.skull__bone--left::before {
box-shadow: 0 3rem 0 white, -2px 3.1rem 0px 2px black, -2px -0.1rem 0px 2px black;
}
.skull__bone--left::after {
box-shadow: 0 3rem 0 white, 3px 3.1rem 0px 1px black, 2px -0.1rem 0px 2px black;
}
.skull__bone--right {
-webkit-transform: rotate(45deg);
transform: rotate(45deg);
}
.skull__bone--right::before {
box-shadow: 0 3rem 0 white, -2px 3.1rem 0px 2px black, -2px -0.1rem 0px 2px black;
}
.skull__bone--right::after {
box-shadow: 0 3rem 0 white, 3px 3.1rem 0px 1px black, 2px -0.1rem 0px 2px black;
}
Any suggestions to make it work at least in Firefox and Chrome.
Just removing the z-index from the .skull__hat class did the trick.
.skull__upper, .skull__lower {
background-color: white;
border: 7px solid black;
display: flex;
}
.skull__lower::before, .skull__jaw::before, .skull__jaw::after {
content: "";
width: 7px;
height: 6rem;
background-color: black;
display: inline-block;
position: absolute;
bottom: -1.6rem;
left: 0px;
right: 0px;
margin: auto;
}
#-webkit-keyframes boneDance {
0% {
-webkit-transform-origin: 49% 0%;
transform-origin: 49% 0%;
}
50% {
-webkit-transform-origin: 50% 0%;
transform-origin: 50% 0%;
}
100% {
-webkit-transform-origin: 51% 0%;
transform-origin: 51% 0%;
}
}
#keyframes boneDance {
0% {
-webkit-transform-origin: 49% 0%;
transform-origin: 49% 0%;
}
50% {
-webkit-transform-origin: 50% 0%;
transform-origin: 50% 0%;
}
100% {
-webkit-transform-origin: 51% 0%;
transform-origin: 51% 0%;
}
}
#-webkit-keyframes skullDance {
0% {
-webkit-transform: rotate(1deg);
transform: rotate(1deg);
}
50% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(-1deg);
transform: rotate(-1deg);
}
}
#keyframes skullDance {
0% {
-webkit-transform: rotate(1deg);
transform: rotate(1deg);
}
50% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(-1deg);
transform: rotate(-1deg);
}
}
#-webkit-keyframes blink {
from {
opacity: 0.4;
}
to {
opacity: 1;
}
}
#keyframes blink {
from {
opacity: 0.4;
}
to {
opacity: 1;
}
}
body {
background-color: #191919;
}
#media only screen and (max-width: 600px) {
body {
font-size: 12px;
}
}
.skull {
display: flex;
justify-content: center;
align-items: center;
margin-top: 10vh;
}
.skull__face {
display: flex;
flex-direction: column;
align-items: center;
z-index: 50;
position: relative;
}
.skull__face::after {
content: "";
width: 13rem;
border-radius: 50%;
box-shadow: 0px 0px 12rem 0 white;
position: absolute;
display: block;
height: 100%;
opacity: 0;
transition: opacity 1s ease-in-out;
}
.skull__face--animate:hover {
-webkit-animation: skullDance 1s steps(3) infinite alternate;
animation: skullDance 1s steps(3) infinite alternate;
cursor: none;
}
.skull__face--animate:hover::after {
opacity: 1;
-webkit-animation: blink 1s linear infinite alternate;
animation: blink 1s linear infinite alternate;
}
.skull__face--animate:hover ~ .skull__bone {
-webkit-animation: boneDance 1s steps(3) infinite alternate;
animation: boneDance 1s steps(3) infinite alternate;
}
.skull__upper {
width: 20rem;
height: 20rem;
border-radius: 50%;
z-index: 50;
position: relative;
}
.skull__upper::before, .skull__upper::after {
content: "";
display: block;
}
.skull__upper::before {
position: absolute;
border-radius: 50%;
box-shadow: 5.5rem 13.5rem 0px 2.8rem black, 14.5rem 13.5rem 0px 2.8rem black;
width: 1px;
height: 1px;
background-color: transparent;
}
.skull__hat {
justify-content: center;
background-color: #FFD020;
width: 20rem;
height: 10rem;
border-top-left-radius: calc(10rem + 7px);
border-top-right-radius: calc(10rem + 7px);
overflow: hidden;
}
.skull__hat::before, .skull__hat::after {
content: "";
display: block;
left: 0px;
right: 0px;
margin: auto;
}
.skull__hat::after {
height: 1rem;
background-color: #FFD020;
position: absolute;
border: 7px solid black;
border-radius: 1rem;
width: 30rem;
left: -5.5rem;
}
.skull__hat::before {
width: 18.5rem;
height: 0;
position: relative;
border-bottom: 3rem solid #FF0012;
border-left: 0.75rem solid transparent;
border-right: 0.75rem solid transparent;
margin-top: 5.35rem;
box-shadow: 0px 0px 0px 0px #191919, 0px -7px 0px 0px black;
}
.skull__lower {
width: 14rem;
height: 16rem;
border-radius: 50% 50% 50% 50% / 60% 60% 40% 40%;
z-index: 49;
margin-top: -7rem;
overflow: hidden;
position: relative;
}
.skull__lower::before {
bottom: 4.5rem;
z-index: 40;
}
.skull__nose {
width: 3rem;
height: 2rem;
background: black;
border-radius: 50%;
position: absolute;
bottom: 2rem;
left: 0px;
right: 0px;
margin: auto;
}
.skull__jaw {
width: 21rem;
height: 21rem;
border-radius: 50%;
border: 7px solid black;
position: absolute;
margin: auto;
top: -12.5rem;
left: -4rem;
box-shadow: 0px 1.8rem 0px 0px white, 0px 2.2rem 0px 0px black;
}
.skull__jaw::before {
margin-left: 6.6rem;
-webkit-transform: rotate(10deg);
transform: rotate(10deg);
}
.skull__jaw::after {
margin-right: 6.6rem;
-webkit-transform: rotate(-10deg);
transform: rotate(-10deg);
}
.skull__bone {
background: white;
height: 3rem;
width: 36rem;
position: absolute;
border: 7px solid black;
-webkit-transform-origin: 50% 0%;
transform-origin: 50% 0%;
}
.skull__bone::before, .skull__bone::after {
content: "";
position: absolute;
border-radius: 50%;
top: -1.5rem;
width: 3rem;
height: 3rem;
background: white;
}
.skull__bone::before {
left: -1.5rem;
}
.skull__bone::after {
right: -1.5rem;
}
.skull__bone--left {
-webkit-transform: rotate(-45deg);
transform: rotate(-45deg);
}
.skull__bone--left::before {
box-shadow: 0 3rem 0 white, -2px 3.1rem 0px 2px black, -2px -0.1rem 0px 2px black;
}
.skull__bone--left::after {
box-shadow: 0 3rem 0 white, 3px 3.1rem 0px 1px black, 2px -0.1rem 0px 2px black;
}
.skull__bone--right {
-webkit-transform: rotate(45deg);
transform: rotate(45deg);
}
.skull__bone--right::before {
box-shadow: 0 3rem 0 white, -2px 3.1rem 0px 2px black, -2px -0.1rem 0px 2px black;
}
.skull__bone--right::after {
box-shadow: 0 3rem 0 white, 3px 3.1rem 0px 1px black, 2px -0.1rem 0px 2px black;
}
<div class="skull">
<div class="skull__face skull__face--animate">
<div class="skull__upper">
<div class="skull__hat"></div>
<div class="skull__nose"></div>
</div>
<div class="skull__lower">
<div class="skull__jaw"></div>
</div>
</div>
<div class="skull__bone skull__bone--left"></div>
<div class="skull__bone skull__bone--right"></div>
</div>

Keyframe animation works on chrome but partly broken on safari

I've been trying to learn css animations by making a little personal site.
Joseph.how
I wanted the title to start large and near the page center, move up, then shrink and move to the left. Unfortunately when using safari the title moves to the left but instead of staying vertically centered, rises slightly, then pops back to center after the animation is done.
You can see the intended behavior on chrome (haven't tested with other browsers yet).
EDIT The problem persists with prefixes
(used auto-prefix extension in brackets)
Link to repo: https://github.com/JoeHowarth/joehowarth.me
EDIT 2 The problem is really just with the title-over keyframe, so I isolated that one
.header-container {
width: 100%;
border-bottom: 1px #000 solid;
height: 40vh;
position: relative;
background-color: #000;
color: #eee;
-webkit-animation: banner-up 1s 2s ease-in-out forwards;
animation: banner-up 1s 2s ease-in-out forwards;
font-family: 'Lato';
.title {
font-size: 30px;
position: absolute;
top: 90%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
font-weight: 700;
letter-spacing: .5em;
font-size: 60px;
-webkit-animation: title-over 4s 2s ease-in-out forwards;
animation: title-over 4s 2s ease-in-out forwards;
span {
font-weight: 100;
letter-spacing: .1em;
font-style: italic;
}
}
nav {
width: 40vw;
height: 10%;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: justify;
-ms-flex-pack: justify;
justify-content: space-between;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-ms-flex-direction: row;
flex-direction: row;
position: absolute;
top: -5vw;
right: 20px;
-webkit-transform: translate(0, -50%);
transform: translate(0, -50%);
-webkit-animation: nav 1s 7s ease-out forwards;
animation: nav 1s 7s ease-out forwards;
-webkit-transition : all 2s ease;
transition: all 2s ease;
div {
width: 15vw;
height: 100%;
margin: 0 2px;
// border: 1px #333 solid;
background: #111;
&:hover {
background: #222;
}
&:active {
background: #2a2a2a;
font-size: 38px;
}
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
font-size: 35px;
p {
text-align: center;
color: #eee;
display: block;
font-weight: 100;
}
}
}
}
// move title to left, make smaller
#keyframes title-over {
30% {
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
45% {
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
letter-spacing: .5em;
font-size: 60px;
}
65% {
letter-spacing: .5em;
}
100% {
top: 50%;
left: 10px;
-webkit-transform: translate(0%, -50%);
transform: translate(0%, -50%);
letter-spacing: .1em;
font-size: 40px;
}
}
#-webkit-keyframes title-over {
30% {
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
45% {
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
letter-spacing: .5em;
font-size: 60px;
}
65% {
letter-spacing: .5em;
}
100% {
top: 50%;
left: 10px;
-webkit-transform: translate(0%, -50%);
transform: translate(0%, -50%);
letter-spacing: .1em;
font-size: 40px;
}
}
HTML
<div class="header-container">
<header class="title">
JOSEPH.HOW<span>ARTH</span>
</header>
<!-- nav defaults to display:none, comes in w/ animation-->
<nav>
<div id="about-nav" href="#"><p>About Me</p></div>
<div id="proj-nav" href="#"><p>Projects</p></div>
<div id="resume-nav" href="#"><p>Resume</p></div>
</nav>
Use #-webkit-keyframes for safari
#keyframes banner-up {
50% {
border-bottom: 1px #111 solid;
}
100% {
height: 80px;
border-bottom: 3px #111 solid;
}
}
/* Safari */
#-webkit-keyframes banner-up {
50% {
border-bottom: 1px #111 solid;
}
100% {
height: 80px;
border-bottom: 3px #111 solid;
}
}

Resources