add overlay on image using ::before [duplicate] - html

This question already has answers here:
How to overlay images
(11 answers)
Closed 3 years ago.
I have a post carousel where i am showing archive post .
<div class="col-md-12">
<div class="post--small mb-4">
<img src="assets/images/Layer%2014.png" alt="" class="post__img img-fluid mr-2">
<div class="post__body">
<a class="post__title post__title--small text-capitalize mb-3 text-white">
Ahmedabad Investor CampFinal Disscusion
</a>
<p class="post__date post__date--small text-uppercase">29 may 2019</p>
</div>
</div>
</div>
and CSS
.post__title, .post:link, .post:visited {
font-size: 18px;
font-weight: 500;
color: #fff;
cursor: pointer;
display: block;
}
.post__img {
position: relative;
}
.post__img::before {
content: "";
display: block;
height: 100%;
position: absolute;
top: 0;
left: 0;
width: 100%;
background-color: rgba(255, 255, 255, .8);
}
.post__date {
font-size: 12px;
font-weight: 400;
color: white;
}
.post--small {
display: flex;
}
.post--small .post__img {
width: 119px;
}
I am trying to achieve overlay on images with any extra div , so i used ::before element . I think everything i done is right but this code didn't work .
Please help , Thank you in advance

This is how I usually go about doing an image overlay, I tried to not edit your code too much, hope this helps: https://jsfiddle.net/jbgvaqtx/23/
HTML
<div class="col-md-12">
<div class="post--small mb-4">
<img src="https://picsum.photos/seed/picsum/200/300" alt="" class="post__img img-fluid mr-2">
<div class="post__body">
<a class="post__title post__title--small text-capitalize mb-3 text-white">Ahmedabad Investor CampFinal Disscusion</a>
<p class="post__date post__date--small text-uppercase">29 may 2019</p>
</div>
</div>
</div>
CSS
.post__title,
.post:link,
.post:visited {
display: block;
font-size: 18px;
font-weight: 500;
color: #fff;
cursor: pointer;
}
.post__img {
position: absolute;
cursor: pointer;
height: 10)%;
width: 100%;
pointer-events: all;
}
.post__img:hover ~ .post__body{
opacity: 1 !important;
}
.post__body{
position: relative;
display: block;
top: 0px;
left: 0px;
height: 100%;
width: 119px;
background-color: rgba(0, 0, 0, 0.5);
opacity: 0;
pointer-events: none;
}
.post__date {
font-size: 12px;
font-weight: 400;
color: white;
}
.post--small {
display: flex;
}
.post--small .post__img {
width: 119px;
}

Pseudo element like :before and :after not work with img tag in all browsers as answered here already https://stackoverflow.com/a/5843078/11719787
Try adding overlay with div tag
//Html
<div class="img-cont">
<img src="https://via.placeholder.com/150" alt="" class="post__img img-fluid mr-2">
<div class="image-overlay"></div>
</div>
//CSS
.img-cont {
position: relative;
}
.image-overlay {
display: block;
height: 100%;
position: absolute;
top: 0;
left: 0;
width: 100%;
background-color: rgba(255, 255, 255, .8);
}

Related

Create css circles connected by line

