Lightbox with transition - css

I wanted to do a smooth transition of a fullscreen lightbox, my actual code is
<a href="#_" class="lightbox" id="img1">
<img src="images/photo.jpg">
</a>
And my style:
.lightbox {
display: none;
position: fixed;
z-index: 999;
width: 100%;
height: 100%;
text-align: center;
top: 0;
left: 0;
background: rgba(0,0,0,0.8);
}
.lightbox img {
max-width: 90%;
max-height: 80%;
margin-top: 2%;
}
.lightbox:target {
outline: none;
display: block;
transition:all 1s;
}
It's really simple, but transition:all seems to don't work with display block/none... Any idea?

display block/none does not allow any transition to run.
You must use visibility and opacity(for cross browser support).
So your code would look like this:
.lightbox {
display: block;
visibility: hidden;
opacity: 0;
position: fixed;
z-index: 999;
width: 100%;
height: 100%;
text-align: center;
top: 0;
left: 0;
background: rgba(0,0,0,0.8);
transition:all 1s;
}
.lightbox img {
max-width: 90%;
max-height: 80%;
margin-top: 2%;
}
.lightbox:target {
outline: none;
visibility: visible;
opacity: 1;
}

If I recall correctly, transition doesn't work with display. It's not time to give up hope, however! There's opacity! Use opacity: 0 and opacity: 1 in combination with display: none and display: block. Also, your transition is on the .lightbox:target, not the .lightbox. When it's on .lightbox:target, it's too late to start the transition.
Corrected CSS:
.lightbox {
display: none;
opacity: 1;
position: fixed;
z-index: 999;
width: 100%;
height: 100%;
text-align: center;
top: 0;
left: 0;
background: rgba(0,0,0,0.8);
transition: opacity 1s;
}
.lightbox img {
max-width: 90%;
max-height: 80%;
margin-top: 2%;
}
.lightbox:target {
outline: none;
display: block;
opacity: 1;
}

you can't transition display since it has no interim values, it is either displayed or hidden (of course there are many different ways of display)
It can't be 25% displayed
in order to create fade in transition with css only, you'll need to use the opacity attribute
function toggle(){
var element = document.getElementById("element");
if(element.className==""){
element.className = "out";
} else {
element.className = "";
}
}
#element{
transition: all 1s;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,0.5);
opacity: 1;
}
#element.out{
opacity:0
}
button{z-index: 2; position: relative}
<div id="element">Element</div>
<br />
<button onclick="toggle()">click to fade in/out</button>

Related

Add style when hover animation is finished

Is it possible to add another style when the hover animation is completely finished?
With the default hover all styles get applied at the same time.
So changing from display: none to display: block will override any transformation because the element will just appear out of nowhere.
In the following example something like this would be helpful, because right now you can trigger the hover effect from outside of the actual "hover area".
.grid_content {
padding: 15px;
position: absolute;
top: 0;
left: 0;
width: 300px;
height: 300px;
background: salmon;
}
.grid_hover {
width: calc(100% - 30px);
height: calc(100% - 30px);
opacity: 0;
transition: all 0.5s;
transition-timing-function: cubic-bezier(1, 0.09, 0.37, 0.93);
position: absolute;
z-index: 5;
}
.bottom_left {
transform-origin: bottom left;
transform: rotate(90deg);
}
.text_overlay {
top: 50%;
width: 70%;
max-height: 80%;
margin: 0 15%;
text-align: center;
z-index: 4;
position: absolute;
}
.background_overlay {
background: #ffffff;
width: 100%;
height: 100%;
bottom: 0;
opacity: 0.95;
z-index: 1;
position: absolute;
}
.box_overlay {
border: 1.5px solid #000000;
width: calc(100% - 2vw);
height: calc(100% - 2vw);
margin: 1vw;
float: left;
z-index: 2;
position: relative;
box-sizing: border-box;
}
.grid_content:hover > .grid_hover {
opacity: 1;
transform: rotate(0);
}
.hover_here {
position: absolute;
top: 350px;
}
<div class="grid_content">
<div class="grid_hover bottom_left">
<div class="text_overlay"> <p>Lorem Ipsum</p></div>
<div class="background_overlay"></div>
</div>
</div>
<p class="hover_here">
Hover somewhere around here to see the "bug"
</p>
I also tried to just set grid_hover to pointer-events: none; that worked, but I can't use it because inside that div will be a button that has to be clickable.
My idea or what I want to achieve is something like this:
.grid_hover is set to display: none at the beginning
hovering on .grid_content will set it to display: block and after that happened the animation should run
Is there a way to make this work in just css without javascript?

CSS transition not smooth for one element on hover, but is smooth when mouse moved away

