CSS <a> with <img> expand to fill space [duplicate] - css

This question already has answers here:
Image inside div has extra space below the image
(10 answers)
Closed 11 months ago.
The community reviewed whether to reopen this question 11 months ago and left it closed:
Original close reason(s) were not resolved
Run the code snippet below, drag to resize smaller and larger - vertically and horizontally. Note that the image will resize to the smaller of it's natural dimensions or the extrinsic box size, which isn't it's direct <a> parent but the <div> above
This is nearly perfect, but I can't figure out the tiny details, easily identifiable in DevTools by hovering the <a> element (none of the red background should be visible)
I need the anchor to cover the <img>, which is restricted in size by the #extrinsicSize div
I also have issues with working solutions when it comes to Firefox and Safari, my best attempt was using a vertical flex box with justify/align start
div#someParent {
height: 100px;
width: 200px;
resize: both;
overflow: auto;
background: lightgrey;
padding: 5px;
}
div#extrinsicSize {
width: 100%;
height: 100%;
max-width: 100%;
max-height: 100%;
}
a {
background: red;
}
img {
background: lightgreen;
display: inline-block;
max-height: 100%;
max-width: 100%
}
<div id="someParent">
<div id="extrinsicSize">
<a href>
<img src="https://res.cloudinary.com/crunchbase-production/image/upload/c_lpad,h_256,w_256,f_auto,q_auto:eco,dpr_1/v1488264559/cbgqpe9icin2ntbpguyc.png" />
</a>
</div>
</div>
<div>
--------------------- Drag to resize ^
</div>

I fix your css. Please kindly check below if you like or not.
div#someParent {
height: 100px;
width: 200px;
resize: both;
overflow: auto;
background: lightgrey;
padding: 5px;
}
div#extrinsicSize {
width: 100%;
height: 100%;
max-width: 100%;
max-height: 100%;
}
a {
background: red;
display: block;
width: 100%; height: 100%;
}
img {
background: lightgreen;
width: 100%;
height: 100%;
object-fit: cover;
}
<div id="someParent">
<div id="extrinsicSize">
<a href>
<img src="https://res.cloudinary.com/crunchbase-production/image/upload/c_lpad,h_256,w_256,f_auto,q_auto:eco,dpr_1/v1488264559/cbgqpe9icin2ntbpguyc.png" />
</a>
</div>
</div>
<div>
--------------------- Drag to resize ^
</div>

Related

Image is larger than overlay element by 1px

I am trying to overlay an image using a pseudo-element that is aligned to the bottom of a parent element. Then parent then hides part of both the image and the pseudo element using overflow: hidden. This should make the parent clip both the image and the pseudo element at the same place. However the image extends beyond the pseudo element by 1px. This happens in both Chrome and IE at specific breakpoints.
I inserted the code to stackoverflow but I can not reproduce using their code viewer. I can however reproduce on codepen using a screen width of 800px:
https://codepen.io/dwigt/pen/PXyrXq
.wrapper {
margin: auto;
}
.item {
background: lightgrey;
max-height: 500px;
min-height: 500px;
height: 100%;
max-width: 800px;
}
.image {
overflow: hidden;
max-height: 250px;
position: relative;
}
.image img {
max-height: 100%;
width: 100%;
position: relative;
}
.image::after {
z-index: 10;
content: "";
position: absolute;
left: -50%;
top: calc(80%);
width: 200%;
height: 200%;
display: block;
background: lightgrey;
border-radius: 100%;
}
<div class="wrapper">
<div class="item">
<div class="image">
<img src="https://images.unsplash.com/photo-1547039963-8bebea5ff026?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1933&q=80"/>
</div>
<div class="text">
Lorem Ipsum
</div>
</div>
</div>

Center/middle align element larger than container [duplicate]

