CSS transform scale breaks image overlay - css

HTML Markup:
<div class="item">
<a href="url">
<img src="photo.jpg" />
</a>
</div>
This CSS zooms the image on hover:
.item a img {
transition: all 0.2s linear;
}
.item a:hover img {
transform: scale(1.05);
}
This CSS adds an overlay on hover:
.item a {
position: relative;
}
.item a:before {
content: "";
display: block;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: none no-repeat center center;
transition: all .3s linear;
}
.item a:hover:before {
background:rgba(0,0,0, 0.5) url('img/zoom.png') no-repeat center center;
}
Each one works fine by itself. However, when I try to use both bits of CSS, only the zoom works; the overlay is broken.
Simply, how can I write the CSS to combine these two effects?

You could try adding z-index:1 to the the absolute positioned element.
.item a img {
transition: all 0.2s linear;
}
.item a:hover img {
transform: scale(1.05);
vertical-align: top;
}
.item a {
position: relative;
display: inline-block;
}
.item a:before {
content: "";
display: block;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: none no-repeat center center;
transition: all .3s linear;
z-index: 1;
}
.item a:hover:before {
background: rgba(0, 0, 0, 0.5) url('//dummyimage.com/50') no-repeat center center;
}
<div class="item">
<a href="url">
<img src="//dummyimage.com/200" />
</a>
</div>

Related

Animate a line under a hyperlink using only CSS [duplicate]

This question already has answers here:
How to animate underline from left to right?
(3 answers)
Closed 2 years ago.
I'm trying to animate a line in a particular way (see the following gif for a visual representation) under a hyperlink using the following code structure:
.navlink {
position: relative;
color: white;
}
.navlink a {
display: inline-block;
margin: 0;
text-decoration: none;
}
.navlink a::after {
display: block;
content: '';
border-bottom: solid 0.2vmax red;
transform: scaleX(0);
transition: transform 250ms ease-in-out;
}
.navlink a:hover::after {
animation: scaleup 3s forwards;
}
#keyframes scaleup {
50% {
transform: scaleX(1)
}
100% {
transform-origin: 50% 0, scaleX(0)
}
}
.navlink a:after {
transform-origin: 0% 50%;
}
<nav id="main-nav">
<div class="main-nav-content">
<div class="navlink">
<a href="/aboutus.html">
<span>About Us</span>
</a>
</div>
</div>
</nav>
I can get the line to animate in one direction OK but having problem with the second half of the animation. Can anyone help me understand a better way to do this using only CSS?
You might do it using translateX, so you wouldn't need to switch transform-origin:
.navlink {
position: relative;
color: white;
}
.navlink a {
display: inline-block;
margin: 0;
overflow: hidden;
text-decoration: none;
}
.navlink a:after {
display: block;
content: '';
border-bottom: solid 0.2vmax;
transform: translate(-110%);
transition: transform 250ms ease-in-out;
}
.navlink a:hover:after {
animation: scaleup 3s forwards;
}
#keyframes scaleup {
50% {
transform: translate(110%)
}
}
.navlink a:after {
transform-origin: 0% 50%;
}
<nav id="main-nav">
<div class="main-nav-content">
<div class="navlink">
<a href="/aboutus.html">
<span>About Us</span>
</a>
</div>
</div>
</nav>
Used different approach, pseudo element of parents width floats from left to right and back
.navlink {
position: relative;
color: white;
}
.navlink a {
display: inline-block;
margin: 0;
text-decoration: none;
position: relative;
overflow: hidden;
padding-bottom: 5px;
}
.navlink span::after {
position: absolute;
left: -100%;
display: block;
content: ' ';
border-bottom: solid 0.2vmax red;
height: 2px;
width: 100%;
transition: left 500ms linear;
left: -100%;
}
.navlink a:hover span::after {
transition: left 500ms linear;
left: 100%;
}
<nav id="main-nav">
<div class="main-nav-content">
<div class="navlink">
<a href="/aboutus.html">
<span>About Us</span>
</a>
</div>
</div>
</nav>

