Im trying to make a block with overlay hover effect (default: weak black background color - Hover: none black background) and an icon and text in the middle that stays in the same state all the way.
How do i get the icon and text to stay in the same state (no hover effect)?
Ive tried several rules to the overlay div and the icon div without any luck.
Is there any css rule that provide some kind of exclusion?
I managed to get it to work by adding them outside the divs that has overlay background, but it didnt work out well as the hover effect breaks when you hover over the icon and text.
Here is the code: https://www.w3schools.com/code/tryit.asp?filename=FEMUM4N9T30Q
<style>
.media-front-top-picture{
background-image: url("");
height:500px;
}
.media-front-top-icon{
content: url(");
width: 130px;
margin: auto;
padding-top: 200px;
opacity: 1;
}
.media-front-txt{
font-size: 22px;
letter-spacing: 8px;
color: white;
margin-top: 15px;
}
.media-front-bottom-picture{
background-image: url("h");
height:500px;
}
.media-front-bottom-icon{
content: url("");
width:130px;
margin: auto;
padding-top: 200px;
}
.media-picture-container {
position: relative;
}
.media-picture-overlay {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
transition: .5s ease;
background-color: rgba(0, 0, 0, 0.47);
}
.media-picture-overlay:hover {
opacity: 0;
cursor:pointer;
}
</style>
<div class="body-media">
<div class="media-picture-container">
<div class="media-front-top-picture" style="border-bottom:4px solid white;">
<div class="media-front-top-icon"></div>
<div class="media-front-txt">VIDEOS</div>
<div class="media-picture-overlay"></div>
</div>
</div>
<div class="media-picture-container">
<div class="media-front-bottom-picture" style="border-bottom:4px solid white;">
<div class="media-front-bottom-icon"></div>
<div class="media-front-txt">PICTURES</div>
<div class="media-picture-overlay"></div>
</div>
</div>
</div>
for the classes on your icons, add a z-index higher than a z-index you add to the overlay class. Also, make sure to make the icon classes have position:relative so the z-index is applied. Note, my example only applies this solution to one icon, its up to you to apply it elsewhere.
Example:
.media-front-top-icon{
content: url("example.com");
width: 130px;
margin: auto;
padding-top: 200px;
opacity: 1;
z-index:10;
position:relative;
}
.media-picture-overlay {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
transition: .5s ease;
background-color: rgba(0, 0, 0, 0.47);
z-index:5;
}
Related
I have an element that requires the background to be scaled, without scaling the elements within the parent. I have achieved this by using a pseudo element to define the background, and then on hover I simply scale the pseudo element. So far, so good...
The problem is, I need some of the elements to stay inline with the scaled background, despite not scaling themselves. My original plan was to simply translate them, but I quickly realised that is not possible due to scale being based on multiples, and translate being based on percentage/pixels etc...
The obvious solution is to scrap scale and instead use margin to shrink the absolutely positioned pseudo element. However, my reservation with this is that it is bad practice to transition the margin value.
Can anybody think of a way in which I can use scale, and also maintain the alignment?
Update
I want to avoid inverse/reverse scaling at all costs as it renders badly in the browser in most cases. With that in mind, I don't think this is actually possible but will leave the question open in case anyone is aware of some CSS magic.
See the following snippet as an example:
.tile {
position: relative;
width: 500px;
height: 100px;
padding: 40px;
}
.tile:hover:before {
transform: scale(.9);
}
.tile:before {
content: '';
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: #000;
z-index: -1;
transition: transform .3s ease-out;
}
h1 {
text-align: center;
color: white;
}
.tile > .button {
position: absolute;
right: 0;
top: 0;
display: inline-block;
background: red;
padding: 10px 15px;
color: white;
}
<div class="tile">
<h1>Hello World</h1>
<div class="button">Align Me</div>
</div>
Try scaling .tile itself and reverse-scaling its children:
.tile {
position: relative;
width: 500px;
padding: 40px;
background: #000;
transition: transform .3s ease-out;
}
h1 {
text-align: center;
}
.tile>* {
color: white;
transition: transform .3s ease-out;
}
.tile>.button {
position: absolute;
right: 0;
top: 0;
background: red;
padding: 10px 15px;
color: white;
transform-origin: 100% 0;
}
.tile:hover {
transform: scale(.9);
}
.tile:hover>* {
transform: scale(1.1);
}
<div class="tile">
<section>
<h1>Hello World</h1>
<p>I have an element that requires the background to be scaled, without scaling the elements within the parent. I have achieved this by using a pseudo element to define the background, and then on hover I simply scale the pseudo element. So far, so good...
The problem is, I need some of the elements to stay inline with the scaled background, despite not scaling themselves. My original plan was to simply translate them, but I quickly realised that is not possible due to scale being based on multiples,
and translate being based on percentage/pixels etc... The obvious solution is to scrap scale and instead use margin to shrink the absolutely positioned pseudo element. However, my reservation with this is that it is bad practice to transition the
margin value. Can anybody think of a way in which I can use scale, and also maintain the alignment?</p>
</section>
<div class="button">Align Me</div>
</div>
Another idea is animating top and right of .button:
html,
body {
width: 75%;
margin: 0;
padding: 0
}
* {
box-sizing: border-box
}
.tile {
position: relative;
width: 100%;
padding: 40px;
color: white;
}
.tile:hover:before {
transform: scale(.9);
}
.tile:before {
content: '';
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: #000;
z-index: -1;
transition: transform .3s ease-out;
}
h1 {
text-align: center;
}
.tile>.button {
position: absolute;
right: 0;
top: 0;
background: red;
padding: 10px 15px;
color: white;
transition: .3s ease-out;
}
.tile:hover>.button {
top: 5%;
right: 5%
}
<div class="tile">
<h1>Hello World</h1>
<p>I have an element that requires the background to be scaled, without scaling the elements within the parent. I have achieved this by using a pseudo element to define the background, and then on hover I simply scale the pseudo element. So far, so good...
The problem is, I need some of the elements to stay inline with the scaled background, despite not scaling themselves. My original plan was to simply translate them, but I quickly realised that is not possible due to scale being based on multiples,
and translate being based on percentage/pixels etc... The obvious solution is to scrap scale and instead use margin to shrink the absolutely positioned pseudo element. However, my reservation with this is that it is bad practice to transition the
margin value. Can anybody think of a way in which I can use scale, and also maintain the alignment?</p>
<div class="button">Align Me</div>
</div>
The next idea is using a bit more complex code, but doing animation of transform property only:
html,
body {
width: 75%;
}
* {
box-sizing: border-box
}
.tile {
position: relative;
width: 100%;
padding: 40px;
color: white;
}
.tile:hover:before {
transform: scale(.9);
}
.tile:before,
.tile>.button {
content: '';
position: absolute;
top: 0;
left: 0;
z-index: -1;
width:100%; height:100%;
background: #000;
transition: transform .3s ease-out;
}
h1 {
text-align: center;
}
.tile>.button {
z-index: 1;
display: flex;
align-items: flex-start;
margin: 0 -100% -100% 0;
background: transparent;
transition: .3s ease-out;
pointer-events: none;
}
.tile>.button div {
padding: 10px 15px;
background: red;
cursor: pointer;
pointer-events: all;
}
.tile>.button:before {
content: '';
flex: 1 0;
}
.tile:hover>.button {
transform: translate3d(-5%, 5%, 0);
}
<div class="tile">
<h1>Hello World</h1>
<p>I have an element that requires the background to be scaled, without scaling the elements within the parent. I have achieved this by using a pseudo element to define the background, and then on hover I simply scale the pseudo element. So far, so good...
The problem is, I need some of the elements to stay inline with the scaled background, despite not scaling themselves. My original plan was to simply translate them, but I quickly realised that is not possible due to scale being based on multiples,
and translate being based on percentage/pixels etc... The obvious solution is to scrap scale and instead use margin to shrink the absolutely positioned pseudo element. However, my reservation with this is that it is bad practice to transition the
margin value. Can anybody think of a way in which I can use scale, and also maintain the alignment?</p>
<div class="button">
<div>Align Me</div>
</div>
</div>
If you are scaling by p then you are reducing the size and the new width will become width*(1 - p). Same logic for the height. You can consider the use of calc() and easily define the translate using this formula.
We divide by 2 because we reduce from both side and we will translate from 1 side
.tile {
position: relative;
width: 540px;
height: 200px;
display:flex;
align-items:center;
justify-content:center;
}
.tile:hover:before {
transform: scale(0.9);
}
.tile:hover .button{
transform: translate(calc(-540px*0.1/2),calc(200px*0.1/2));
}
.tile:before {
content: '';
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: #000;
z-index: -1;
transition: transform .3s;
}
h1 {
text-align: center;
color: white;
margin:0;
}
.tile > .button {
position: absolute;
right: 0;
top: 0;
display: inline-block;
background: red;
padding: 10px 15px;
color: white;
transition: transform .3s ;
}
<div class="tile">
<h1>Hello World</h1>
<div class="button">Align Me</div>
</div>
You can consider CSS variables to easily change the scale value:
.tile {
position: relative;
width: 540px;
height: 200px;
display:flex;
align-items:center;
justify-content:center;
--s:0.9;
}
.tile:hover:before {
transform: scale(var(--s));
}
.tile:hover .button{
transform: translate(calc(-540px*(1 - var(--s))/2),calc(200px*(1 - var(--s))/2));
}
.tile:before {
content: '';
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: #000;
z-index: -1;
transition: transform .3s;
}
h1 {
text-align: center;
color: white;
margin:0;
}
.tile > .button {
position: absolute;
right: 0;
top: 0;
display: inline-block;
background: red;
padding: 10px 15px;
color: white;
transition: transform .3s ;
}
<div class="tile">
<h1>Hello World</h1>
<div class="button">Align Me</div>
</div>
<div class="tile" style="--s:0.5">
<h1>Hello World</h1>
<div class="button">Align Me</div>
</div>
I'm trying to animate a box shadow transition with the aid of CSS pseudo-elements :before and :after. In principle, the code provided in the JSFiddle works fine, except that on mousing out of the subdiv in the lefthand column, its box shadow jumps to the leftparentdiv. This behavior occurs whenever the window is window is small enough that overflow-y: scroll kicks in. The problem seems to occur in all browsers that support box shadows.
I guess I'm missing something obvious here, but can't figure out what.
body {
background-color: pink;
}
.subdiv {
width: 25vw;
border: 1px solid;
}
.subdiv:after {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.30);
transition: all 0.6s ease-in-out;
opacity: 0;
}
.subdiv:hover {
transform: scale(1.1, 1.1);
}
.subdiv:hover:after {
opacity: 1;
}
#leftparentdiv {
position: absolute;
left: 0;
top: 0;
border: 1px solid;
width: 47vw;
padding: 3%;
overflow-y: scroll;
}
#rightparentdiv {
position: absolute;
left: 53vw;
top: 0;
border: 1px solid;
width: 47vw;
padding: 3%;
overflow-y: scroll;
}
<div id="leftparentdiv">
<div class="subdiv">
Blabla;
</div>
</div>
<div id="rightparentdiv">
<div class="subdiv">
Blabla;
</div>
</div>
JSFiddle
You have a transform on .subdiv:hover, but none on .subdiv. A box with a transform establishes a containing block. This is what allows the pseudo-element (and its shadow) to be painted around .subdiv when the mouse is over it. But when the mouse leaves the element, the pseudo-element (and its shadow) jumps to .subdiv's parent because .subdiv no longer establishes a containing block, so the pseudo-element sizes according to the parent element and not its originating .subdiv because the parent element does establish a containing block. This is also true when the layout is first rendered, before the cursor ever touches the .subdiv (you just don't see it because the pseudo-element is invisible).
This behavior actually occurs only when .subdiv's parent has overflow: visible. It doesn't occur otherwise. The reason for that is because the pseudo-element's box shadow is actually overflowing the parent element whenever its originating .subdiv is not :hover. So a non-visible overflow clips the shadow away. This isn't immediately apparent because the parent element doesn't scroll — and the reason for that is because box shadows don't affect layout.
Assuming the desired behavior is for .subdiv to always be the one casting the shadow, all you have to do is position .subdiv so it establishes a containing block at all times:
body {
background-color: pink;
}
.subdiv {
width: 25vw;
position: relative;
border: 1px solid;
}
.subdiv:after {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.30);
transition: all 0.6s ease-in-out;
opacity: 0;
}
.subdiv:hover {
transform: scale(1.1, 1.1);
}
.subdiv:hover:after {
opacity: 1;
}
#leftparentdiv {
position: absolute;
left: 0;
top: 0;
border: 1px solid;
width: 47vw;
padding: 3%;
overflow-y: scroll;
}
#rightparentdiv {
position: absolute;
left: 53vw;
top: 0;
border: 1px solid;
width: 47vw;
padding: 3%;
overflow-y: scroll;
}
<div id="leftparentdiv">
<div class="subdiv">
Blabla;
</div>
</div>
<div id="rightparentdiv">
<div class="subdiv">
Blabla;
</div>
</div>
What is happening
What I want to happen
I want the icon-x-circle to be horizontally centered and on the same line as "Rename" but be right-aligned (probably 30px away from the right end of the header). If someone could let me know how to do that it would be greatly appreciated!
Something to note:
The icon-x-circle itself is not centered. For some reason Fontastic icons seem to add extra space at the bottom. So this is another reason why I'm struggling to horizontally center icon-x-circle.
My Code
HTML
<div id="popup-rename" class="overlay">
<div class="popup">
<header>
<h1>Rename</h1>
<a class="close icon-x-circle" href="#"></a>
</header>
<div class="content">
<div class="student-name student-rect">
<h1>Student Name</h1>
</div>
<div class="save-button center-children">
<a class="save icon-check-circle" href="#"></a>
</div>
</div>
</div>
</div>
CSS
header{
background-color: #F5F5F5;
padding-top: 15px;
padding-bottom: 15px;
text-align: center;
text-transform: uppercase;
}
header h1 {
margin-top: 10px;
margin-bottom: 10px;
font-weight: 300; /*100, 200*/
}
.icon-x-circle{
color: #E1E1E1;
}
.overlay {
position: absolute;
z-index: 2;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: rgba(0, 0, 0, 0.7);
transition: opacity 500ms;
visibility: hidden;
opacity: 0;
}
.overlay:target {
visibility: visible;
opacity: 1;
}
.popup {
margin: 70px auto;
background: white;
width: 50%;
position: relative;
transition: all 200ms ease-in-out;
}
.popup header{
padding: 20px;
}
.close, .save{
transition: all 200ms;
}
.icon-x-circle:hover {
color: #B6B6B6;
}
JSFiddle
One method for aligning elements is to use position: absolute;:
.icon-x-circle {
position: absolute;
right: 0px;
width: 300px;
border: 3px solid #73AD21;
padding: 10px;
}
You can use absolute positioning and put the button wherever you want.
first, make header a relative container
header{
position: relative;
}
Then you can make the button absolute
header a{
position: absolute;
right: 30px;
top: 10px
}
You can mess with right and top to move the button wherever.
https://jsfiddle.net/49abesy2/1/
I'm implementing an on-boarding similar to Medium's which has text in the center of the box over an black-overlay with the background-image behind it.
However, I'm struggling with making the text INSIDE the div with the background-image NOT having opacity effect.
<div class="blackBackground">
<div class="topicImage opacityFilter" style="background-image: url(https://images.unsplash.com/photo-1444401045234-4a2ab1f645c0?ixlib=rb-0.3.5&q=80&fm=jp&crop=entropy&s=4372cb6539c799269e343dd9456b7eb3);">
<p class="text-inside-image">Fashion</p>
</div>
</div>
Here's my CSS:
.blackBackground {
background-color: black;
z-index: -1;
}
.opacityFilter {
opacity: 0.8;
position: relative;
}
.margin-bottom-negsix {
margin-bottom: -6px !important;
}
.topicImage {
padding-bottom: 75%;
background-position: 50% 50%;
background-repeat: no-repeat;
background-size: cover;
margin: 0 auto;
position: relative !important;
height:150px;
background-color: rgba(0, 0, 0, 0.8) !important;
}
.text-inside-image {
position: absolute;
top: 20%;
left: 35%;
color: white;
font-size: 24px;
font-weight: 500;
z-index: 1;
}
I've tried several solutions such as CSS - Opaque text on low opacity div?
and How to keep text opacity 100 when its parent container is having opacity of 50
and a couple more, but no luck.
My progress with my JSFiddle is here: https://jsfiddle.net/RohitTigga/akz5zng7/1/
Why is this occurring and how to fix it?
Hi change your HTML like this
HTML
<div class="my-container">
<h1 class="text-inside-image">Fashion</h1>
<img src="https://images.unsplash.com/photo-1444401045234-4a2ab1f645c0?ixlib=rb-0.3.5&q=80&fm=jp&crop=entropy&s=4372cb6539c799269e343dd9456b7eb3">
</div>
CSS
.my-container {
position: relative;
background: #5C97FF;
overflow: hidden;
}
.my-container h1 {
padding: 50px;
text-align: center;
z-index: 2;
position: relative;
color: #fff;
}
.my-container img {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: auto;
z-index: 1;
opacity: 0.6;
}
for reference https://plnkr.co/edit/YugyLd8H5mQExzF61rA9?p=preview
You have set a translucent background colour on the element and then covered it up with a background image.
If you want the background image to be translucent, use an image that is intrinsically translucent. The PNG image format supports this.
I am trying to achieve two hover effects on an image.
First, when the user hovers over an image a plus icon on the top right corner of the image appears.
Second, when the user hovers over the plus the icon changes to: “Add to collection”.
All these events need to be smooth transitions.
My first problem is I can't get any smooth transitions going for the first hover.
My second problem is I have no idea how to achieve the second hover - I've done a lot of Google searches but this doesn't seem to be a common effect.
Here is the code I have tried so far (with fill murray placeholder image):
HTML:
<div class="item">
<a href="#" class="item-link">
<img src="https://www.fillmurray.com/g/582/580" alt="dimsum">
</a>
</div>
CSS:
.item-link:hover:before {
content: '';
display: block;
position: absolute;
width: 58px;
height: 58px;
background-image: url('http://i.imgur.com/bWcylV3.png');
border-radius: 50%;
top: 10px;
right: 10px;
}
And here is the js fiddle
Here is the screenshots for what I want to achieve with the second hover:
Just did a little bit changes in your mark up and and find a solution for your issue. Yes, It's not possible to :hover a pseudo-element. Added a new div btn-plus and a span text for convenience. This is done using pure css. Hope this helps :)
.btn-plus:before {
content: '';
display: block;
position: absolute;
width: 58px;
height: 58px;
background-image: url('http://i.imgur.com/bWcylV3.png');
border-radius: 50%;
top: 0px;
right: 30px;
z-index: 1;
}
.btn-plus{
position: absolute;
display: block;
width: 200px;
height: 58px;
top: 30px;
right: 0;
opacity : 0;
transition: all ease .5s;
}
.item-link{
width: 100%;
height: 100%;
display: block;
}
.item-link img{
width: 100%;
}
span.text{
position : absolute;
top: 0px;
right: 0px;
color: #fff;
padding: 15px;
width: 150px;
height: 30px;
border-radius: 30px;
background: rgba(0, 0, 0, 0.5);
z-index: 0;
transition: all ease .5s;
opacity : 0;
}
.item-link:hover .btn-plus{
opacity : 1;
}
.btn-plus:hover span{
opacity : 1;
right: 30px
}
<div class="item">
<a href="#" class="item-link">
<img src="https://www.fillmurray.com/g/582/580" alt="dimsum">
<div class="btn-plus">
<span class="text">Add to list</span>
</div>
</a>
</div>