This question already has answers here:
Is there an equivalent to background-size: cover and contain for image elements?
(14 answers)
Closed 5 years ago.
EDIT: Trying to reword the question so that the problem is understood correctly
I have a div element within which there is a video element. The div element is resizable. The video element needs to be resizable too but it also needs to keep its original aspect ratio.
.container {
background: #ff9;
height: 150px;
width: 100px;
}
.subcontainer {
background: #9ff;
min-width: 100%;
min-height: 100%;
margin: 5px;
}
.fixedsize{
background: #9f9;
}
<div class="container">
<div class="subcontainer">
<video class="fixedsize" src="https://media.giphy.com/media/3ohryjnGyiSRrGWKn6/giphy-hd.mp4" poster="https://media.giphy.com/media/3ohryjnGyiSRrGWKn6/giphy_s.gif" autoplay="" loop="" playsinline=""></video>
</div>
</div>
So I need, the video element here to be centered both horizontally and vertically without losing the aspect ratio of it.
.container {
background: #ff9;
height: 400px;
width: 1000px;
}
.subcontainer {
background: #9ff;
min-width: 100%;
min-height: 100%;
margin: 5px;
}
.fixedsize {
background: #9f9;
}
<div class="container">
<div class="subcontainer">
<video class="fixedsize" src="https://media.giphy.com/media/3ohryjnGyiSRrGWKn6/giphy-hd.mp4" poster="https://media.giphy.com/media/3ohryjnGyiSRrGWKn6/giphy_s.gif" autoplay="" loop="" playsinline=""></video>
</div>
</div>
In this case, I want the video to stretch vertically and then centered horizontally.
Similar case for where the width of container is greater than the video width; I'd want the video to stretch horizontally and centered vertically.
Is this possible with only css?
max-width and max-height both set to 100% will force the element to stay smaller than its parent. The aligment is the same as one would usually do to center a block element.
.container {
background: #ff9;
height: 150px;
width: 100px;
//overflow: hidden;
}
.subcontainer {
background: #9ff;
min-width: 100%;
min-height: 100%;
margin: 5px;
//overflow: hidden;
position: relative;
}
.fixedsize{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
max-width: 100%;
max-height: 100%;
background: #9f9;
}
<div class="container">
<div class="subcontainer">
<video class="fixedsize" src="https://media.giphy.com/media/3ohryjnGyiSRrGWKn6/giphy-hd.mp4" poster="https://media.giphy.com/media/3ohryjnGyiSRrGWKn6/giphy_s.gif" autoplay="" loop="" playsinline=""></video>
</div>
</div>

Scale image within parent, retaining perspective, when larger then X

Trying to get a CSS only solution for the following problem.
I would like to display a variety of sized images within a container. If the image is larger then 80% viewport height, it should be scaled down to fit within the container.
Problem I am having is scaling to both a max-height and max-width (in order to accommodate both landscape and portrait images).
Here is a non-working JSFiddle as a starting point. None of the images should flow outside of the gray box.
https://jsfiddle.net/0h5zkk0z/2/
<div id="container">
<img src="http://dummyimage.com/200x200/000/fff/?text=small" />
</div>
<div id="container">
<img src="http://dummyimage.com/400x700/000/fff/?text=portrait" />
</div>
<div id="container">
<img src="http://dummyimage.com/600x400/000/fff/?text=landscape" />
</div>
<style>
#container {
max-height: 80vh;
background-color: #ccc;
position: relative;
margin-bottom: 30px;
}
#container IMG {
margin: 0 auto;
display: block;
width: auto;
height: 100%;
}
</style>
.container {
max-height: 80vh;
background-color: #ccc;
position: relative;
margin-bottom: 30px;
}
.container img {
margin: 0 auto;
display: block;
width: auto;
max-height: inherit; //Inherits from container height
}
Btw: Please use an ID only once :-)
Fiddle

How to position an image of different size using css?