When I put the toggleclassList('open) on my .sidebar class the transition properties won't work on just the .sidebar Why won't it work?

Here is my code and the javascript. I've tried deleting the width off the original class .sidebar but it doesn't work. The nav-links come in smooth but the .sidebar background snaps into place. It doesn't smoothly transition with the rest of the elements but when the browser resizes the transitions take place. It's just that when I click on the event action it snaps into place.
var toggler = document.getElementsByClassName('toggler')[0]
var sideBar = document.getElementsByClassName('sidebar')[0]
toggler.addEventListener('click', function openSideBar() {
sideBar.classList.toggle('open')
});
.menu {
height: 100vh;
width: 100%;
background: #eeefcf;
}
h1{
display: flex;
justify-content: center;
align-items: center;
}
.menu-toggler{
position: absolute;
top: 0;
left: 0;
height: 50px;
width: 50px;
background: purple;
z-index: 1;
transition: ease-in .4s;
}
.toggler {
position: absolute;
top: 0;
left: 0;
width: 30px;
height: 30px;
cursor: pointer;
z-index: 2;
opacity: 0;
transition: all ease-in .9s;
}
.sidebar {
position: absolute;
top: 0;
left: 0;
height: 100vh;
width: -200px;
background: rgb(45, 125, 218);
transition: ease 0.9s;
}
.nav-links {
position: absolute;
top: 100px;
left: -70px;
display: flex;
flex-direction: column;
transition: ease-in .4s;
}
.nav-link {
margin: 15px 0px;
}
.nav-link a {
color: white;
text-decoration: none;
}
.open {
width: 250px;
transition: ease 2s all;
}
.open .nav-links {
left: 70px;
transition: ease-in all .5s;
}
<div class="menu">
<h1>Move It over</h1>
<div class="menu-toggler">
<input type="checkbox" class="toggler">
</div>
<aside class="sidebar">
<ul class="nav-links">
<li class="nav-link">Home</li>
<li class="nav-link">About</li>
<li class="nav-link">Services</li>
<li class="nav-link">Contact</li>
</ul>
</div>
</aside>
You have set the width of .sidebar to -200px, which is an invalid value.
If you set it to 0px it will animate.

Weird CSS image hover

I'm creating a hover effect on an image with SCSS on a WordPress site (see gif: https://gyazo.com/1a35247e40d74b5fc756d508de4231eb)
As you see the image gets a "distorted" after hovering over it, maybe the ease-in property is wrong, or I'm not doing the hover effect properly. I'm wondering what I'm doing wrong in the code when it behaves like this.
This is the code that is working:
(left out some SCSS because it was so wast but the & is used to use parent class)
Edit: The HTML & SCSS
<div class="project_container">
<div class="project_content">
Test event
<br>
2018
</div>
<img src="http://testsite.com/wp-content/uploads/2018/12/img.jpg" class="attachment-full aligncenter">
</div>
-
&_container {
position: relative;
height: 300px;
width: 300px;
&:hover {
& > img {
opacity: .2;
}
& > .project_content {
opacity: 1;
}
}
& img {
position: absolute;
width: 100%;
height: 100%;
/*
object-fit: none;
background-size: cover;
background-position: 50% 50%;
background-repeat: no-repeat;
*/
// Hover tranisiton
transition: opacity .5s;
}
}
&_content {
opacity: 0;
transition: opacity .5s;
// Center Position
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: $purple;
z-index: 2;
text-transform: uppercase;
font-size: 20px;
font-weight: 500;
text-align: center;
}
}
So using :hover; on the &_container gives the project_content: opacity: 1;. Then it also blurs the background image with the opacity: .2;, and the effect is achieved with a transition;
Thank you!
I rewrote everything with the hover effect so now I use an overlay class which has opacity: 0; on it (and a transition that takes care of the effect on :hover)
This is a simple version of the HTML:
<div class="project_container">
<div class="project_content">
<p>Content</p>
</div>
<img src="#" alt="test">
<div class="project_overlay"></div>
</div>
and the simplified SCSS:
.project {
&_container {
position: relative;
height: 300px;
width: 300px;
&:hover .project_overlay,
&:hover .project_content {
opacity: 1;
transition: opacity .5s;
}
}
& img {
position: absolute;
width: 100%;
height: 100%;
}
&_overlay {
background-color: rgba(255, 255, 255, .5);
position: absolute;
height: 100%;
width: 100%;
opacity: 0;
transition: opacity .5s;
}
}

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;
}

Scrollable / hoverable CSS tooltip with psuedo elements

I have a hoverable CSS-only tooltip that works well in most instances, but I want to add a scrollbar when it exceeds a max-height. If I add max-height: 50px; overflow-y: auto, my pseudo elements :before and :after will disappear due to the overflow property.
See: http://jsfiddle.net/accelerate/24xwru1n/
Is there a way to add a scrollbar to my tooltip while maintaining my pseudo elements? Or will I have to live without my pseudo elements to make it work?
I'm afraid you have to add a wrapper when you want a scroll in hover and apply to this the css as in tooltip-text:
HTML
<div class="tooltip tooltip-scroll">Hover over me for scrollbar
<div class="wrapper">
<span class="tooltip-text">Hello there<br/>abc<br/>def<br/>ghi<br/>jkl<br/></span>
</div>
</div>
.wrapper{
position:relative;
}
.tooltip {
transform: none;
margin: 50px;
}
.tooltip:hover > .tooltip-text, .tooltip:hover > .wrapper {
pointer-events: auto;
opacity: 1.0;
}
.tooltip > .tooltip-text, .tooltip >.wrapper {
display: block;
position: absolute;
z-index: 6000;
overflow: visible;
padding: 5px 8px;
margin-top: 10px;
line-height: 16px;
border-radius: 4px;
text-align: left;
color: #fff;
background: #000;
pointer-events: none;
opacity: 0.0;
-o-transition: all 0.3s ease-out;
-ms-transition: all 0.3s ease-out;
-moz-transition: all 0.3s ease-out;
-webkit-transition: all 0.3s ease-out;
transition: all 0.3s ease-out;
}
/* Arrow */
.tooltip > .tooltip-text:before, .tooltip > .wrapper:before {
display: inline;
top: -5px;
content: "";
position: absolute;
border: solid;
border-color: rgba(0, 0, 0, 1) transparent;
border-width: 0 .5em .5em .5em;
z-index: 6000;
left: 20px;
}
/* Invisible area so you can hover over tooltip */
.tooltip > .tooltip-text:after, .tooltip > .wrapper:after {
top: -20px;
content: " ";
display: block;
height: 20px;
position: absolute;
width: 60px;
left: 20px;
}
.wrapper > .tooltip-text {
overflow-y: auto;
max-height: 40px;
display: block;
}
<div class="tooltip">Hover over me for no scrollbar<span class="tooltip-text">Hello there<p/>abc<br/>def<br/>ghi<br/>jkl<br/></span></div>
<p/><p/><p/>
<div class="tooltip tooltip-scroll">Hover over me for scrollbar
<div class="wrapper">
<span class="tooltip-text">Hello there<br/>abc<br/>def<br/>ghi<br/>jkl<br/></span>
</div>
</div>

Resources