Tricky CSS Positioning Animation - css

I'm learning about CSS animations and am trying to animate this stamp which uses relative and absolute positioning. I want the animation to:
Start at it's original size.
Grow 2-3xs that size and be at the center of the screen.
Pause for 2-3 seconds seconds.
Shrink back down to it's original size and spot.
The problem I'm running into is keeping the elements positioned on top of the stamp in the same place as the transitions occur. Looking to keep it pure CSS if possible (*side note I haven't added any web-kit/browser support yet because I'm just trying to make it work first).
Here is the code:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
display: flex;
height: 90vh;
justify-content: flex-end;
align-items: flex-start;
background: grey;
}
.park-img {
width: 10rem;
height: 11.2rem;
display: inline-block;
margin-left: 2px;
padding: 10px;
background: white;
position: relative;
top: 2rem;
left: -2rem;
/*-webkit-filter: drop-shadow(0px 0px 10px rgba(0,0,0,0.5));
/*The stamp cutout will be created using crisp radial gradients*/
background: radial-gradient( transparent 0px, transparent 4px, white 4px, white);
/*reducing the gradient size*/
background-size: 20px 20px;
/*Offset to move the holes to the edge*/
background-position: -10px -10px;
/*Animation*/
animation: stampAnimation 9s ease-in-out;
}
#keyframes stampAnimation {
0% {}
50% {
transform: scale(3, 3) translate(-35%, 35%);
}
75% {
transform: scale(3, 3) translate(-35%, 35%);
}
}
.stampText {
position: relative;
top: -1rem;
left: -1.8rem;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
color: #fafafa;
text-transform: uppercase;
animation: stampAnimation 9s ease-in-out;
}
.park-name {
font-weight: bold;
text-align: center;
font-size: 1rem;
}
.park-title {
width: 90%;
overflow: hidden;
text-align: center;
font-size: .5rem;
}
.park-title:before,
.park-title:after {
background-color: #fafafa;
content: "";
display: inline-block;
height: 1px;
position: relative;
vertical-align: middle;
width: 10%;
}
.park-title:before {
right: 0.5rem;
margin-left: -50%;
}
.park-title:after {
left: 0.5rem;
margin-right: -50%;
}
<div class="park-stamp">
<img src="https://res.cloudinary.com/saveallthethings/image/upload/v1614633821/daniel-burka-X_IwSPO2GH0-unsplash_zvoyst.jpg" class="park-img" />
<div class="stampText">
<div class="park-name">Zion</div>
<div class="park-title">National Park</div>
</div>
</div>
As well as the codepen:
https://codepen.io/aspirationalhobbit/pen/GRNPqxw?editors=0100

I have edited your code to make changes that are different from my initial answer.
Check https://codepen.io/udabasili/pen/VwmqmQK?editors=1100.
Basically, I created a css for the container of your element and moved the animation there. I also removed the translate from your animation. Check the css in the codepen to see the changes
.park-stamp{
animation: stampAnimation 9s ease-in-out infinite;
}

Related

sass animation did not work after adding a transition-timing function

i wanted to create a box with a border and inside it a small div, i wanted when i have a hover over the box the small div inside it will start to animate and but the animation did not start at all, so i deleted hover also the animation did not work in this case too,
here what i have tried:
<div class="row mb-4">
<div class="col col__animation">
<div id="object"></div>
</div>
</div>
Scss:
.col__animation{
display: flex;
border-radius: 1rem !important;
border: 1px solid #284876;
height: 200px !important;
align-items: center;
#object {
width: 40px;
height: 50px;
background: blueviolet;
margin-top: 2px;
margin-bottom: 1px;
margin-right: 3px;
}
&:hover{
#object{
transition: transform 1000ms;
transition-timing-function: ease-in-out;
}
}
}
I am trying to try many animations effects like making the box move to right and go back to initial position and many more animations
This should work
.col__animation {
display: flex;
border-radius: 1rem !important;
border: 1px solid #284876;
height: 200px !important;
align-items: center;
}
.col__animation #object {
width: 40px;
height: 50px;
background: blueviolet;
margin-top: 2px;
margin-bottom: 1px;
margin-right: 3px;
animation: mymove 3s infinite;
}
#keyframes mymove {
0% {
margin-left: 0px;
}
50% {
margin-left: calc(100% - 40px);
}
100% {
margin-left: 0px;
}
}
Codepen

