Is it possible to have markup like this but also background overlay on hover?
<figure class="gallery-item">
<div class="gallery-icon landscape">
<a href="www.google.com">
<img src="http://placehold.it/300x300" />
</a>
</div>
</figure>
I tried placing background-color: #333 on .gallery-icon on hover, but only something like border-bottom appears?
http://codepen.io/filaret/pen/NRpVyr
You are definitely on the right track. Since you are using an :after element for the icon, you should leave that element alone since it's already positioned and defining its own width+height (based off the icon).
The reason the :after selector positions itself correctly is because it's not relying on its parent containers dimensions. You only have it as absolute from the top and left, which is fine. But it doesn't know about how tall it should be, because its parent has no defined height! If you use absolute positioning, you need to define the parent containers dimensions so that the child knows where its bounds are.
So first off, .gallery-icon is already a block element, so you don't need to define its width (its already 100% by nature), just the height:
.gallery-icon {
position: relative;
height: 100%;
}
Second, you should use a :before element to define a background, so that you don't have to mess with the :after icon:
&:before {
content: '';
position: absolute;
height: 100%;
width: 100%;
top: 0;
left: 0;
background-color: #333;
opacity: 0;
transition: opacity 0.3s ease-in-out;
}
Now, you just have to add the opacity change on hover!
&:hover {
.gallery-icon {
&:before {
opacity: .5;
}
&:after {
opacity: 0.6;
}
}
Hope that helps, here is a codepen forked off your original: http://codepen.io/anon/pen/JRWqxX
Edit: I also noticed that your img tag is causing it to go below the visual bottom of the container, a quick fix is just to add:
.gallery-icon {
img {
display: block;
}
You need to understand your markup works. Your image will be displayed on top of everything, and when you put a background colour on .gallery-icon that background colour will be under the image, and since the anchor link doesn't has a width and height, it only take a little bit of portion, that's why it showing a border bottom.
To create a background overlay on hover, you need to position it to be on top of the image.
Using pseudo element to create a background overlay:
&:hover .gallery-icon {
&::before {
content: '';
background-color: #333;
display: block;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
opacity: 0.2;
}
}
The pseudo element has a position absolute so it will displayed on top of the image. top, left, right and bottom 0 to tell the pseudo element to stretch it self as tall and as wide as the parent element.
Hope this helps.
I've tried to simplify the code a little bit. I hope it's what you've tried to achieve.
The trick is to place a as a independent element to img.
<figure class="gallery-item">
<img src="http://placehold.it/300x300">
</figure>
http://codepen.io/anon/pen/LRWoaR
The image (http://placehold.it/300x300) has a solid background colour, no?
That will block anything happening behind itself.
Related
I'm trying to create a transition for both an image and a pseudo element of its container, but for some reason, these transitions appear to be out of sync with each other, resulting in the pseudo element reaching a opacity: 0 state before the image does.
I've tried various combinations of style rules, but I never managed to accomplish an ease-in-out transition to work correctly.
Here's some context for the current code: the image is padded on purpose, to provide a better visual (centered) of its content. The images that'll be used are always guaranteed to have a white background. That's why I'm using a pseudo-element with a white background color to fill the vertical spaces that the image does not cover.
The background-image should take the full width/height of the container and there are not guarantees of its background being white.
The desired effect is for both the pseudo-element and image to reach opacity: 0 at the same making it look like its a single element.
I'm also considering using an ::after pseudo element to provide a "loading skeleton" while the image is not retrieved from the server, but that's not a concern for now.
Here's the code, and the respective fiddle: https://jsfiddle.net/rjk2z31d/1/
*,
*::before,
*::after {
box-sizing: border-box;
}
.box {
width: 248px;
height: 320px;
}
.image-box {
position: relative;
display: block;
background-repeat: no-repeat;
background-size: cover;
line-height: 0;
background-color: #FFFFFF;
&::before {
display: block;
content: "";
width: 100%;
padding-top: (100% + (100% / 3));
}
img {
z-index: 1;
position: absolute;
top: 50%;
left: 0;
width: 100%;
transform: translate3d(0, -50%, 0);
padding: 16px 16px;
}
&::before, img {
background-color: #FFFFFF;
opacity: 1;
transition: all 1.5s ease-in-out;
}
&:hover {
&::before, img {
opacity: 0;
}
}
}
<div class="box">
<div class="image-box" style="background-image: url('https://via.placeholder.com/248x320/FF0000/000000?text=Background')">
<img src="https://via.placeholder.com/248x320/FFFFFF/000000?text=Image">
</div>
</div>
Actually, they both fade at the same speed.
The out-of-sync effect you're talking about is an illusion due to the opacities overlapping.
If you set the initial opacity of both elements, it's easier to understand what's going on.
The image's faded white added to the pseudo element's faded white looks less transparent than the pseudo element's faded white alone.
See it in effect with the below image:
If you need to be convinced of their synchronization, add a transform rule to the :hover handler. the result is synced as it is supposed to be.
As a workaround, I would suggest you to try figuring out a better approach than fading overlapping elements.
You could use the <picture> tag with css object-fit property to get rid of those blank spaces.
picture doc
object-fit doc
is there anyone to add an overlay using html to make the image darker? I tried using data-overlay=0.6. However, no effect took place. If it isn't possible, can I do use the below coding?
!-- Slide 1 -->
<li data-index="slide-1" data-transition="fade" data-slotamount="1" data-easein="default" data-easeout="default" data-masterspeed="500" data-rotate="0" data-delay="6000">
<!-- Main image -->
<img class="pic_slide_one" src="media/image/slider/audi-black-car-8639.jpg" alt="slide-1" data-bgfit="cover" data-bgposition="center bottom">
/* Styling and fetching IMG */
.pic_one_slider {
background:linear-gradient(0deg,rgba(0,0,0,0.95),rgba(0,0,0,0.95)),url('media/image/slider/audi-black-car-8639.jpg');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
It looks like your question goes beyond a simple image overlaying. For a single image, my suggestion would be to use an position: absolute div so that you can overlay however you want (color, with another picture, etc)
The idea is:
a container div. Container has here display: inline-block so that it takes the width and height of the img child. If your container has full width, you may skip this
the img itself
an empty div which does the overlay. The overlay can be done via multiple options:
in case of a single color, you can use background: rgba(0, 0, 0, 0.5) where 0.2 is the opacity
Put whatever you want in the div and use opacity: 0.5
Here is an example:
.darken-img{
/* to make absolute children depending on this parent */
position: relative;
/* to make parent div adapt to img width/height*/
display: inline-block;
}
.darken-img img{
height: 400px;
}
.darken-img .darkener{
/* to go overlay the img */
position: absolute;
top: 0;
/* to cover the whole img */
height: 100%;
width: 100%;
/* make your choice here */
background: rgba(0,0,0,0.6);
}
<div class="darken-img">
<img src="http://st.motortrend.com/uploads/sites/5/2017/04/2018-Lexus-NX-300h-front-three-quarter-01.jpg" />
<div class="darkener"></div>
</div>
You could try decreasing the opacity. Depending on your image and expected results, this may be just enough:
.pic_one_slider {
opacity: 0.8;
}
This is difficult to answer without access to all of the css included, but this is how I would do it. You could try overlapping the image with a div with the same width and height of the image and a background-color property set to black and then setting the opacity value of that div.
Note the usage of z-index which requires the position property to be set. In this example I've set it to absolute.
.overlay {
background-color: black;
width: 600px;
height: 400px;
z-index: 2;
position: absolute;
opacity: 0.8;
}
and
<div class="overlay"></div><img class="pic_slide_one" src="https://www.w3schools.com/w3css/img_lights.jpg" alt="slide-1" data-bgfit="cover" data-bgposition="center bottom" style="z-index:1;position: absolute;">
Obviously you could include the styling on your img class somewhere else, such as within your pic_slide_one class.
I am trying to have a bit of text showing over the images on the hover state (http://francescaponzini.com/kay/).
So far I've managed to do it with css. However, I am struggling with the positioning. I'd like the text to show when the user hover any point of the image. I've tried to used the position absolute and relative but without success.
Is there a way to have the div that contains the text assume the same dimension of the image if this makes sense?
this is my code so far:
<a class="image_link" href="http://francescaponzini.com/kay/?p=106">
<img src="http://francescaponzini.com/kay/wp-content/uploads/2014/06/Firstname.png" width="450" height="575" alt="" style="width: 243px;">
<div class="text-content">Place Name</div>
</a>
any help or hint appreciated!thanks to all.
.image_link:hover .text-content {
opacity: 1;
}
Change the display of the wrapping link and give a postition:
body.home .hentry > a {
position: relative;
display: block;
...
}
Position the content block and make it fill the wrapping element:
.text-content {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
/* Remove width and height declarations */
...
}
I have a parent <div> and a child <a>. The parent has a background image set to 60% opacity, but I'd like the child link to have 100% opacity. My reason for implementing it this way is so I can fade the parent's opacity to 100% on hover, thereby eliminating the need for a hover image.
I understand that children inherit their parent's opacity. I tried the :after {} technique described here, but even with appropriate z-index values set, the child link still sits beneath the parent element and is not clickable.
My issue is that the child link cannot be clicked because the parent's :after pseudo-element sits above the child.
My code is as follows:
<div>
Load more
</div>
div {
position: relative;
height: 300px;
}
div:after {
position: absolute;
top: 0;
left: 0;
content: '';
background: url('../img/bg-load-more.png') repeat-x;
width: 100%;
height: 300px;
z-index: 10;
opacity: 0.4;
}
div a {
display: block;
z-index: 100;
}
Does anyone know of a solution to this issue, or must I create an image sprite and switch swap background images on hover?
The problem is that you aren't applying a position to the <a> itself (z-index only applies to positioned elements) only the containing div and the pseudo-element, so the pseudo-element is sitting on top of the link preventing it from being clicked.
All you need to do is give the link a stacking context, e.g. include relative positioning:
div a {
display: block;
position: relative;
z-index: 100;
}
Example
I want to add some shine to an element on webpage. I would prefer if I don't have to add additional html to the page. I want the image to appear in front of the element rather than behind. What's the best way to do this?
To achieve a "foreground image" (without extra HTML code), you can use a pseudo-element (::before / :before) plus the CSS pointer-events. The last property is needed so that the user can actually click through the layer "as if it did not exist".
Here's an example (using a colour whose alpha channel is 50% so that you can see that the real elements can actually be focused). http://jsfiddle.net/JxNdT/
#cont {
width: 200px;
height: 200px;
border: 1px solid #aaa;
/*To show the boundaries of the element*/
}
#cont:before {
position: absolute;
content: '';
background: rgba(0, 0, 0, 0.5);
width: 200px;
height: 200px;
pointer-events: none;
}
<div id="cont">
Test<br>
<input type="text" placeholder="edit">
</div>
PS. I picked the ::before pseudo-element, because that naturally leads to the correct positioning. If I pick ::after, then I have to add position:relative; to the real element (#cont), and top:0;left:0; to the pseudo-element (::after).
PPS. To get the foreground effect on elements without a fixed size, an additional element is needed. This wrapper element requires the position:relative;display:inline-block; styles. Set the width and height of the pseudo-element to 100%, and the pseudo-element will stretch to the width and height of the wrapper element. Demo: http://jsfiddle.net/JxNdT/1/.
If you need a white-transparent foreground
This is for future visitors like me who are considering adding a white-transparent foreground to an element to communicate that it's hidden / disabled for instance. You can often achieve your goal by simply lowering the opacity below 1:
.is-hidden {
opacity: 0.5;
}
visible
<span class="is-hidden">hidden</span>
visible
You can use this css
#yourImage
{
z-index: 1;
}
NOTE
Set the z-index to index greater the the z-index of the element over which you are putting the image.
If you have not specified any z-index then 1 would do the work.
You can also set z-index to -1,in that case the image would always be at background!
A neat solution: box-sizing + padding-left, see more at css-tricks
Somewhere in your HTML:
<img id="test_replacement" src="test.png" alt="test" />
The CSS for replacing the image (on hovering)
#test_replacement {
width: 200px; //must be the size of your image (and the replacement one)
height: 200px; //idem
display: block;
}
#test_replacement:hover {
box-sizing: border-box;
background-image: url('somewhere/other_image.png');
padding-left: 200px; //at least the size of the width
}
Use an absolutely positioned <img> element:
img {
position: absolute;
opacity: 0.3;
pointer-events: none;
}
iframe {
width: 500px;
height: 300px;
border: 0;
}
<img src="https://i.stack.imgur.com/rET57.jpg" alt="Foreground image">
<iframe src="https://example.com/"></iframe>