I have two images of different width and height that need to be positioned bottom centered within the image box. Here is the HTML and CSS example.
<div class="box">
<div class='image'>
<img alt="" src="image.jpg"/>
</div>
</div>
.box {
max-width: 970px;
height: 440px;
}
.box img {
max-width: 100%;
position: absolute;
bottom: 8px;
margin-left: auto;
margin-right: auto;
}
This code works fine for a large image of exact width and height. But when a smaller image is placed within image box, that image is centered bottom right. How can I make both images center bottom?
Thanks for anyone's help!
Here you go... I'll try to explain as we go, but short answer, a fiddle
.box {
/* Just so I could see the parent */
background-color: #bada55;
max-width: 970px;
height: 440px;
/* Needed to make this element positional (so it will contain the absolutely positioned child */
position: relative;
/* Yep, center wasn't necessary here... */
}
.box .image { /* move this to the image wrapper */
position: absolute;
bottom: 8px;
/* Force full width */
left: 0;
right: 0;
/* Center contents (the image) */
text-align: center;
}
img {
max-width: 100%;
}
I found this semantic trick to work pretty well (without any absolute positions)
.box {
margin: 0;
text-align: center;
max-width: 970px;
height: 440px;
border:2px solid red;
}
.box .something-semantic {
display: table;
width: 100%;
height: 100%;
}
.box .something-else-semantic {
display: table-cell;
text-align: center;
vertical-align: bottom;
}
html
<div class="box">
<div class="something-semantic">
<div class="something-else-semantic">
<img src="" width="50" height="40"/>
<img src="" width="120" height="70"/>
</div>
</div>
</div>
fiddle here.

Child with max-height: 100% overflows parent

