Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to give a cover to auto-scale image with CSS only?

Tags:

html

css

image

It is well known that using max-height and max-width can make an image auto fit in a div, like the following:

.cover img {
    max-width: 100%;
    max-height: 100%;
}

Is there a way to make a translucent cover (by setting opacity: 0.8 to a div) that just fit the size of the image without getting the width and height by javascript?

The following is my attempt in jsfiddle. I can only make it cover the whole container, but what I want is just to cover the image only. The size of the image is variable as they are to be uploaded by user. https://jsfiddle.net/muorou0c/1/

like image 688
cytsunny Avatar asked Dec 24 '15 07:12

cytsunny


People also ask

How do I Auto size an image in CSS?

Answer: Use the CSS max-width Property You can simply use the CSS max-width property to auto-resize a large image so that it can fit into a smaller width <div> container while maintaining its aspect ratio.

How do I make an image scale proportionally CSS?

In that situation we can use CSS max-width or width to fit the image. Use max-width: 100% to limit the size but allow smaller image sizes, use width: 100% to always scale the image to fit the parent container width.

How do I resize an image in HTML CSS?

One of the simplest ways to resize an image in the HTML is using the height and width attributes on the img tag. These values specify the height and width of the image element. The values are set in px i.e. CSS pixels. For example, the original image is 640×960.

How do I resize an image without losing quality CSS?

Use object fit property in your css, and give a fixed width and height to your image tag or respective class so that every image will have same width and height, Now Your Image won't be distorted.


Video Answer


6 Answers

Here's a simple flexbox-solution that should be quite straight forward:

.container {
  display: block;
  height: 300px;
  width: 300px;
  background-color: #000;
  border: 2px solid red;
  display: flex;
  align-items: center;
  justify-content: center;
}
.inner {
  position: relative;
}
.container img {
  max-width: 300px;
  max-height: 300px;
  display: block;
}
.cover {
  display: none;
}
.container:hover .cover{
  display: block;
  position: absolute;
  top: 0px;
  left: 0px;
  height: 100%;
  width: 100%;
  background-color: #FFF;
  opacity: 0.8;
}
<div class="container">
  <div class="inner">
    <img src="http://lorempixel.com/400/200/">
    <div class="cover"></div>
  </div>
</div>

<div class="container">
  <div class="inner">
    <img src="http://lorempixel.com/400/800/">
    <div class="cover"></div>
  </div>
</div>

There are three parts that makes this solution work:

  1. Hard coded container size on img tag (as max-width: 300px, max-height: 300px), to maintain aspect ratio and size.
  2. Using an inner container div that wraps the boundaries for the cover layer, setting the boundary as to how big the cover can be. The .cover could be replaced with a ::before or ::after pseudo element, see the alternative fiddle below.
  3. Using flexbox to center the inner container in the outer container. This could also be done using the position absolute + translate3d trick used to position the .cover element in the original question, see the alternative fiddle below.

Here's a fiddle with the alternative solutions from point 2 & 3 above: https://jsfiddle.net/muorou0c/18/

like image 189
Johan Persson Avatar answered Oct 17 '22 15:10

Johan Persson


I have adapted your fiddle, and added an extra layer under container

.container {
  position: relative;
  display: block;
  height: 300px;
  width: 300px;
  max-height: 300px;
  max-width: 300px;
  background-color: #000;
  border: 2px solid red;
}

.container2 {
  max-width: inherit;
  max-height: inherit;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%,-50%);
  border: 2px solid cyan;
}

.container2 img {
  max-height: inherit;
  max-width: inherit;
}

.cover {
  display: none;
}
.container:hover .cover{
  display: block;
  position: absolute;
  top: 0px;
  left: 0px;
  height: 100%;
  width: 100%;
  background-color: #FFF;
  opacity: 0.8;
}
<div class="container">
  <div class="container2">
  <img src="http://lorempixel.com/400/200/">
      <div class="cover"></div>
  </div>
</div>

<div class="container">
  <div class="container2">
  <img src="http://lorempixel.com/400/800/">
  <div class="cover"></div>
  </div>
</div>

This works by setting to container a max-height ans max-width. This go to the image via inherit values.

Then the image gets its dimension.

And the container2 element gets it's dimension from the child.

and finally cover uses the dimension from container2

like image 42
vals Avatar answered Oct 17 '22 14:10

vals


If it fits your needs, there are a lot of filters you can add over you image(rather than covering it with a colored div). Here's a example.

img:hover{
  -webkit-filter:  brightness(200%); 
  filter:  brightness(200%);
}
like image 28
miraco Avatar answered Oct 17 '22 16:10

miraco


.container {
  position: relative;
  display: block;
  height: 300px;
  width: 300px;
  background-color: #000;
  border: 2px solid red;
}
.container img {
    position: absolute;
    display: block;
    top: 50%;
    left: 50%;
    transform: translate(-50%,-50%);
    object-fit: cover;
    object-position: center;
    height: 100%;
    width: 100%;
}
.cover {
  display: none;
}
.container:hover .cover{
  display: block;
  position: absolute;
  top: 0px;
  left: 0px;
  height: 100%;
  width: 100%;
  background-color: #FFF;
  opacity: 0.8;
}
<div class="container">
  <img src="http://lorempixel.com/400/200/">
  <div class="cover"></div>
  </div>
</div>

<div class="container">
  <img src="http://lorempixel.com/400/800/">
  <div class="cover"></div>
</div>
like image 41
Amir Naeem Avatar answered Oct 17 '22 15:10

Amir Naeem


Ok I made some modification to the way your code was organised.

.container {
  position: relative;
  display: block;
  height: 300px;
  width: 300px;
  background-color: #000;
  border: 2px solid red;
}
.image {
  display: block;
  content: "";
  width:auto;
  position: relative;
  max-width: 100%;
  max-height: 100%;
  top: 50%;
  left: 50%;
  transform: translate(-50%,-50%);
  background-image: url("http://lorempixel.com/400/200/");
}
.image:hover:after{
  display:block;
  content: "";
  position: absolute;
  top: 0;
  width: 100%;
  height: 100%;
  background-color: #fff;
  opacity: .5; /* if needed */
}
<div class="container">
  <div class="image">
     <img src="http://lorempixel.com/400/200/" style="visibility:hidden"/>
  </div>
</div>

The time when you are constructing your html add the img element for maintaining the height of the container using javascript. I think in case of an uploaded image scenario the html must be constructed dynamically.

references

Overlay image on dynamically sized div

How to get div height to auto-adjust to background size?

Why don't :before and :after pseudo elements work with `img` elements?

like image 1
harshitpthk Avatar answered Oct 17 '22 15:10

harshitpthk


Sounds like a job for a pseudo element.

.container{
     background:yellow;
     border:2px solid red;
     width:300px;
     height:300px;
     text-align:center;
}

.container:before{ 
    content: "";
    display: inline-block;
    vertical-align: middle;
    height: 100%;
  }

.cover{
        position:relative;
        display:inline-block;
        vertical-align:middle;
    }
    
 .cover:hover:after{
        content:"";
        position:absolute;
        top:0;
        left:0;
        right:0;
        bottom:0;
        max-width:inherit;
        max-height:inherit;
        opacity:.5;
        background:blue;
    }

.container img{
    display:block;
    max-width:300px;
    max-height:300px;
}
<div class="container"><div class="cover"><img src="http://lorempixel.com/400/200/"/></div></div>

Just assign the background property to the .cover:after selector to get the overlay.

like image 1
Donnie D'Amato Avatar answered Oct 17 '22 16:10

Donnie D'Amato