css transition is not working on gradients? [duplicate]

This question already has answers here:
Use CSS3 transitions with gradient backgrounds
(19 answers)
Closed 1 year ago.
.body {
background-color: #18181a;
color: white;
font-size: 2.5rem;
margin-left: 0%;
border-radius: 5px;
}
.body .card{
background:linear-gradient(90deg, rgba(0,0,0,1) 0%, rgba(0,212,255,0) 100%),url("./images/yuuki_mikan_bg.jpg");
background-repeat: no-repeat;
background-position: right;
width: 90%;
height: 80%;
border-radius: 10px;
margin: 10px;
margin-left: auto;
margin-right: auto;
display: flex;
justify-content: space-between;
flex-direction: row-reverse;
transition: background 0.5s linear;
}
.body .card:hover {
background:linear-gradient(90deg, rgba(0,0,0,0.17690826330532217) 0%, rgba(0,212,255,0) 100%),url("./images/yuuki_mikan_bg.jpg");
background-position: right;
}
.body .card .card_img{
max-width: 80%;
max-height: 95%;
border-radius: 5px;
/* bottom: 9px; */
/* left: -10px; */
/* top: -10px; */
transition: 0.5s;
opacity: 1;
display: flex;
justify-content: flex-start;
align-self: center;
}
.body .card .card_name{
margin-right: 2%;
margin-top: auto;
margin-bottom: auto;
font-size: 2.5rem;
text-shadow: 0px 0px 18px black;
opacity: 1;
}
this is the code im using, whenever i hover over .card, it changes the background color but transition doesn't delay its transition time. If you want more context, this is the website my code is running at https://oniichann.tk/waifus
I believe the only animatable property on a background gradient is background-position.
You may be able to achieve what you're looking for by doing something like the following:
.card {
position: relative;
text-align: center;
color: white;
padding: 100px;
background: url("https://oniichann.tk/waifus/images/bg.jpg");
background-repeat: no-repeat;
background-position: right;
background-size: cover;
}
.card:before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(
90deg,
rgba(0, 0, 0, 1) 0%,
rgba(0, 0, 0, 0) 100%
);
background-size: 200% 200%;
transition: background-position 0.5s linear;
}
.card:hover:before {
background-position: 100% 50%;
}
<div class="card"></div>

Triggering CSS transition when setting top to auto