I'm trying to understand what appears to be unexpected behaviour to me:
I have an element with a max-height of 100% inside a container that also uses a max-height but, unexpectedly, the child overflows the parent:
.container {
background: blue;
padding: 10px;
max-height: 200px;
max-width: 200px;
}
img {
display: block;
max-height: 100%;
max-width: 100%;
}
<div class="container">
<img src="http://placekitten.com/400/500" />
</div>
This is fixed, however, if the parent is given an explicit height:
.container {
background: blue;
padding: 10px;
max-height: 200px;
max-width: 200px;
height: 200px;
}
img {
display: block;
max-height: 100%;
max-width: 100%;
}
<div class="container">
<img src="http://placekitten.com/400/500" />
</div>
Does anyone know why the child would not honour the max-height of its parent in the first example? Why is an explicit height required?
When you specify a percentage for max-height on a child, it is a percentage of the parent's actual height, not the parent's max-height, oddly enough. The same applies to max-width.
So, when you don't specify an explicit height on the parent, then there's no base height for the child's max-height to be calculated from, so max-height computes to none, allowing the child to be as tall as possible. The only other constraint acting on the child now is the max-width of its parent, and since the image itself is taller than it is wide, it overflows the container's height downwards, in order to maintain its aspect ratio while still being as large as possible overall.
When you do specify an explicit height for the parent, then the child knows it has to be at most 100% of that explicit height. That allows it to be constrained to the parent's height (while still maintaining its aspect ratio).
.container {
background: blue;
padding: 10px;
max-height: 200px;
max-width: 200px;
float: left;
margin-right: 20px;
}
.img1 {
display: block;
max-height: 100%;
max-width: 100%;
}
.img2 {
display: block;
max-height: inherit;
max-width: inherit;
}
<!-- example 1 -->
<div class="container">
<img class='img1' src="http://via.placeholder.com/350x450" />
</div>
<!-- example 2 -->
<div class="container">
<img class='img2' src="http://via.placeholder.com/350x450" />
</div>
I played around a little. On a larger image in firefox, I got a good result with using the inherit property value. Will this help you?
.container {
background: blue;
padding: 10px;
max-height: 100px;
max-width: 100px;
text-align:center;
}
img {
max-height: inherit;
max-width: inherit;
}
Instead of going with max-height: 100%/100%, an alternative approach of filling up all the space would be using position: absolute with top/bottom/left/right set to 0.
In other words, the HTML would look like the following:
<div class="flex-content">
<div class="scrollable-content-wrapper">
<div class="scrollable-content">
1, 2, 3
</div>
</div>
</div>
.flex-content {
flex-grow: 1;
position: relative;
width: 100%;
height: 100%;
}
.scrollable-content-wrapper {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
overflow: auto;
}
.scrollable-content {
/* Add styling here */
}
Try it below:
.flex-content {
flex-grow: 1;
position: relative;
width: 100%;
height: 100%;
}
.scrollable-content-wrapper {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
overflow: auto;
}
html {
height: 50%;
width: 50%;
}
body {
height: 100%;
width: 100%;
}
.parent {
height: 100%;
outline: 1px solid red;
}
<html>
<body>
<div class="parent">
<div class="flex-content">
<div class="scrollable-content-wrapper">
<div class="scrollable-content" id="scrollable">
1, 2, 3
</div>
</div>
</div>
</div>
<button onClick="scrollable.innerText += '\nSome more text'" style="margin-top: 1rem;">Add Line</button>
<p>
The red outline represents the parent. Click above to add a line until overflow occurs to see that the size of the parent is not increased.
</p>
</body>
</html>
I found a solution here:
http://www.sitepoint.com/maintain-image-aspect-ratios-responsive-web-design/
The trick is possible because it exists a relation between WIDTH and PADDING-BOTTOM of an element. So:
parent:
container {
height: 0;
padding-bottom: 66%; /* for a 4:3 container size */
}
child (remove all css related to width, i.e. width:100%):
img {
max-height: 100%;
max-width: 100%;
position: absolute;
display:block;
margin:0 auto; /* center */
left:0; /* center */
right:0; /* center */
}
You can use the property object-fit
.cover {
object-fit: cover;
width: 150px;
height: 100px;
}
Like suggested here
A full explanation of this property by Chris Mills in Dev.Opera
And an even better one in CSS-Tricks
It's supported in
Chrome 31+
Safari 7.1+
Firefox 36+
Opera 26+
Android 4.4.4+
iOS 8+
I just checked that vivaldi and chromium support it as well (no surprise here)
It's currently not supported on IE, but... who cares ? Also, iOS supports object-fit, but not object-position, but it will soon.
Here is a solution for a recently opened question marked as a duplicate of this question. The <img> tag was exceeding the max-height of the parent <div>.
Broken: Fiddle
Working: Fiddle
In this case, adding display:flex to the 2 parent <div> tags was the answer
Maybe someone else can explain the reasons behind your problem but you can solve it by specifying the height of the container and then setting the height of the image to be 100%. It is important that the width of the image appears before the height.
<html>
<head>
<style>
.container {
background: blue;
padding: 10px;
height: 100%;
max-height: 200px;
max-width: 300px;
}
.container img {
width: 100%;
height: 100%
}
</style>
</head>
<body>
<div class="container">
<img src="http://placekitten.com/400/500" />
</div>
</body>
</html>
The closest I can get to this is this example:
http://jsfiddle.net/YRFJQ/1/
or
.container {
background: blue;
border: 10px solid blue;
max-height: 200px;
max-width: 200px;
overflow:hidden;
box-sizing:border-box;
}
img {
display: block;
max-height: 100%;
max-width: 100%;
}
The main problem is that the height takes the percentage of the containers height, so it is looking for an explicitly set height in the parent container, not it's max-height.
The only way round this to some extent I can see is the fiddle above where you can hide the overflow, but then the padding still acts as visible space for the image to flow into, and so replacing with a solid border works instead (and then adding border-box to make it 200px if that's the width you need)
Not sure if this would fit with what you need it for, but the best I can seem to get to.
A good solution is to not use height on the parent and use it just on the child with View Port :
Fiddle Example: https://jsfiddle.net/voan3v13/1/
body, html {
width: 100%;
height: 100%;
}
.parent {
width: 400px;
background: green;
}
.child {
max-height: 40vh;
background: blue;
overflow-y: scroll;
}
Containers will already generally wrap their content nicely. It often doesn't work as well the other way around: children don't fill their ancestors nicely. So, set your width/height values on the inner-most element rather than the outer-most element, and let the outer elements wrap their contents.
.container {
background: blue;
padding: 10px;
}
img {
display: block;
max-height: 200px;
max-width: 200px;
}
http://jsfiddle.net/mpalpha/71Lhcb5q/
.container {
display: flex;
background: blue;
padding: 10px;
max-height: 200px;
max-width: 200px;
}
img {
object-fit: contain;
max-height: 100%;
max-width: 100%;
}
<div class="container">
<img src="http://placekitten.com/400/500" />
</div>

Resources