CSS cubic-bezier doesn't animate back to the original position - css

I have this somewhat simple animation. It does the animation just fine when hover over the target elements, but it doesn't transition back to the original position when the cursor hovers outside the target element. Rather, it just snaps back in one fell and ugly swoop. :)
<article class="anim">
<a href="#foo">
<img src="https://dummyimage.com/240x200/ff9900/fff.png&text=TADA" alt="foo">
<span class="left">
<img src="https://dummyimage.com/240x200/121212/fff&text=hey+you" alt="left">
</span>
<span class="right">
<img src="https://dummyimage.com/240x200/000/fff&text=hey+you" alt="right">
</span>
</a>
</article>
And this is the scss:
.anim {
$w: 240px;
$h: 200px;
width: $w;
height: $h;
overflow: hidden;
a {
display: block;
position: relative;
width: 100%;
height: 100%;
}
img {
z-index: 1;
position: absolute;
width: $w;
top: 0;
left: 0;
}
span {
display: block;
height: 100%;
width: 50%;
position: absolute;
z-index: 2;
overflow: hidden;
// This animation snaps back uglily.
transition: all cubic-bezier(.29, 1.01, 1, -0.68) 0.5s;
// This animation transitions back just fine...
//transition: all 0.5s ease-in 0s;
}
.left {
left: 0px;
}
.right {
right: 0px;
img {
margin-left: -100%;
}
}
a:hover > .left {
left: -100%;
}
a:hover > .right {
right: -100%;
}
}
What I don't understand is that the commented out animation (with easy-in) transitions back smootly, but the cubic-bezier one does not.
I don't know what is missing here. Here's a pen:
https://codepen.io/FernandoBasso/pen/XqrOpV?editors=1100

The reason is that in the following code
a:hover > .left {
left: -100%;
}
a:hover > .right {
right: -100%;
}
the values -100% send the divs too far away to see the reverse effect. Using -50% instead does what you want! :)
Check this out:
https://codepen.io/sotmihos/pen/yjLqJK