I've got the following CSS and HTML. The problem is, that when the mouse is moved over the button, the red rectangle flashes to the center instead of smoothly moving to the center. It is strange because when the mouse is moved away from the button, it moves back slowly. How can I make the red rectangle move to the center smooth?
.btn {
position: relative;
display: inline-block;
padding: 30px 45px;
margin: 80px;
cursor: pointer;
}
.btn .rect {
transition: all 0.5s linear;
height: 100%;
width: 100%;
opacity: 0.3;
position: absolute;
}
.btn .top-left {
top: -10px;
left: -10px;
}
.btn .bottom-right {
bottom: -10px;
right: -10px;
}
.red-translucent {
background-color: red;
}
.blue-translucent {
background-color: blue;
}
.btn-text {
z-index: 99999;
position: relative;
font-family: Arial;
}
.btn:hover .rect {
top: 0;
bottom: 0;
left: 0;
right: 0;
}
<div class='btn'>
<span class='btn-text'>button</span>
<div class='rect top-left blue-translucent'></div>
<div class='rect bottom-right red-translucent'></div>
</div>
For some reason, it didn't work with bottom: -10px and right: -10px. I'm not sure if this has to do with my code or if this is a browser problem, but the easy fix is to use the top and left properties instead:
.btn {
position: relative;
display: inline-block;
padding: 30px 45px;
margin: 80px;
cursor: pointer;
}
.btn .rect {
transition: all 0.5s linear;
height: 100%;
width: 100%;
opacity: 0.3;
position: absolute;
}
.btn .top-left {
top: -10px;
left: -10px;
}
.btn .bottom-right {
top: 10px;
left: 10px;
}
.red-translucent {
background-color: red;
}
.blue-translucent {
background-color: blue;
}
.btn-text {
z-index: 99999;
position: relative;
font-family: Arial;
}
.btn:hover .rect {
top: 0;
bottom: 0;
left: 0;
right: 0;
}
<div class='btn'>
<span class='btn-text'>button</span>
<div class='rect top-left blue-translucent'></div>
<div class='rect bottom-right red-translucent'></div>
</div>
.red-translucent {
background-color: red;
top: 10px;
left: 10px;
}
Use transform instead of top, left, bottom, right like this:
.btn {
position: relative;
display: flex;
padding: 30px 45px;
margin: 80px;
cursor: pointer;
justify-content: center;
align-items: center;
width: 50px;
height: 50px;
}
.btn .rect {
transition: all 0.5s linear;
height: 100%;
width: 100%;
opacity: 0.3;
position: absolute;
}
.btn .top-left {
transform: translate(-10px, -10px);
}
.btn .bottom-right {
transform: translate(10px, 10px);
}
.red-translucent {
background-color: red;
}
.blue-translucent {
background-color: blue;
}
.btn-text {
z-index: 99999;
position: relative;
font-family: Arial;
}
.btn:hover .rect {
transform: translate(0px, 0px);
}
This will work smoothly on either the move-in or move-out of the pointer.

How to hover parent & have child respond to keyframe animation

I am trying to write code that mimics this animation as much as possible.
I have been going over keyframe animations & I think that they can be used to do what I need them to do.
I effectively want to have three things happen when the user hovers over the parent element. The first is the color
on the right side of the element will change dynamically (as in the picture & as in the example code), the
icon will animate into the picture & then the text will then animate.
I am new to programming & I am looking for some direction.
Example of finished product: https://imgur.com/a/bxV1V1B
DEMO
.wrapper {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
a {
display: block;
width: 200px;
height: 40px;
line-height: 40px;
font-size: 18px;
font-family: sans-serif;
text-decoration: none;
color: #333;
border: 2px solid #333;
letter-spacing: 2px;
text-align: center;
position: relative;
transition: all .35s;
}
a span {
position: relative;
z-index: 2;
}
a:after {
position: absolute;
content: "";
top: 0;
right: 0;
width: 0;
height: 100%;
background: green;
transition: all .35s;
}
a:hover:after {
width: 15%;
}
<div class="wrapper">
<span>Hover Me!</span>
</div>
Here you go. I made a CSS animation for you which will rotate and translate a new i that I have added into the HTML. I used font awesome for the check with the circle around it. Take a look:
.wrapper {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
a {
display: block;
width: 200px;
height: 40px;
line-height: 40px;
font-size: 18px;
font-family: sans-serif;
text-decoration: none;
color: #333;
border: 2px solid #333;
letter-spacing: 2px;
text-align: center;
position: relative;
transition: all .35s;
}
a span {
position: relative;
z-index: 2;
}
a:after {
position: absolute;
content: "";
top: 0;
right: 0;
width: 0;
height: 100%;
background: green;
transition: all .35s;
visibility: hidden;
}
a:hover:after {
width: 15%;
visibility: visible;
}
#check {
right: 2px;
top: 8px;
position: absolute;
display: none;
z-index: 3;
transition: right .35s;
}
a:hover #check {
animation:spin .35s linear;
display: block;
}
#keyframes spin {
0% {
transform: translate(25px) rotate(0deg);
}
100% {
transform: translate(0px) rotate(360deg);
}
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<div class="wrapper">
<span>Hover Me!</span><i id="check"style="font-size:22px; color:lightgrey" class="fa fa-check-circle"></i>
</div>