I am building a personal portfolio site to showcase some projects and am trying to implement the following:
A screenshot of a website is shown with the title of the site on a card at the bottom of the image
When the user hovers over the image, the image fades and the card at the bottom of the image smoothly pops up to display a description of the site
Everything is set up, but I cannot get the card to transition smoothly from the bottom of the image, it currently jumps from its starting position to ending position.
A codepen is here: https://codepen.io/umbauk/full/vYYZEjW
The relevant portion of my code is here:
.project-text {
background-color: rgb(58, 58, 58);
padding: 1%;
z-index: 5;
position: absolute;
width: 100%;
top: calc(100% - 3rem);
left: 0;
transition: all 0.5s ease;
}
.project-box:hover .project-text {
top: auto;
bottom: 0;
transition: all 0.5s ease;
}
project-text box is of variable size so I initially set it to show the top 3rem of the text box so that only the title displays. On hover, I set bottom: 0 so that all text is displayed (and set top: auto so that setting bottom can override top.
However, transition: all 0.5s ease; is not being triggered. It is triggered if I set top to something other than auto e.g. top: 50%.
How do I get my project-text box to smoothly transition in and out while just popping up enough to show all text? Thanks in advance!
Basically you cannot transition anything to auto. Transitions etc rely on numbers and auto is not a number.
Rather than using changing top values etc I'd suggest you look into a transform.
html {
font-size: 18px;
height: 100%;
}
body {
color: rgb(177, 177, 177);
height: 100%;
background-color: #121212;
}
h3 {
font-size: 2rem;
color: #ffffff;
text-decoration: none;
opacity: 0.87;
margin: 0;
}
.projects {
height: 100%;
background-color: #121212;
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 300px 300px;
grid-template-areas: 'project1 project2' 'project3 project4';
padding-left: 15%;
padding-right: 15%;
padding-top: 5%;
grid-gap: 5%;
}
.project-text {
background-color: rgb(58, 58, 58);
padding: 1%;
z-index: 5;
position: absolute;
width: 100%;
top: 100%;
left: 0;
transform: translateY(-3rem);
transition: all 0.5s ease;
}
.project-box:hover .project-text {
transform: translateY(-100%);
transition: all 0.5s ease;
}
.project-box {
display: flex;
flex-direction: column;
flex-wrap: wrap;
flex: 1 1 auto;
justify-content: center;
align-items: flex-end;
background-position: center;
background-size: cover;
position: relative;
background: #121212;
overflow: hidden;
}
.project-box:before {
content: ' ';
display: block;
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: 1;
background-repeat: no-repeat;
background-position: 50% 0;
background-size: cover;
}
.project-box:hover::before {
opacity: 0.6;
}
.project1 {
grid-area: project1;
}
.project1:before {
background-image: url('https://darrengreenfield.com/cafeandkids.png');
}
<body>
<div class="projects" id="projects">
<div class="project1 project-box">
<div class="project-text">
<a href="https://cafeandkids.com" target="_blank" rel="noopener noreferrer">
<h3>cafeandkids.com</h3>
</a>
<p>
An app to help parents find great playgrounds near great coffee shops. A single page, front-end only app using HTMl, CSS, JavaScript and React. Uses Google Maps API and the OpenWeather API.
</p>
</div>
</div>
</div>
</body>

Change animation origin on mouse off event

I've got some css/html code. I wanna improve my "unhover" state by doing following: when I hover over a button there is a before element sliding from left to right. I can easily change it from right to left. However when I do the "unhover" action, before element slides in the opposite direction - from right to left. What I want to achieve is animating it's width from 100% to 0% but from left to right. What should I do to get the result?
https://codepen.io/trueFalse24/pen/YzKNgYm
a{
background: #7f8c8d;
padding: 20px 30px;
text-transform: uppercase;
color: #fff;
position: relative;
&:before{
content: '';
position: absolute;
top: 0;
left: 0;
width: 0%;
height: 100%;
background: rgba(236,240,241, 0.3);
transition: all 0.3s ease;
}
&:hover{
&:before{
width: 100%;
}
}
}
I've modified your pen to get the effect by changing a few usages of the left and right properties. My edits are marked by comments below.
.container{
padding:0;
margin: 0;
box-sizing: border-box;
background: #3498db;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
a{
background: #7f8c8d;
padding: 20px 30px;
text-transform: uppercase;
color: #fff;
position: relative;
&:before{
content: '';
position: absolute;
top: 0;
right: 0; /* Replaced left */
width: 0%;
height: 100%;
background: rgba(236,240,241, 0.3);
transition: all 0.3s ease;
}
&:hover{
&:before{
width: 100%;
right: auto; /* Added */
left: 0; /* Added */
}
}
}
}

CSS Grid, position absolute an element in a css grid item: IMPOSSIBLE

I have this situation: https://jsfiddle.net/rozkvsdh/5/
A CSS Grid, simply, but in some items, I need to put a ribbon or another div.
It's impossible!
How can I do?
grid-item {
background-color: lightgreen;
display: flex;
justify-content: center;
align-items: center;
}
.ribbon-wrapper {
width: 85px; // the length should be not in px I think!
height: 88px; // the length should be not in px I think!
overflow: hidden;
//position: absolute; it doesn't work!
position: relative;
top: -3px;
left: -3px;
.ribbon {
font: bold 15px sans-serif;
color: #333;
text-align: center;
-webkit-transform: rotate(-45deg);
-moz-transform: rotate(-45deg);
-ms-transform: rotate(-45deg);
-o-transform: rotate(-45deg);
position: relative;
padding: 7px 0;
top: 15px;
left: -30px;
width: 120px;
background-color: #ebb134;
color: #fff;
}
}
you could use a pseudo and a data attribute :
HTML5 is designed with extensibility in mind for data that should be associated with a particular element but need not have any defined meaning. data-* attributes allow us to store extra information on standard, semantic HTML elements without other hacks such as non-standard attributes, extra properties on DOM
overflow can be used and background-clip can help to mimic ribbon standing a bit outside
The background-clip CSS property specifies whether an element's background, either the color or image, extends underneath its border.
vmin or vmax units could be used to set font-size to resize the ribbon via em on padding and coordonates.
The viewport-percentage lengths
are relative to the size of the initial containing block. When the height or width of the initial containing block is changed, they are scaled accordingly.
eventually, shadow can be added and linear-gradient can help to draw slanted shadow's parts.
Demo:
body {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
grid-auto-rows: 1fr;
grid-gap: 2px;
height: 100vh;
padding: 5px;
margin: 0;
box-sizing: border-box;
}
grid-item {
background-color: lightgreen;
background-clip: content-box;
display: flex;
justify-content: center;
align-items: center;
position: relative;
overflow: hidden;
padding: 3px;
}
grid-item[data-class="new"]:before {
content: attr(data-class);
position: absolute;
font-size: 2vmax; /* update font-size */
top: 0.4em;
left: -1.3em;
padding: 0em 1.5em;
transform: rotate(315deg);
background-color:gold;
/* eventually add some shadow effects */
background-image:
linear-gradient(135deg, black 0.9em, transparent 1.15em),
linear-gradient(-135deg, black 0.9em, transparent 1.15em);
box-shadow: 0 0 3px;
}
<grid-item>see</grid-item>
<grid-item>full</grid-item>
<grid-item>page</grid-item>
<grid-item>then</grid-item>
<grid-item data-class="new">RESIZE</grid-item>
<grid-item>window</grid-item>
<grid-item>to</grid-item>
<grid-item>see</grid-item>
<grid-item>ribbon</grid-item>
<grid-item data-class="new">font&size</grid-item>
<grid-item>updates</grid-item>
<grid-item>F</grid-item>
<grid-item data-class="new">PRO</grid-item>
<grid-item>B</grid-item>
<grid-item>C</grid-item>
<grid-item>D</grid-item>
<grid-item>E</grid-item>
<grid-item>F</grid-item>
<grid-item>A</grid-item>
<grid-item>B</grid-item>
you need to put position: relative; on grid-item and then you can use absolute position on .ribbon-wrapper.
grid-item {
background-color: lightgreen;
display: flex;
justify-content: center;
align-items: center;
position: relative;
}
.ribbon-wrapper {
width: 85px; // the length should be not in px I think!
height: 88px; // the length should be not in px I think!
overflow: hidden;
position: absolute;
top: -3px;
left: -3px;
.ribbon {
font: bold 15px sans-serif;
color: #333;
text-align: center;
-webkit-transform: rotate(-45deg);
-moz-transform: rotate(-45deg);
-ms-transform: rotate(-45deg);
-o-transform: rotate(-45deg);
position: relative;
padding: 7px 0;
top: 15px;
left: -30px;
width: 120px;
background-color: #ebb134;
color: #fff;
}
}
https://jsfiddle.net/thesouthstar86/rozkvsdh/6/
You can do it and also works for resize but it's a bit messy.
The spacer divs are there so you have the height. You need one on each side because you want PRO to be centered. We sacrifice 1px on each side to make this work and now ribbon-wrapper can be absolute
https://jsfiddle.net/rozkvsdh/9/
HTML
<grid-item>
<div class="ribbon-wrapper"><div class="ribbon">NEW</div></div>
<div class="spacer"></div>
<div>PRO</div>
<div class="spacer"></div>
</grid-item>
CSS
// this is new
.spacer {
height: 88px;
width: 1px;
}
grid-item {
background-color: lightgreen;
display: flex;
justify-content: center;
align-items: center;
position: relative; // added
}
.ribbon-wrapper {
width: 85px; // the length should be not in px I think!
height: 88px; // the length should be not in px I think!
overflow: hidden;
position: absolute;
top: 0; // edited
left: 0; // edited
}
The ribbon won't align left because it's an in-flow child of a flex container with justify-content: center. So both the ribbon and the content are centered side-by-side.
You can override that setting with margin-right: auto, which will left-align the ribbon, but it will also right-align the content.
You can insert an invisible spacer item to create equal balance in the container, keeping the content centered. But that's a bit involved and may be unnecessary.
Stick with CSS positioning properties. This will position the ribbon. Re-sizing it is another matter:
grid-item {
background-color: lightgreen;
display: flex;
justify-content: center;
align-items: center;
position: relative; /* establish nearest positioned ancestor for abspos containment */
}
.ribbon-wrapper {
overflow: hidden;
position: absolute;
top: 0;
left: 0;
bottom: 0;
}
.ribbon-wrapper .ribbon {
font: bold 15px sans-serif;
color: #333;
text-align: center;
transform: rotate(-45deg);
position: relative;
padding: 7px 0;
top: 15px;
left: -30px;
width: 15vw;
background-color: #ebb134;
color: #fff;
}
revised fiddle

Resources