you can reverse the cubic-bezier to achieve that :
( don't mind the javascript function it's there just to show how to reverse the cubic-bezier )
function reverseCssCubicBezier(cubicBezier) {
var maxX = Math.max(cubicBezier[0].x, cubicBezier[1].x, cubicBezier[2].x, cubicBezier[3].x);
var maxY = Math.max(cubicBezier[0].y, cubicBezier[1].y, cubicBezier[2].y, cubicBezier[3].y);
var halfUnitTurn = function(v) {
var tx = maxX/2, ty = maxY/2;
return { x: tx - (v.x-tx), y: ty - (v.y-ty) };
};
var revd = cubicBezier.map(halfUnitTurn);
return revd.reverse();
}
var ease = [{x:0,y:0}, {x:0.29,y:1.01}, {x:1,y:-0.68}, {x:1,y:1}];
var ease_reversed = reverseCssCubicBezier(ease);
var ease_css_string = 'cubic_bezier(' + [ease[1].x, ease[1].y, ease[2].x, ease[2].y].join(', ') + ')';
var ease_reversed_css_string = 'cubic_bezier(' + [ease_reversed[1].x, ease_reversed[1].y, ease_reversed[2].x, ease_reversed[2].y].join(', ') + ')';
console.log('ease_css_string : ', ease_css_string)
console.log('ease_reversed_css_string : ', ease_reversed_css_string)
.anim {
width: 240px;
height: 200px;
overflow: hidden;
}
.anim a {
display: block;
position: relative;
width: 100%;
height: 100%;
}
.anim img {
z-index: 1;
position: absolute;
width: 240px;
top: 0;
left: 0;
}
.anim span {
display: block;
height: 100%;
width: 50%;
position: absolute;
z-index: 2;
overflow: hidden;
transition: all cubic-bezier(0, 1.69, 0.71, 0) 0.5s; /* added */
}
.anim .left {
left: 0px;
}
.anim .right {
right: 0px;
}
.anim .right img {
margin-left: -100%;
}
.anim a:hover > span {
transition: all cubic-bezier(0.29, 1.01, 1, -0.68) 0.5s; /* added */
}
.anim a:hover > .left {
left: -100%;
}
.anim a:hover > .right {
right: -100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<article class="anim">
<a href="#foo">
<img src="https://dummyimage.com/240x200/ff9900/fff.png&text=TADA" alt="foo">
<span class="left">
<img src="https://dummyimage.com/240x200/121212/fff&text=hey+you" alt="left">
</span>
<span class="right">
<img src="https://dummyimage.com/240x200/000/fff&text=hey+you" alt="right">
</span>
</a>
</article>

Related

Lazy Load Iframe Only After Modal is Triggered

Issue: I cannot natively lazy load an iframe on a modal window. When I check the waterfall in Inspect element > Network, the iframe loads immediately.
Goal: The iframe should load ONLY when modal is triggered. Can you help please?
I don't use dependencies like jQuery, but javascript is OK if it provides a solution. I tried the native and several other lazy loading solutions with no success.
My code:
.modal-state {
display: none
}
.modal-state:checked+.modal {
opacity: 1;
visibility: visible
}
.modal-state:checked+.modal .modal__inner {
top: 0
}
.modal {
opacity: 0;
visibility: hidden;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
text-align: left;
background: #f2f2f2;
transition: opacity .01s ease;
z-index: 7;
display: flex;
flex-direction: column;
height: 100vh;
overflow-y: auto
}
.modal__bg {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
cursor: pointer
}
.modal__inner {
transition: top .01s ease;
height: max-content;
position: relative;
max-width: 1200px;
width: -webkit-fill-available;
margin: auto;
padding: 1em 1em;
}
.modal__close {
position: absolute;
right: 1.1em;
top: 0;
/*-.3em*/
width: 1.1em;
height: 1.1em;
cursor: pointer;
z-index: 1
}
.modal__close:after,
.modal__close:before {
content: '';
position: absolute;
width: 2px;
height: 1.5em;
background: #999;
display: block;
transform: rotate(45deg);
left: 50%;
margin: -3px 0 0 -1px;
top: 0
}
.modal__close:hover:after,
.modal__close:hover:before {
background: #000
}
.modal__close:before {
transform: rotate(-45deg)
}
.container-pay {
position: relative;
width: 100%;
height: 200px;
overflow: hidden;
padding-top: 56.25%;
/* 16:9 Aspect Ratio */
}
.responsive-iframe-pay {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
width: 100%;
height: 100%;
border: none;
}
<p>In our <label for="modal-store">merchandize store</label>.</p>
<input class="modal-state" id="modal-store" type="checkbox" />
<div class="modal">
<label class="modal__bg" for="modal-store"></label>
<div class="modal__inner"><label class="modal__close" for="modal-store"></label>
<p>
<div class="container-pay">
<iframe loading="lazy" class="responsive-iframe-pay" src="https://store.website.com"></iframe>
</div>
</p>
</div>
</div>
iFrames load when they're encountered in the rendered HTML DOM. Since your iFrame exists as part of the initially loaded code, it will load when the parser hits that portion of the HTML.
You can defeat that initial load action by either adding the iFrame to the DOM or modifying the URL right before the modal window is opened.
Modifying the <iframe src="" /> is likely the best solution since it will keep the loaded content for any additional times the modal is displayed.
You can do this by adding an "onchange" event to the checkbox which will run the javascript to change the src attribute of the iframe.
Make sure to change the src on the iframe to an empty string"" so it doesn't try to load anything right away.
var toggle = document.getElementById('modal-store');
var frame = document.getElementById('the-iframe');
var urlTarg = "https://google.com";
// put the page you want to load in the frame in the urlTarg
function toggleModal() {
if(toggle.checked && frame.src != urlTarg){
frame.src = urlTarg;
}
}
.modal-state {
display: none
}
.modal-state:checked+.modal {
opacity: 1;
visibility: visible
}
.modal-state:checked+.modal .modal__inner {
top: 0
}
.modal {
opacity: 0;
visibility: hidden;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
text-align: left;
background: #f2f2f2;
transition: opacity .01s ease;
z-index: 7;
display: flex;
flex-direction: column;
height: 100vh;
overflow-y: auto
}
.modal__bg {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
cursor: pointer
}
.modal__inner {
transition: top .01s ease;
height: max-content;
position: relative;
max-width: 1200px;
width: -webkit-fill-available;
margin: auto;
padding: 1em 1em;
}
.modal__close {
position: absolute;
right: 1.1em;
top: 0;
/*-.3em*/
width: 1.1em;
height: 1.1em;
cursor: pointer;
z-index: 1
}
.modal__close:after,
.modal__close:before {
content: '';
position: absolute;
width: 2px;
height: 1.5em;
background: #999;
display: block;
transform: rotate(45deg);
left: 50%;
margin: -3px 0 0 -1px;
top: 0
}
.modal__close:hover:after,
.modal__close:hover:before {
background: #000
}
.modal__close:before {
transform: rotate(-45deg)
}
.container-pay {
position: relative;
width: 100%;
height: 200px;
overflow: hidden;
padding-top: 56.25%;
/* 16:9 Aspect Ratio */
}
.responsive-iframe-pay {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
width: 100%;
height: 100%;
border: none;
}
<p>In our <label for="modal-store">merchandize store</label>.</p>
<input class="modal-state" id="modal-store" type="checkbox" onchange="toggleModal" />
<div class="modal">
<label class="modal__bg" for="modal-store"></label>
<div class="modal__inner"><label class="modal__close" for="modal-store"></label>
<p>
<div class="container-pay">
<iframe id="the-iframe" loading="lazy" class="responsive-iframe-pay" src=""></iframe>
</div>
</p>
</div>
</div>
Edit: Apply to multiple different buttons showing content in the same iframe
You can apply this to multiple iframe targets on the same page or the same site with a few modifications. This assumes that:
You'll re-use the modal window AND iframe HTML code.
That you want to display a different URL each time the modal is opened
The modal window HTML exists on each HTML page that you want to have modal + iframe.
You would modify the Javascript to something like this:
// you'll pass all the required values to the function
function toggleModal(checkbox, frameTarg, urlTarg) {
var frame = document.getElementById(frameTarg);
if(checkbox.checked && frame.src != urlTarg){
frame.src = urlTarg;
}
}
You will only need the javascript once per parent page since the same function can work for any combo of checkboxes, iframes, and URLs
And the checkbox HTML to:
(Note: the same function could be applied to a button, link, etc)
<input class="modal-state"
id="modal-store"
type="checkbox"
onchange="toggleModal(this, 'the-iframe', 'https://theurltoloadinframe.com')"
/>
<input class="modal-state2"
id="modal-store"
type="checkbox"
onchange="toggleModal(this, 'iframe2', 'https://someotherurltoload.com')"
/>
Basically, the function expects you to pass in:
The current checkbox - (denoted by this)
The ID of the iframe you want to change make sure its a string with quotes
The URL you want to load in the iFrame also in a string

LESS/ CSS : Writing a static text on image

I have following image as following,
How can i write text on image above and achieve the outcome as the following?
Try this, I hope it'll help you out. Thanks
.wrapper {
position: relative;
}
.wrapper img {
width: 100%;
}
.wrapper label {
color: #fff;
font-size: 24px;
position: absolute;
}
.wrapper #id1 {
left: 20px;
top: 20px;
}
.wrapper #id2 {
right: 20px;
top: 20px;
}
.wrapper #id3 {
left: 20px;
bottom: 20px;
}
.wrapper #id4 {
right: 20px;
bottom: 20px;
}
.wrapper #id5 {
right: 20px;
top: 50%;
transform: rotate(90deg)
}
.wrapper #id6 {
left: 20px;
top: 50%;
transform: rotate(-90deg)
}
<div class="wrapper">
<label id="id1">Text Left!</label>
<label id="id2">Text Right!</label>
<label id="id3">Text Bottom Left!</label>
<label id="id4">Text Bottom Right!</label>
<label id="id5">Text Rotate Right!</label>
<label id="id6">Text Rotate Left!</label>
<img src="https://keyassets.timeincuk.net/inspirewp/live/wp-content/uploads/sites/12/2015/07/Depth-of-field-landscape.jpg" alt="" />
</div>
Assuming you have HTML like:
<div class="container">
<img />
<p>Foo</p>
</div>
something like this would work (you'll have to fiddle the values obviously):
.container {
position: relative;
img{ z-index: 1; // img styles here }
p { position: absolute; left: 0.5rem; top: 0.5rem; z-index: 3; transform: rotate(90deg) }
}
Step by step:
Position the text absolutely
Rotate it 90 degrees
Set a Z-index higher than the image
Position the text correctly on the image
Profit ...

Rotate Image From Its Bottom

I am trying to go for a needle effect and I cannot seem to get the needle to rotate from its bottom. I want the bottom of the image to stay fixed in its position and just the top of the needle to move along the half circle. This is was I have so far. Any suggestions on how to get this effect to work?
$(document).ready(function() {
setTimeout(function() {
$(".needle").css("transform", "rotate(0deg)");
}, 1000)
})
figure {
position: relative;
display: inline-block;
}
.graph {
width: 300px;
}
.needle {
position: absolute;
width: 160px;
left: 15px;
bottom: -28px;
transform: rotate(-171deg);
-webkit-transform: rotate(-171deg);
transition: all 7s;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<figure>
<img src="http://1.bp.blogspot.com/-XqCc5ql8Xqc/T6DuArRFB0I/AAAAAAAAADA/IK6fKAjzkOc/s1600/Finished+semi-circle+3.png" class="graph" />
<img src="http://www.kiteinnovation.com/wp-content/themes/naked-wordpress-master/images/arrow.png" class="needle" />
</figure>
Use css transform-origin property
$(document).ready(function() {
setTimeout(function() {
$(".needle").css("transform", "rotate(0deg)");
}, 1000)
})
figure {
position: relative;
display: inline-block;
}
.graph {
width: 300px;
}
.needle {
position: absolute;
width: 160px;
right: 15px;
bottom: -28px;
transform: rotate(-171deg);
transform-origin: left;
-webkit-transform: rotate(-171deg);
transition: all 7s;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<figure>
<img src="http://1.bp.blogspot.com/-XqCc5ql8Xqc/T6DuArRFB0I/AAAAAAAAADA/IK6fKAjzkOc/s1600/Finished+semi-circle+3.png" class="graph" />
<img src="http://www.kiteinnovation.com/wp-content/themes/naked-wordpress-master/images/arrow.png" class="needle" />
</figure>

How to create an animation that would be triggered by click

How can I achieve the following effect: when a user clicks a link he'll see the content of the current page slowly move up and away then new content of the next page appear instead. I'd prefer to use only CSS if possible.
A CSS-only solution can be achieved with transitions. Here's the example and the code is as follows:
CSS
.message {
background:#181818;
color:#FFF;
position: absolute;
top: -250px;
left: 0;
width: 100%;
height: 250px;
padding: 20px;
transition: top 300ms cubic-bezier(0.17, 0.04, 0.03, 0.94);
overflow: hidden;
box-sizing: border-box;
}
.message h1 {
color:#FFF;
}
#toggle {
position:absolute;
appearance:none;
cursor:pointer;
left:-100%;
top:-100%;
}
#toggle + label {
position:absolute;
cursor:pointer;
padding:10px;
background: #26ae90;
width: 100px;
border-radius: 3px;
padding: 8px 10px;
color: #FFF;
line-height:20px;
font-size:12px;
text-align:center;
-webkit-font-smoothing: antialiased;
cursor: pointer;
margin:20px 50px;
transition:all 500ms ease;
}
#toggle + label:after {
content:"Open"
}
.container {
transition: margin 300ms cubic-bezier(0.17, 0.04, 0.03, 0.94);
padding:5em 3em;
}
#toggle:checked ~ .message {
top: 0;
}
#toggle:checked ~ .container {
margin-top: 250px;
}
#toggle:checked + label {
background:#dd6149;
}
#toggle:checked + label:after {
content:"Close"
}
HTML
<input type="checkbox" name="toggle" id="toggle" />
<label for="toggle"></label>
<div class="container">
<h1> Click the Open button to see hidden mesage.</h1>
</div>
<div class="message">
<h1> hello, I'm a hidden message. You found it.</h1>
</div>
Here's one way to do it:
HTML Include all your pages in a <main> div (or else)
<body>
<main>
some link
</main>
</body>
CSS make the <main> in fixed position, and the size of the window
main {
position: fixed; top: 0; left: 0;
width: 100%; height: 100%;
}
jQuery
$('a').click(function(event){ // when click on any link <a>
event.preventDefault(); // prevents <a> natural behavior (sending you somewhere)
var URL = $(this).attr('href'); // stores the <a> href attribute
$('main').animate({top:'-=100%'},1000,function(){ // moves up <main> and when it's gone…
window.location.href = URL; // sends you where you belong
});
});
Cheers!
$('a').click(function(event){
event.preventDefault();
var URL = $(this).attr('href');
$('main').animate({top:'-=100%'},1000,function(){
window.location.href = URL;
});
});
main {
position: fixed; top: 0; left: 0;
width: 100%; height: 100%;
background-color: #DDD;
padding: 10px;
box-sizing: border-box;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<main>
some link
</main>

How to close CSS3 Lightbox by clicking outside of the current image?

I try to close lightbox by clicking outside of the current image, but I don't how to do.
I just have a link "Back" in order to close this lightbox...
I use only CSS3, maybe Script is the solution, thanks for your help.
Here's a short CSS :
/*thumbnails*/
.album {
position: relative;
width:1200px;
height:auto;
float: left;
}
/*fullscreen*/
.overlay {
position: fixed;
left: 258px;
top: 0px;
padding: 0px;
overflow: hidden;
}
/*close fullscreen, back to thumbnails*/
.close {
position: absolute;
top: 50px;
left: 50%;
}
HTML
<ul class="album">
<li>
<img src="images/thumbs/example.jpg>
<div class="overlay" id="example">
<img src="images/full/example.jpg" />
BACK
</div>
</li>
</ul>
You could use a pseudo-element on the .close element and position that between the lightbox and the image using z-index.
.overlay:target .close:before {
position: fixed;
content: '';
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 10;
}
.overlay { z-index: 5; }
.lightbox image { z-index: 15; }

Resources