I need to do this kind of slider that is just three circles connected by a line and with a description below each circle:
But at the moment I just have this:
And this is the code I used to make that:
<div
class="
text-center
my-5
px-5
d-flex
align-items-center
justify-content-between
slider-container
"
>
<div class="slider-item">
<i
class="
icon-circle
fs-16 fs-md-20
d-inline-block
text-gray-300
"
></i>
<p class="m-0 font-RobotoBold1 fs-10 fs-md-12 mt-2">
Selecciona <br />
cantidad
</p>
</div>
<div>
<i
class="
icon-circle
fs-16 fs-md-20
d-inline-block
text-gray-300
"
></i>
<p class="m-0 font-RobotoBold1 fs-10 fs-md-12 mt-2">
Selecciona <br />
destino
</p>
</div>
<div>
<i
class="
icon-circle
fs-16 fs-md-20
d-inline-block
text-gray-300
"
></i>
<p class="m-0 font-RobotoBold1 fs-10 fs-md-12 mt-2">
Confirma <br />
transferencia
</p>
</div>
</div>
This is the css code:
.slider-container {
position: relative;
display: flex;
justify-content: space-between;
align-items: center;
padding: 1em;
overflow: hidden;
}
.slider-container::before {
position: absolute;
top: calc(50% - 20px);
right: 0;
left: 0;
Content: "";
Background-color: grey;
height: 1px;
z-index: -1;
}
Anyone knows how to make that line behind the circles and that doesn't exceed them?
Sidenote: This is why I would never use tailwindcss or the likes. You don't need it, and it totally ruins the HTML.
Now compare the markup you have with the markup below - which is a) much, much more concise, b) using only a single CSS class and c) using the proper semantic elements for the job.
It also works for 2 or 4 or 7 items. Sure it needs some refinement regarding size and color of the active circle, but that should be an easy adjustment for you.
The only restriction of this solution is that your page background-color needs to be solid and be matched by the background-color of the ::after elements.
document.querySelectorAll('.steplist').forEach(steplist => {
steplist.addEventListener('click', function(event) {
if (event.target.nodeName !== 'LI') return;
const items = event.target.closest('.steplist').querySelectorAll('li');
for (const item of items) {
item.classList.toggle('active', item === event.target);
}
});
});
*, ::after, ::before { box-sizing: border-box; }
.steplist {
border-top: 2px solid #ccc;
display: inline-flex;
font-family: 'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif;
list-style-type: none;
gap: 7em;
margin: 0;
padding: 0;
--circle-radius: 8px;
}
.steplist li {
color: #999;
cursor: pointer;
padding: calc(5px + var(--circle-radius)) 0 0;
margin: 0;
position: relative;
text-align: center;
}
.steplist li::before {
background-color: #ccc;
border-radius: 50%;
content: '';
position: absolute;
height: calc(2 * var(--circle-radius));
width: calc(2 * var(--circle-radius));
top: 0;
left: 50%;
transform: translate(-50%, -50%);
transition: all 0.3s ease;
}
.steplist .active {
color: black;
}
.steplist .active::before {
background-color: green;
box-shadow: 0 0 0 3px rgba(0,255,0,.25);
}
.steplist li:first-child::after {
background-color: white;
content: '';
position: absolute;
height: 2px;
width: 100%;
top: -2px;
left: calc(-50% - var(--circle-radius));
}
.steplist li:last-child::after {
background-color: white;
content: '';
position: absolute;
height: 2px;
width: 100%;
top: -2px;
left: calc(50% + var(--circle-radius));
}
.circle-big {
--circle-radius: 12px;
}
<ol class="steplist">
<li>Point 1<br>whatever</li>
<li>Point 2<br>whatever</li>
<li>Point 3<br>whatever</li>
</ol>
<br><br><br>
<ol class="steplist circle-big">
<li>Point 1<br>whatever</li>
<li>Point 2<br>whatever</li>
<li>Point 3<br>whatever</li>
<li>Point 4<br>whatever</li>
</ol>
Finally I solve the case with this code, I added the custom classes so you can understand what are those, and in the slider-container:before, the formula 'top: calc(50% - 22px)', the px can change depending of the size of the screen. :
/* slider css code */
.slider-container {
position: relative;
display: flex;
justify-content: space-between;
align-items: center;
padding: 1em;
overflow: hidden;
}
.slider-container::before {
position: absolute;
top: calc(50% - 22px);
right: 65px;
left: 65px;
content: "";
background-color: #d8d8d8;
height: 1px;
z-index: -1;
}
#media (max-width: 768px) {
.slider-container::before {
top: calc(50% - 22px);
right: 60px;
left: 60px;
}
}
/* this are custom css classes we use at work */
.wi-12 {
width: 12px;
}
.he-12 {
height: 12px;
}
.wi-24 {
width: 24px;
}
.he-24 {
height: 24px;
}
#media (min-width: 768px) {
.wi-md-20 {
width: 20px;
}
.he-md-20 {
height: 20px;
}
.wi-md-30 {
width: 30px;
}
.he-md-30 {
height: 30px;
}
.wi-md-100 {
width: 100px;
}
}
.wi-70 {
width: 70px;
}
.bg-green-700 {
background-color: #00bf79;
}
.bg-gray-300 {
background-color: #bababa;
}
.bor-rounded-full {
border-radius: 50%;
}
.font-Roboto {
font-family: "Roboto";
}
.fs-10 {
font-size: 10px;
}
.fs-md-12 {
font-size: 12px;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" />
<div class="
text-center
mt-md-4
px-4
d-flex
align-items-center
justify-content-between
slider-container
mb-md-3
">
<div class="slider-item wi-70 wi-md-100">
<div class="
wi-24
he-24
wi-md-30
he-md-30
bor-rounded-full
d-inline-flex
justify-content-center
align-items-center
" style="
background: rgba(0, 191, 121, 0.3);
">
<div class="wi-12 he-12 wi-md-20 he-md-20 bg-green-700 bor-rounded-full d-inline-block"></div>
</div>
<p class="m-0 font-Roboto fs-10 fs-md-12 mt-2">
Selecciona <br /> cantidad
</p>
</div>
<div class="slider-item wi-70 wi-md-100">
<div class="
wi-24
he-24
wi-md-30
he-md-30
bor-rounded-full
d-inline-flex
justify-content-center
align-items-center
">
<div class="wi-12 he-12 wi-md-20 he-md-20 bg-gray-300 bor-rounded-full d-inline-block"></div>
</div>
<p class="m-0 font-Roboto fs-10 fs-md-12 mt-2">
Selecciona <br /> destino
</p>
</div>
<div class="slider-item wi-70 wi-md-100">
<div class="
wi-24
he-24
wi-md-30
he-md-30
bor-rounded-full
d-inline-flex
justify-content-center
align-items-center
">
<div class="wi-12 he-12 wi-md-20 he-md-20 bg-gray-300 bor-rounded-full d-inline-block"></div>
</div>
<p class="m-0 font-Roboto fs-10 fs-md-12 mt-2">
Confirma <br /> transferencia
</p>
</div>
</div>

Adding classes to a parent div on click

I have a setup that works similarly to an accordion, but vertical. I would like the add the class "unset" to the "choice" class, also while removing the "expand" and "small" classes.
I've edited the jQuery code to include to say when the card-close class is clicked, choice removes expand and adds class unset, and also if card-close is clicked, choice removes small and adds class unset.
Nothing I have used though has worked and I'm thinking it's because the div is inside the "choice" section.
Any ideas on how to get this to work?
jQuery(document).ready(function() {
jQuery(".card-close").on("click", function() {
jQuery(".choice").removeClass("expand");
jQuery(".choice").addClass("unset");
jQuery(".choice").removeClass("small");
jQuery(".choice").addClass("unset");
});
jQuery(".choice").on("click", function() {
jQuery(".choice").removeClass("expand unset ");
jQuery(".choice").addClass("small");
jQuery(this).removeClass("small");
jQuery(this).addClass("expand");
});
})
.container {
display: flex;
width: 100%;
padding: 0;
}
.choice {
height: 40vw;
box-sizing: border-box;
padding: 0;
overflow: hidden;
float: left;
align-items: center;
transition: width 0.2s;
position: relative;
}
.card-body {
z-index: 9;
}
.card-body h4 {
text-align: center;
font-family: 'Poppins', sans-serif !important;
color: #fff;
font-weight: 700;
opacity: .7;
text-decoration: none;
text-transform: uppercase;
margin-bottom: 3px;
width: max-content;
}
.card-body .card-title {
position: absolute;
transform: translate(-50%, -50%);
top: 50%;
left: 50%;
text-align: center;
}
.expand .card-body .card-title {
left: 56%;
top: 40%;
}
.card-body .card-title .card-open,
.card-body .card-title .card-close {
color: #000;
background-color: #CBE3A9;
width: max-content;
padding: 0 7px;
font-size: 20px;
margin: 0 auto;
}
.card-body .card-title .card-close,
.expand .card-body .card-title .card-open {
display: none;
}
.expand .card-body .card-title .card-close,
.card-body .card-title .card-open {
display: block;
}
.choice .bg-image {
background-size: cover;
width: 100%;
height: 100%;
position: absolute;
filter: blur(6px);
transition: 1s;
z-index: -9;
}
.danger-color .bg-image {
background-color: green;
}
.warning-color .bg-image {
background-color: blue;
}
.success-color .bg-image {
background-color: red;
}
.info-color .bg-image {
background-color: yellow;
}
.choice.expand .bg-image {
filter: blur(0px);
transition: 1s;
z-index: -999;
}
.expand .card-text {
width: 32%;
background-color: #A7D16D;
padding: 2%;
margin: 0 auto;
position: absolute;
left: 57%;
top: 51.9%;
}
.expand .card-body h4 {
opacity: 1;
font-size: 65px;
}
.small .card-body h4 {
font-size: 25px;
}
.expand {
width: 130%;
}
.unset {
width: 25%;
cursor: pointer;
}
.small .card-title h4 {
display: none;
}
.small {
width: 5%;
cursor: pointer;
background-color: #0000006e;
}
.small>.card-body .card-text {
opacity: 0;
}
.unset>div>p {
opacity: 0;
}
.expand>div {
transition-delay: 200ms;
opacity: 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<div class="container mt-5 justify-content-center">
<div class="choice unset mx-2 danger-color">
<div class="bg-image"></div>
<div class="card-body">
<!-- Title -->
<div class="card-title">
<h4>Strategic</h4>
<p class="card-open">+</p>
<p class="card-close">-</p>
</div>
<!-- Text -->
<p class="card-text">Every FeltonBuford Partners’ insight strategist has worked on the client side. As former leaders of businesses, we can understand the problems our clients face and deliver the level of strategic thinking that leads to true business breakthroughs.</p>
</div>
</div>
<div class="choice unset mx-2 warning-color">
<div class="bg-image"></div>
<div class="card-body">
<!-- Title -->
<div class="card-title">
<h4>Experience</h4>
<p class="card-open">+</p>
<p class="card-close">-</p>
</div>
<!-- Text -->
<p class="card-text">For more than two decades, FeltonBuford Partners has been providing powerful insights that lead to transformational growth for our clients. From the beginning, our goal has been to be the kind of research firm we would have wanted to hire when we
were on the client side.</p>
</div>
</div>
<div class="choice unset mx-2 success-color">
<div class="bg-image"></div>
<div class="card-body">
<!-- Title -->
<div class="card-title">
<h4>Fearless</h4>
<p class="card-open">+</p>
<p class="card-close">-</p>
</div>
<!-- Text -->
<p class="card-text">We have earned the reputation for being fearless. Because of our depth of experience, we have the confidence to tackle the toughest and most complex projects across the globe.</p>
</div>
</div>
<div class="choice unset mx-2 info-color">
<div class="bg-image"></div>
<div class="card-body">
<!-- Title -->
<div class="card-title">
<h4>Diverse</h4>
<p class="card-open">+</p>
<p class="card-close">-</p>
</div>
<!-- Text -->
<p class="card-text">Our diversity is a true strength. As a minority and women-owned company, we have a unique appreciation of the diversity of the human experience. We can apply our varied talents and perspectives to a broader and more relevant understanding of the
complex world in which we live.</p>
</div>
</div>
</div>
Or you can use stopPropagation in the close event, the event will be stopped before triggering open e.g
jQuery(".card-close").on("click", function(event) {
event.stopPropagation();
jQuery(".choice").removeClass("expand");
jQuery(".choice").addClass("unset");
jQuery(".choice").removeClass("small");
jQuery(".choice").addClass("unset");
});
Read more about it here: https://developer.mozilla.org/en-US/docs/Web/API/Event/stopPropagation
Use relative addressing
Something like this - run in full screen
$(document).ready(function() {
$(".card-toggle").on("click", function() {
const $parent = $(this).closest(".choice")
$parent.toggleClass("expand");
$parent.toggleClass("unset");
$parent.toggleClass("small");
$parent.toggleClass("unset");
$(this).text($parent.hasClass("expand") ? "+" : "-")
});
})
.container {
display: flex;
width: 100%;
padding: 0;
}
.choice {
height: 40vw;
box-sizing: border-box;
padding: 0;
overflow: hidden;
float: left;
align-items: center;
transition: width 0.2s;
position: relative;
}
.card-body {
z-index: 9;
}
.card-body h4 {
text-align: center;
font-family: 'Poppins', sans-serif !important;
color: #fff;
font-weight: 700;
opacity: .7;
text-decoration: none;
text-transform: uppercase;
margin-bottom: 3px;
width: max-content;
}
.card-body .card-title {
position: absolute;
transform: translate(-50%, -50%);
top: 50%;
left: 50%;
text-align: center;
}
.expand .card-body .card-title {
left: 56%;
top: 40%;
}
.card-body .card-title .card-open,
.card-body .card-title .card-close {
color: #000;
background-color: #CBE3A9;
width: max-content;
padding: 0 7px;
font-size: 20px;
margin: 0 auto;
}
.card-body .card-title .card-close,
.expand .card-body .card-title .card-open {
display: none;
}
.expand .card-body .card-title .card-close,
.card-body .card-title .card-open {
display: block;
}
.choice .bg-image {
background-size: cover;
width: 100%;
height: 100%;
position: absolute;
filter: blur(6px);
transition: 1s;
z-index: -9;
}
.danger-color .bg-image {
background-color: green;
}
.warning-color .bg-image {
background-color: blue;
}
.success-color .bg-image {
background-color: red;
}
.info-color .bg-image {
background-color: yellow;
}
.choice.expand .bg-image {
filter: blur(0px);
transition: 1s;
z-index: -999;
}
.expand .card-text {
width: 32%;
background-color: #A7D16D;
padding: 2%;
margin: 0 auto;
position: absolute;
left: 57%;
top: 51.9%;
}
.expand .card-body h4 {
opacity: 1;
font-size: 65px;
}
.small .card-body h4 {
font-size: 25px;
}
.expand {
width: 130%;
}
.unset {
width: 25%;
cursor: pointer;
}
.small .card-title h4 {
display: none;
}
.small {
width: 5%;
cursor: pointer;
background-color: #0000006e;
}
.small>.card-body .card-text {
opacity: 0;
}
.unset>div>p {
opacity: 0;
}
.expand>div {
transition-delay: 200ms;
opacity: 1;
}
.card-toggle { font-size: xx-large }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<div class="container mt-5 justify-content-center">
<div class="choice unset mx-2 danger-color">
<div class="bg-image"></div>
<div class="card-body">
<!-- Title -->
<div class="card-title">
<h4>Strategic</h4>
<p class="card-toggle">-</p>
</div>
<!-- Text -->
<p class="card-text">Every FeltonBuford Partners’ insight strategist has worked on the client side. As former leaders of businesses, we can understand the problems our clients face and deliver the level of strategic thinking that leads to true business breakthroughs.</p>
</div>
</div>
<div class="choice unset mx-2 warning-color">
<div class="bg-image"></div>
<div class="card-body">
<!-- Title -->
<div class="card-title">
<h4>Experience</h4>
<p class="card-toggle">-</p>
</div>
<!-- Text -->
<p class="card-text">For more than two decades, FeltonBuford Partners has been providing powerful insights that lead to transformational growth for our clients. From the beginning, our goal has been to be the kind of research firm we would have wanted to hire when we
were on the client side.</p>
</div>
</div>
<div class="choice unset mx-2 success-color">
<div class="bg-image"></div>
<div class="card-body">
<!-- Title -->
<div class="card-title">
<h4>Fearless</h4>
<p class="card-toggle">-</p>
</div>
<!-- Text -->
<p class="card-text">We have earned the reputation for being fearless. Because of our depth of experience, we have the confidence to tackle the toughest and most complex projects across the globe.</p>
</div>
</div>
<div class="choice unset mx-2 info-color">
<div class="bg-image"></div>
<div class="card-body">
<!-- Title -->
<div class="card-title">
<h4>Diverse</h4>
<p class="card-toggle">-</p>
</div>
<!-- Text -->
<p class="card-text">Our diversity is a true strength. As a minority and women-owned company, we have a unique appreciation of the diversity of the human experience. We can apply our varied talents and perspectives to a broader and more relevant understanding of the
complex world in which we live.</p>
</div>
</div>
</div>

Reduce clickable area for an image

I've created a left navigation bar using buttons. I'm trying to reduce the hyperlink area to just the background image. Also, another issue I'm having is the elements overlaying the background image are taking precedence over the hyperlink, so the button is not actually clickable. Page for reference
http://www.auburn.edu/administration/facilities/home-page/index.html
Hyperlink area
Here's the background image area
.img-responsive {
display: block;
padding: 0;
margin: 0;
}
.background:hover .head {
color: #d76e08;
}
.overlay {
position: absolute;
z-index: 1;
top: 0;
left: 0;
color: white;
}
.icon {
padding-top: 15px;
padding-left: 40px;
}
.head {
margin-top: -75px;
padding-left: 120px;
}
.content {
margin-top: -5px;
padding-left: 120px;
padding-right: 35px;
}
<div class="row">
<div class="col-sm-12">
<div class="background">
<a href="../Collin/misc/issues/index.html">
<img alt="background" class="img-responsive" src="buttons/images/button.png" />
</a>
<div class="overlay">
<div class="icon">
<img alt="test" class="img-responsive" src="buttons/images/info-icon.png" />
</div>
<p class="head">Ask Facilities</p>
<p class="content">Here will be text about the button. .</p>
</div>
</div>
</div>
</div>
I'm trying to reduce the hyperlink area to just the background image.
Your markup is incredibly complex for what you are displaying.
You could have something like:
<ul>
<li>
<a>
<h2></h2>
<p></p>
</a>
</li>
<li>
<a>
<h2></h2>
<p></p>
</a>
</li>
</ul>
and add the image and the gradient using CSS.
I would use a single link tag for your button and leverage CSS gradients for the background:
* {
box-sizing: border-box;
}
body {
font-family: sans-serif;
}
.button {
background-image: linear-gradient(to bottom, #3D85C6, #07355F 50%, #07355F);
background-size: 100% 200%;
border-radius: 4px;
color: #fff;
display: block;
padding: 10px;
text-decoration: none;
transition: all 150ms ease-in-out;
}
.button:hover,
.button:focus,
.button:active {
background-position: 0 50%;
}
.button-icon {
float: left;
margin-right: 15px;
}
.button-content {
overflow: hidden;
}
.button-title {
font-size: 18px;
font-weight: bold;
}
.button-description {
font-size: 16px;
}
<a class="button" href="../Collin/misc/issues/index.html">
<div class="button-icon">
<img src="http://satyr.io/72/white?brand=github" alt=""/>
</div>
<div class="button-content">
<p class="button-title">Ask Facilities</p>
<p class="button-description">Here will be text about the button…</p>
</div>
</a>
Also here http://jsbin.com/rikisemawe/edit?html,css,output
The elements in OP were stacked in the markup, there were no nested components of the button. That would explain the unusual position coords and large padding.
Instead of <img>, background-image is used. Changed some of the tags to a real <button>, <h4> instead of <p>, etc.
SNIPPET
.button {
position: relative;
min-width: 350px;
max-width: 100%;
min-height: 95px;
height: auto;
padding: 5px 10px;
border: 0 none transparent;
border-radius: 6px;
background: url(http://www.auburn.edu/administration/facilities/home-page/buttons/images/button.png)no-repeat;
background-size: cover;
}
.background:hover .head {
color: #d76e08;
}
.text {
padding: 0 5px;
position: absolute;
left: 85px;
top: 5px;
text-align: left;
color: #def;
text-decoration: none;
}
.button:hover,
.text:hover {
text-decoration: none;
color: #def;
}
.button:hover .head {
color: gold;
}
.icon {
width: 75px;
height: 75px;
position: absolute;
top: calc(50% - 37.5px);
background: url(http://www.auburn.edu/administration/facilities/home-page/buttons/images/service-icon.png)no-repeat;
}
<link rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css'>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<div class="row">
<div class="col-sm-12">
<button class="button">
<div class="icon"></div>
<a class='text'>
<h4 class="head">Ask Facilities</h4>
<p class="content">Here will be text about the button.</p>
</a>
</button>
</div>
</div>

How can I centre an object whose height I do not know in a list?

It seems like no matter what I do I just can't get some text with a black background to centre vertically. The problem is that sometimes the text is on one line and sometimes it is on two or even three. I'm trying to get it to automatically adjust but I just can't.
I have tried numerous approaches such as those listed on here.
Here is my code I am trying to centre:
.infogrid {
display: inline-block;
position: relative;
bottom: 45px;
right: 0;
margin: 0px 1% -100% 1%;
width: 98%;
background-color: #F6F6F6;
}
.infogrid ul {
margin: 0;
padding: 0;
text-align: center;
}
.infogrid li {
display: inline-block;
position: relative;
background-color: white;
width: 320px;
margin: 1vw;
height: 320px;
transition: transform 0.4s;
box-shadow: 0.2vh 0vh 0.8vh #888888;
}
.infogrid li:hover {
transform: scale(1.05, 1.05);
}
.tilewrappertext {
display: inline-block;
color: white;
visibility: hidden;
z-index: 1;
width: 100%;
text-align: center;
font-family: "Century Gothic", "Arial", "Sans-Serif";
background-color: black;
opacity: 0.75;
font-size: 2.2em;
}
#tilewrapper:hover .tilewrappertext {
visibility: visible;
}
<div class="infogrid">
<ul>
<li>
<div id="tilewrapper">
<img id="automargins" src="content/tile1.png" width="96%">
<h3 class="tilewrappertext">Half price facials</h3>
</div>
</li>
<li>
<div id="tilewrapper">
<img id="automargins" src="content/tile2.png" width="96%">
<h3 class="tilewrappertext">1/4 off massages</h3>
</div>
</li>
<li>
<div id="tilewrapper">
<img id="automargins" src="content/tile3.png" width="96%">
<h3 class="tilewrappertext">20/3 off hot rocks</h3>
</div>
</li>
<li>
<div id="tilewrapper">
<img id="automargins" src="content/tile4.png" width="96%">
<h3 class="tilewrappertext">20/3 off nails</h3>
</div>
</li>
<li>
<div id="tilewrapper">
<img id="automargins" src="content/tile5.png" width="96%">
<h3 class="tilewrappertext">Free use of sauna with treatment</h3>
</div>
</li>
<li>
<div id="tilewrapper">
<img id="automargins" src="content/tile6.png" width="96%">
<h3 class="tilewrappertext">Free use of jacuzzi with treatment</h3>
</div>
</li>
<li>
<div id="tilewrapper">
<img id="automargins" src="content/tile7.png" width="96%">
<h3 class="tilewrappertext">1/20 off eyes</h3>
</div>
</li>
<li>
<div id="tilewrapper">
<img id="automargins" src="content/tile8.png" width="96%">
<h3 class="tilewrappertext">1/20 off hair</h3>
</div>
</li>
</ul>
</div>
The text appears when the image is hovered over.
Since your li is already position relative, you can add the following css rules to the h3 to center it vertically within the li.:
position: absolute;
top: 50%;
transform: translateY(-50%);
margin: 0;
Example here: http://codepen.io/nicerhugs/details/dMGMEv/
The top will move the top of the h3 halfway down the li, and the transform will correct for the height of the li itself. Getting rid of the margin will take away that weird mystery space that makes it appear to be lower than it really is.
Just go with the Jess's answer. Here is another method to do this using pseudo element aka ghost element in css.
You have to give absolute position to image. add a :after element to div#tilewrapper and make it display inline-block, also make the h3 tag inline-block and apply vertical-align: middle, it will position vertically middle. Little complicate to understand but anyway Here is the code . :)
.infogrid {
display: inline-block;
position: relative;
bottom: 45px;
right: 0;
margin: 0px 1% -100% 1%;
width: 98%;
background-color: #F6F6F6;
}
.infogrid ul {
margin: 0;
padding: 0;
text-align: center;
}
.infogrid li {
display: inline-block;
position: relative;
background-color: white;
width: 320px;
margin: 1vw;
height: 320px;
transition: transform 0.4s;
box-shadow: 0.2vh 0vh 0.8vh #888888;
}
.infogrid li:hover {
transform: scale(1.05, 1.05);
}
.tilewrappertext {
display: inline-block;
color: white;
visibility: hidden;
z-index: 1;
width: 100%;
text-align: center;
font-family: "Century Gothic", "Arial", "Sans-Serif";
background-color: black;
opacity: 0.75;
font-size: 2.2em;
}
#tilewrapper:hover .tilewrappertext {
visibility: visible;
}
.infogrid{
margin-top: 50px;
}
img {
max-height: 320px;
position: absolute;
}
div#tilewrapper{
height: 100%;
}
.tilewrappertext {
display: inline-block;
color: white;
visibility: hidden;
z-index: 1;
width: 100%;
text-align: center;
font-family: "Century Gothic", "Arial", "Sans-Serif";
background-color: black;
opacity: 0.75;
font-size: 2.2em;
vertical-align: middle;
display: inline-block;
vertical-align: middle;
width: calc(100% - 4px);
}
div#tilewrapper:after {
content: '';
display: inline-block;
height: 100%;
vertical-align: middle;
margin-right: -5px;
}
<div class="infogrid">
<ul>
<li>
<div id="tilewrapper">
<img id="automargins" src="http://1.bp.blogspot.com/-fqGa-MyjVHY/UZPYekbmfHI/AAAAAAAABrg/CC4q0AQsY9o/s320/air-baloon.jpg" width="96%">
<h3 class="tilewrappertext">Half price facials</h3>
</div>
</li>
</ul>
</div>

How to show text on image when hovering?

I'm trying to show a description when hovering over an image. I've already done it in a less than desirable way, using image sprites and hovers here: I want it to look exactly like how I have it, but using real text instead of an image.
I've tried a few different things but I can't seem to figure out how to do it. I'm trying to do it using HTML and CSS only, but I'm not sure if that's possible.
Feel free to poke around in my code, I'll paste what I think is relavent here.
HTML
div#projectlist {
width: 770px;
margin: 0 auto;
margin-top: 20px;
margin-bottom: 40px;
}
div#buzzbutton {
display: block;
float: left;
margin: 2px;
background: url(content/assets/thumbnails/design/buzz_sprite.jpg) 0 0px no-repeat;
width: 150px;
height: 150px;
}
div#buzzbutton:hover {
background: url(content/assets/thumbnails/design/buzz_sprite.jpg);
width: 150px;
height: 150px;
background-position: 0 -150px;
}
div#slinksterbutton {
display: block;
float: left;
background: url(content/assets/thumbnails/design/slinkster_sprite.jpg) 0 0px no-repeat;
width: 150px;
height: 150px;
margin: 2px;
}
div#slinksterbutton:hover {
background: url(content/assets/thumbnails/design/slinkster_sprite.jpg);
width: 150px;
height: 150px;
background-position: 0 -150px;
}
<div id="projectlist">
<div id="buzzbutton">
<img src="content/assets/thumbnails/transparent_150x150.png" alt="" />
</div>
<div id="slinksterbutton">
<img src="content/assets/thumbnails/transparent_150x150.png" alt="" />
</div>
</div>
It's simple. Wrap the image and the "appear on hover" description in a div with the same dimensions of the image. Then, with some CSS, order the description to appear while hovering that div.
/* quick reset */
* {
margin: 0;
padding: 0;
border: 0;
}
/* relevant styles */
.img__wrap {
position: relative;
height: 200px;
width: 257px;
}
.img__description {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: rgba(29, 106, 154, 0.72);
color: #fff;
visibility: hidden;
opacity: 0;
/* transition effect. not necessary */
transition: opacity .2s, visibility .2s;
}
.img__wrap:hover .img__description {
visibility: visible;
opacity: 1;
}
<div class="img__wrap">
<img class="img__img" src="http://placehold.it/257x200.jpg" />
<p class="img__description">This image looks super neat.</p>
</div>
A nice fiddle: https://jsfiddle.net/govdqd8y/
EDIT:
There's another option if you don't want to explicitly set the height of the <img> on the wrapping <div>, and that is simply setting the <div>'s display to inline-block. (Keep in mind, though, that it won't look good if the image fails to load.)
If you choose this option, you'll notice that there'll be a slight spacing between the <img> and the bottom of the wrapping <div>. That's because of the <img>'s default vertical-align value of baseline. If you set it to bottom it will disappear.
Here's a fiddle using this option: https://jsfiddle.net/joplomacedo/5cL31o0g/
In your HTML, try and put the text that you want to come up in the title part of the code:
<a href="buzz.html" title="buzz hover text">
You can also do the same for the alt text of your image.
You can also use the title attribute in your image tag
<img src="content/assets/thumbnails/transparent_150x150.png" alt="" title="hover text" />
This is what I use to make the text appear on hover:
* {
box-sizing: border-box
}
div {
position: relative;
top: 0px;
left: 0px;
width: 400px;
height: 400px;
border-radius: 50%;
overflow: hidden;
text-align: center
}
img {
width: 400px;
height: 400px;
position: absolute;
border-radius: 50%
}
img:hover {
opacity: 0;
transition:opacity 2s;
}
heading {
line-height: 40px;
font-weight: bold;
font-family: "Trebuchet MS";
text-align: center;
position: absolute;
display: block
}
div p {
z-index: -1;
width: 420px;
line-height: 20px;
display: inline-block;
padding: 200px 0px;
vertical-align: middle;
font-family: "Trebuchet MS";
height: 450px
}
<div>
<img src="https://68.media.tumblr.com/20b34e8d12d4230f9b362d7feb148c57/tumblr_oiwytz4dh41tf8vylo1_1280.png">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing <br>elit. Reiciendis temporibus iure dolores aspernatur excepturi <br> corporis nihil in suscipit, repudiandae. Totam.
</p>
</div>
.container {
position: relative;
width: 50%;
}
.image {
display: block;
width: 100%;
height: auto;
}
.overlay {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
height: 100%;
width: 100%;
opacity: 0;
transition: .5s ease;
background-color: #008CBA;
}
.container:hover .overlay {
opacity: 1;
}
.text {
color: white;
font-size: 20px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
}
<!DOCTYPE html>
<html>
<head></head>
<body>
<div class="container">
<img src="http://lorempixel.com/500/500/" alt="Avatar" class="image">
<div class="overlay">
<div class="text">Hello World</div>
</div>
</div>
</body>
</html>
Reference Link W3schools with multiple styles
HTML
<img id="close" className="fa fa-close" src="" alt="" title="Close Me" />
CSS
#close[title]:hover:after {
color: red;
content: attr(title);
position: absolute;
left: 50px;
}
I saw a lot of people use an image tag. I prefer to use a background image because I can manipulate it. For example, I can:
Add smoother transitions
save time not having to crop images by using the "background-size: cover;" property.
The HTML/CSS:
.overlay-box {
background-color: #f5f5f5;
height: 100%;
background-repeat: no-repeat;
background-size: cover;
}
.overlay-box:hover .desc,
.overlay-box:focus .desc {
opacity: 1;
}
/* opacity 0.01 for accessibility */
/* adjust the styles like height,padding to match your design*/
.overlay-box .desc {
opacity: 0.01;
min-height: 355px;
font-size: 1rem;
height: 100%;
padding: 30px 25px 20px;
transition: all 0.3s ease;
background: rgba(0, 0, 0, 0.7);
color: #fff;
}
<div class="overlay-box" style="background-image: url('https://via.placeholder.com/768x768');">
<div class="desc">
<p>Place your text here</p>
<ul>
<li>lorem ipsum dolor</li>
<li>lorem lipsum</li>
<li>lorem</li>
</ul>
</div>
</div>
<!DOCTYPE html><html lang='en' class=''>
<head><script src='//production-assets.codepen.io/assets/editor/live/console_runner-079c09a0e3b9ff743e39ee2d5637b9216b3545af0de366d4b9aad9dc87e26bfd.js'></script><script src='//production-assets.codepen.io/assets/editor/live/events_runner-73716630c22bbc8cff4bd0f07b135f00a0bdc5d14629260c3ec49e5606f98fdd.js'></script><script src='//production-assets.codepen.io/assets/editor/live/css_live_reload_init-2c0dc5167d60a5af3ee189d570b1835129687ea2a61bee3513dee3a50c115a77.js'></script><meta charset='UTF-8'><meta name="robots" content="noindex"><link rel="shortcut icon" type="image/x-icon" href="//production-assets.codepen.io/assets/favicon/favicon-8ea04875e70c4b0bb41da869e81236e54394d63638a1ef12fa558a4a835f1164.ico" /><link rel="mask-icon" type="" href="//production-assets.codepen.io/assets/favicon/logo-pin-f2d2b6d2c61838f7e76325261b7195c27224080bc099486ddd6dccb469b8e8e6.svg" color="#111" /><link rel="canonical" href="https://codepen.io/nelsonleite/pen/RaGwba?depth=everything&order=popularity&page=4&q=product&show_forks=false" />
<link href='https://fonts.googleapis.com/css?family=Raleway' rel='stylesheet' type='text/css'>
<link rel='stylesheet prefetch' href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css'>
<style class="cp-pen-styles">.product-description {
transform: translate3d(0, 0, 0);
transform-style: preserve-3d;
perspective: 1000;
backface-visibility: hidden;
}
body {
color: #212121;
}
.container {
padding-top: 25px;
padding-bottom: 25px;
}
img {
max-width: 100%;
}
hr {
border-color: #e5e5e5;
margin: 15px 0;
}
.secondary-text {
color: #b6b6b6;
}
.list-inline {
margin: 0;
}
.list-inline li {
padding: 0;
}
.card-wrapper {
position: relative;
width: 100%;
height: 390px;
border: 1px solid #e5e5e5;
border-bottom-width: 2px;
overflow: hidden;
margin-bottom: 30px;
}
.card-wrapper:after {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
transition: opacity 0.6s cubic-bezier(0.165, 0.84, 0.44, 1);
}
.card-wrapper:hover:after {
opacity: 1;
}
.card-wrapper:hover .image-holder:before {
opacity: .75;
}
.card-wrapper:hover .image-holder:after {
opacity: 1;
transform: translate(-50%, -50%);
}
.card-wrapper:hover .image-holder--original {
transform: translateY(-15px);
}
.card-wrapper:hover .product-description {
height: 205px;
}
#media (min-width: 768px) {
.card-wrapper:hover .product-description {
height: 185px;
}
}
.image-holder {
display: block;
position: relative;
width: 100%;
height: 310px;
background-color: #ffffff;
z-index: 1;
}
#media (min-width: 768px) {
.image-holder {
height: 325px;
}
}
.image-holder:before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #4CAF50;
opacity: 0;
z-index: 5;
transition: opacity 0.6s;
}
.image-holder:after {
content: '+';
font-family: 'Raleway', sans-serif;
font-size: 70px;
color: #4CAF50;
text-align: center;
position: absolute;
top: 92.5px;
left: 50%;
width: 75px;
height: 75px;
line-height: 75px;
background-color: #ffffff;
opacity: 0;
border-radius: 50%;
z-index: 10;
transform: translate(-50%, 100%);
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
transition: all 0.4s ease-out;
}
#media (min-width: 768px) {
.image-holder:after {
top: 107.5px;
}
}
.image-holder .image-holder__link {
display: block;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 15;
}
.image-holder .image-holder--original {
transition: transform 0.8s cubic-bezier(0.165, 0.84, 0.44, 1);
}
.image-liquid {
width: 100%;
height: 325px;
background-size: cover;
background-position: center center;
}
.product-description {
position: absolute;
left: 0;
bottom: 0;
width: 100%;
height: 80px;
padding: 10px 15px;
overflow: hidden;
background-color: #fafafa;
border-top: 1px solid #e5e5e5;
transition: height 0.6s cubic-bezier(0.165, 0.84, 0.44, 1);
z-index: 2;
}
#media (min-width: 768px) {
.product-description {
height: 65px;
}
}
.product-description p {
margin: 0 0 5px;
}
.product-description .product-description__title {
font-family: 'Raleway', sans-serif;
position: relative;
white-space: nowrap;
overflow: hidden;
margin: 0;
font-size: 18px;
line-height: 1.25;
}
.product-description .product-description__title:after {
content: '';
width: 60px;
height: 100%;
position: absolute;
top: 0;
right: 0;
background: linear-gradient(to right, rgba(255, 255, 255, 0), #fafafa);
}
.product-description .product-description__title a {
text-decoration: none;
color: inherit;
}
.product-description .product-description__category {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.product-description .product-description__price {
color: #4CAF50;
text-align: left;
font-weight: bold;
letter-spacing: 0.06em;
}
#media (min-width: 768px) {
.product-description .product-description__price {
text-align: right;
}
}
.product-description .sizes-wrapper {
margin-bottom: 15px;
}
.product-description .color-list {
font-size: 0;
}
.product-description .color-list__item {
width: 25px;
height: 10px;
position: relative;
z-index: 1;
transition: all .2s;
}
.product-description .color-list__item:hover {
width: 40px;
}
.product-description .color-list__item--red {
background-color: #F44336;
}
.product-description .color-list__item--blue {
background-color: #448AFF;
}
.product-description .color-list__item--green {
background-color: #CDDC39;
}
.product-description .color-list__item--orange {
background-color: #FF9800;
}
.product-description .color-list__item--purple {
background-color: #673AB7;
}
</style></head><body>
<!--
Inspired in this dribbble
https://dribbble.com/shots/986548-Product-Catalog
-->
<div class="container">
<div class="row">
<div class="col-xs-12 col-sm-6 col-md-4">
<article class="card-wrapper">
<div class="image-holder">
<div class="image-liquid image-holder--original" style="background-image: url('https://upload.wikimedia.org/wikipedia/commons/2/24/Blue_Tshirt.jpg')">
</div>
</div>
<div class="product-description">
<!-- title -->
<h1 class="product-description__title">
<a href="#">
Adidas Originals
</a>
</h1>
<!-- category and price -->
<div class="row">
<div class="col-xs-12 col-sm-8 product-description__category secondary-text">
Men's running shirt
</div>
<div class="col-xs-12 col-sm-4 product-description__price">
€ 499
</div>
</div>
<!-- divider -->
<hr />
<!-- sizes -->
<div class="sizes-wrapper">
<b>Sizes</b>
<br />
<span class="secondary-text text-uppercase">
<ul class="list-inline">
<li>xs,</li>
<li>s,</li>
<li>sm,</li>
<li>m,</li>
<li>l,</li>
<li>xl,</li>
<li>xxl</li>
</ul>
</span>
</div>
<!-- colors -->
<div class="color-wrapper">
<b>Colors</b>
<br />
<ul class="list-inline color-list">
<li class="color-list__item color-list__item--red"></li>
<li class="color-list__item color-list__item--blue"></li>
<li class="color-list__item color-list__item--green"></li>
<li class="color-list__item color-list__item--orange"></li>
<li class="color-list__item color-list__item--purple"></li>
</ul>
</div>
</div>
</article>
</div>
<div class="col-xs-12 col-sm-6 col-md-4">
<article class="card-wrapper">
<div class="image-holder">
<div class="image-liquid image-holder--original" style="background-image: url('https://upload.wikimedia.org/wikipedia/commons/thumb/7/75/Jeans_BW_2_(3213391837).jpg/543px-Jeans_BW_2_(3213391837).jpg')">
</div>
</div>
<div class="product-description">
<!-- title -->
<h1 class="product-description__title">
<a href="#">
Adidas Originals
</a>
</h1>
<!-- category and price -->
<div class="row">
<div class="col-sm-8 product-description__category secondary-text">
Men's running shirt
</div>
<div class="col-sm-4 product-description__price text-right">
€ 499
</div>
</div>
<!-- divider -->
<hr />
<!-- sizes -->
<div class="sizes-wrapper">
<b>Sizes</b>
<br />
<span class="secondary-text text-uppercase">
<ul class="list-inline">
<li>xs,</li>
<li>s,</li>
<li>sm,</li>
<li>m,</li>
<li>l,</li>
<li>xl,</li>
<li>xxl</li>
</ul>
</span>
</div>
<!-- colors -->
<div class="color-wrapper">
<b>Colors</b>
<br />
<ul class="list-inline color-list">
<li class="color-list__item color-list__item--red"></li>
<li class="color-list__item color-list__item--blue"></li>
<li class="color-list__item color-list__item--green"></li>
<li class="color-list__item color-list__item--orange"></li>
<li class="color-list__item color-list__item--purple"></li>
</ul>
</div>
</div>
</article>
</div>
<div class="col-xs-12 col-sm-6 col-md-4">
<article class="card-wrapper">
<div class="image-holder">
<div class="image-liquid image-holder--original" style="background-image: url('https://upload.wikimedia.org/wikipedia/commons/b/b8/Columbia_Sportswear_Jacket.jpg')">
</div>
</div>
<div class="product-description">
<!-- title -->
<h1 class="product-description__title">
<a href="#">
Adidas Originals
</a>
</h1>
<!-- category and price -->
<div class="row">
<div class="col-sm-8 product-description__category secondary-text">
Men's running shirt
</div>
<div class="col-sm-4 product-description__price text-right">
€ 499
</div>
</div>
<!-- divider -->
<hr />
<!-- sizes -->
<div class="sizes-wrapper">
<b>Sizes</b>
<br />
<span class="secondary-text text-uppercase">
<ul class="list-inline">
<li>xs,</li>
<li>s,</li>
<li>sm,</li>
<li>m,</li>
<li>l,</li>
<li>xl,</li>
<li>xxl</li>
</ul>
</span>
</div>
<!-- colors -->
<div class="color-wrapper">
<b>Colors</b>
<br />
<ul class="list-inline color-list">
<li class="color-list__item color-list__item--red"></li>
<li class="color-list__item color-list__item--blue"></li>
<li class="color-list__item color-list__item--green"></li>
<li class="color-list__item color-list__item--orange"></li>
<li class="color-list__item color-list__item--purple"></li>
</ul>
</div>
</div>
</article>
</div>
<div class="col-xs-12 col-sm-6 col-md-4">
<article class="card-wrapper">
<div class="image-holder">
<div class="image-liquid image-holder--original" style="background-image: url('http://www.publicdomainpictures.net/pictures/20000/nahled/red-shoes-isolated.jpg')">
</div>
</div>
<div class="product-description">
<!-- title -->
<h1 class="product-description__title">
<a href="#">
Adidas Originals
</a>
</h1>
<!-- category and price -->
<div class="row">
<div class="col-sm-8 product-description__category secondary-text">
Men's running shirt
</div>
<div class="col-sm-4 product-description__price text-right">
€ 499
</div>
</div>
<!-- divider -->
<hr />
<!-- sizes -->
<div class="sizes-wrapper">
<b>Sizes</b>
<br />
<span class="secondary-text text-uppercase">
<ul class="list-inline">
<li>xs,</li>
<li>s,</li>
<li>sm,</li>
<li>m,</li>
<li>l,</li>
<li>xl,</li>
<li>xxl</li>
</ul>
</span>
</div>
<!-- colors -->
<div class="color-wrapper">
<b>Colors</b>
<br />
<ul class="list-inline color-list">
<li class="color-list__item color-list__item--red"></li>
<li class="color-list__item color-list__item--blue"></li>
<li class="color-list__item color-list__item--green"></li>
<li class="color-list__item color-list__item--orange"></li>
<li class="color-list__item color-list__item--purple"></li>
</ul>
</div>
</div>
</article>
</div>
</div>
</div>
</body></html>
The sample is made
<html>
<head>
<style>
.hide {
display: none;
}
.myDIV:hover + .hide {
display: block;
color: red;
}
</style>
</head>
<body>
<h2>Display an Element on Hover</h2>
<div class="myDIV">Hover over me.</div>
<div class="hide">I am shown when someone hovers over the div above.</div>
</body>
</html>
For accessibility reasons, you should use the correct semantic tags. Use a figure as a container and include the text to the image as figcaption.
Apply position: absolute to the container and then position: absolute to the figcaption.
Simply hide the figcaption with display: block and make it visible again by using :hover on the wrapping figure element.
figure {
position: relative;
}
figcaption {
position: absolute;
inset: 2px;
display: none;
}
figure:hover figcaption {
display: flex;
}
/* for visualization only */
figure {
display: inline-block;
}
figcaption {
padding: 1em;
justify-content: center;
align-items: center;
background-color: rgba(255, 255, 255, 0.7);
}
img {
border: 2px dashed red;
}
<figure>
<img src="https://via.placeholder.com/200.jpg" alt="placeholder image used for demonstration">
<figcaption>placeholder image used for demonstration</figcaption>
</figure>