Using pseudo selector :after to create an overlay over an image -- not taking the full height

Trying to create an overlay effect on hover, using :after, but it's not taking the full height.
It will work if I give a:after a fixed height in pixels. But I was hoping not to set a static height so it can be applied to images of all sizes.
Thanks in advance!
* {
margin: 0;
padding: 0;
}
.container {
width: 500px;
height: 500px;
}
a {
position: relative;
height: 100%;
width: 100%;
}
a:after {
content: '';
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
background: rgba(0,0,0,0.4);
opacity: 0;
transition: all .4s;
-webkit-transition: all .4s;
}
a:hover:after {
opacity: 1;
}
<div class="container">
<a href="#">
<img src="https://vignette.wikia.nocookie.net/dragonballfanon/images/7/70/Random.png/revision/latest?cb=20161221030547">
</a>
</div>
I removed width: 100%; and height: 100% from a and added display: inline-block; By default a tags have a display value of inline which ignores width and height values so they weren't doing anything before anyway. display: inline-block; is probably what you wanted to go with from the beginning.
* {
margin: 0;
padding: 0;
}
.container {
width: 500px;
height: 500px;
}
a {
position: relative;
display: inline-block;
}
a::after {
content: '';
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
background: rgba(0,0,0,0.4);
opacity: 0;
transition: all .4s;
-webkit-transition: all .4s;
}
a:hover::after {
opacity: 1;
}
<div class="container">
<a href="#">
<img src="https://vignette.wikia.nocookie.net/dragonballfanon/images/7/70/Random.png/revision/latest?cb=20161221030547">
</a>
</div>
<a> tag default display is display: inline.
To achieve the desired result you should display your <a> as inline-block. See docs: https://www.w3schools.com/css/css_inline-block.asp
a {
position: relative;
display: inline-block;
}
* {
margin: 0;
padding: 0;
}
.container {
width: 500px;
height: 500px;
}
a {
position: relative;
display: inline-block;
}
a:after {
content: '';
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
background: rgba(0,0,0,0.4);
opacity: 0;
transition: all .4s;
-webkit-transition: all .4s;
}
a:hover:after {
opacity: 1;
}
<div class="container">
<a href="#">
<img src="https://vignette.wikia.nocookie.net/dragonballfanon/images/7/70/Random.png/revision/latest?cb=20161221030547">
</a>
</div>
Your <a> element is not getting the full height, because by default is displayed as inline.
You can set display:inline-block; to change the default render behavior... or you can play with the position property.
Setting the container to position:relative, and the a and the a:after to position:absolute, will let you force the a:after to adjust to top:0px; and bottom:0px; covering the full height.
With that changes, everything works as expected.
Check it.
.container {
width: 500px;
height: 500px;
position: relative;
}
a {
position: absolute;
}
a:after {
content: '';
position: absolute;
width: 100%;
top: 0;
bottom: 0px;
background: rgba(0,0,0,0.4);
transition: all .4s;
-webkit-transition: all .4s;
opacity:0.2;
}
a:hover:after {
opacity: 1;
}
<div class="container">
<a href="#">
<img src="https://vignette.wikia.nocookie.net/dragonballfanon/images/7/70/Random.png/revision/latest?cb=20161221030547">
</a>
</div>
add a display block:
a {
position: relative;
height: 100%;
width: 100%;
display:block;
}

How to create these shapes using CSS3

I am creating a responsive website. I want to create below shape in CSS3. using ul li.
you could use a pseudo element, and have overflow:hidden set on the parent container.
html {
margin: 0;
padding: 0;
background: #222;
}
.wrap {
position: relative;
width: 100%;
height: 200px;
background: #222;
overflow: hidden;
}
.wrap div {
display: inline-block;
position: relative;
height: 100%;
width: 22%;
margin-left: 2%;
background: lightblue;
transition: all 0.6s;
line-height:200px;
text-align:center;
}
.wrap:before {
content: "";
position: absolute;
bottom: -25%;
left: 0;
height: 50%;
width: 100%;
border-radius: 50%;
background: #222;
z-index: 8;
}
div.withImage {
background: url(http://placekitten.com/g/300/300);
background-size: 100% 100%;
}
.wrap div:hover:before {
opacity: 1;
}
.wrap div:before {
content: "";
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
background: blue;
opacity: 0;
transition: all 0.6s;
}
<div class="wrap">
<div>ONE</div>
<div>TWO</div>
<div>THREE</div>
<div class="withImage">FOUR</div>
</div>
NOTE
This has been done using Divs. I have left it as an exercise for the OP to alter this code for ul li.
This can also be altered to include Dynamically added elements: JSFIDDLE

Resources