how to size next js 13 images - html

I am building a responsive website and I have been struggling to get the sizing right.
This is how my image looks like on mobile, which is correct:
Now when I switch over to desktop screen view, the image is way too big.
I will try describe how I want the image to behave:
On mobile screen on bottom of screen, just like it is now.
On Desktop screen, I want to image on bottom right corner of the current view. Basically in the red rectangle I have drawn. I don't want it to have it fixed height and width because I need it to grow and shrink responsively.
this is the relevant html code
<section class="page_hero-section__MZdi7">
<div class="page_hero-con__ijIdx">
<a>particulieren</a>
<h2>(zorg-)organisaties</h2>
<p>Ontlast de werkvloer. Onze x komen op locatie en zorgen voor een stralende lach voor clienten én medewerkers.</p>
<button>werkwijze</button><button>get started</button>
</div>
<div class="page_hero-join-con__AkBR0">
<Image alt="cool girl with colorful glasses"
src={coolGirlGlasses}
\>
<div>
<p>werken bij ons?</p>
<span>
<hr>
</span>
<a>join the crew</a>
</div>
</div>
<div class="page_hero-werkwijze__IoSuu">
<p>werkwijze</p>
<div class="page_hero-werkwijze-line__ccNUj"></div>
</div>
</section>
this is the relevant css
.hero-section {
position: relative;
display: flex;
height: calc(100vh - var(--header-height));
flex-direction: column;
justify-content: space-between;
}
img {
display: block;
max-width: 100%;
height: auto;
}
If i give the image a height of 100% it is bigger than its container.
I have also tried giving the image object-fit: contain but it changed nothing.

fixed it.
By adding flex: 1 to the parent element hero-join-con of the img and adding fill={true} on the <Image /> react element and adding object-fit: contain and object-position: right bottom to hero-con-join img.
object-fit didn't work out earlier because I was missing the fill={true} property.

Related

How to make image nested in div fill the remaining space on the page?

I'm learning CSS and got stuck creating a layout that contains a header and an image that fills the rest of the screen. Using the following code, I'm able to achieve what I'm looking for:
html, body {
height: 100%;
margin: 0;
}
.container {
display: flex;
flex-direction: column;
height: 100%;
}
.image-container {
flex: 1;
}
img {
width: 100%;
height: 100%;
object-fit: contain;
}
<html>
<body>
<div class="container">
<div class="header">
<h1>Test Page</h1>
</div>
<!-- <div class="image-container"> -->
<img src="https://picsum.photos/500/300"/>
<!-- </div> -->
</div>
</body>
</html>
Now the problem is that I want to wrap the image element into a div as I'd like to position an overlay on top of the image. As soon as I nest the img within a div, the resizing doesn't work properly anymore. If the screen is wide, the image overflows to the bottom, creating a vertical scrollbar.
I've tried a lot of things, but nothing's worked so far. Can you explain to me why introducing the div (image-container) changes the layout and how to make it behave like the version without the div? That'd be great, thanks in advance!
EDIT:
I want the image to be displayed exactly like in the snippet I posted. It should be as large as possible, but only so large that the whole image is still visible and nothing is cropped. For a wide window, there should be blank bars left and right of the image. For a narrow but tall window, there should be blank bars above/beyond the image.
My issue is that as soon as I add the <div class="image-container">, the image always takes the whole width. For a wide window, I get scrollbars and can't see the whole image anymore. I'd like to know how I can get the image to scale like in the version without the additional <div>. I'd also like to understand why adding the <div> changes how the image is scaled.
EDIT 2:
Someone suggested to add overflow: hidden; on .image-container, but deleted their answer. This does in fact work (overflow: hidden/scroll/auto; work, overflow: visible; does not), but now I'm completely confused to why that's the case. I thought that overflow would control if overflow is visible, but wouldn't affect the size of the content being displayed. In this case though, it seems like the overflow property does have an effect on the size of the picture being displayed. That's weird and if anyone knows what's going on, please let me know!
Flex is already helping the image take up as much space as possible, so the height: 100% and width: 100% were causing the image to grow.
For getting something to appear on top of the image, I would recommend looking into position: absolute or position: relative
html,
body {
height: 100%;
margin: 0;
}
.container {
display: flex;
flex-direction: column;
height: 100%;
}
.image-container {
display: flex;
justify-content: center;
}
img {
object-fit: contain;
}
<html>
<body>
<div class="container">
<div class="header">
<h1>Test Page</h1>
</div>
<div class="image-container">
<img src="https://picsum.photos/500/300" />
</div>
</div>
</body>
</html>

Remove whitespace from left and right of resized image

I have a fixed height container in which I'd like to display an image and a caption. The requirement is that the image should scale to fit the available height while maintaining aspect ratio. The caption could be of variable height.
Below is a JS fiddle of what I have so far. I am unable to get the whitespace on the right and left side of the images to disappear (I've added a border to the img tag to show what I mean). Is it possible to remove the excess whitespace?
https://jsfiddle.net/peL1a7vj/1/
HTML
<div class="container">
<div class="item">
<img class="image" src="https://www.stockvault.net/data/2009/07/14/109489/thumb16.jpg"/>
<div class="text">
Caption 1
</div>
</div>
<div class="item">
<img class="image" src="https://images.unsplash.com/photo-1591870509558-26b7eee6d549"/>
<div class="text">
Caption 2
</div>
</div>
</div>
CSS
.container {
height: 200px;
flex: 1 1 auto;
display: flex;
flex-flow: row nowrap;
overflow-x: auto;
overflow-y: hidden;
}
.item {
display: flex;
flex-direction: column;
}
.text {
flex: 0 0 auto;
}
.image {
flex: 1 1 auto;
overflow: hidden;
object-fit: contain;
max-height: 100%;
width: auto;
border: solid;
}
This is similar to CSS object-fit: contain; is keeping original image width in layout but I was unable to fix it using the methods suggested in the accepted answer
"The requirement is that the image should scale to fit the available height while maintaining aspect ratio" - that's what it does in your code! If you would stretch the width ("to fill the whitespace"), either you would loose the aspect ratio and get a distorteded image, or - if the ratio is kept - the top and bottom of the image would be cut off since it would grow due to the extended width.
There is no other solution: Either there is some whitespace, or some of the image is cut off, or the image is distorted. Unless you change the dimensions of the parent container:
The only situation where your wish could be fulfilled: When the parent of the image has the same height/width proportion as the original image. So you would have to set height and width for the container accoring to the proportions of the image.

Why is wrapping image with <a href> link changing the layout of the page?

Adding < a href> to images makes the box around the image larger and forces the text on the right hand side of the image further right. I would like to make the image link to another page while keeping the current format.
I tried adding to the image (alt is connector) (shown below), but it didn't work. (https://www.w3schools.com/html/html_images.asp - Image as a Link
uses around ).
I would expect adding the to the image would simply make the image link to another page, but it changed the size of the box for the image and pushed the text to the right of the image further right.
Page: https://www.flexsweep.com/pages/aboutourproducts (shows layout as it should be - provides access to inspect if needed.)
/*Image and Advantages*/
.content {
display: flex;
align-items: flex-start;
justify-content: flex-start;
}
.content img {
width: 50%;
margin-right: 70px;
}
.details {
width: 50%;
}
<div id="PushBrooms" class="tabcontent">
<p>Intro text.</p>
<div class="content">
<img src="https://cdn.shopify.com/s/files/1/2355/6001/files/BlackConnector.PushBroom.White.Smooth.jpg?765" alt="Connector" />
<div class="details">
<p>
More text.
<div>Shop Push Brooms →</div>
</p>
</div>
</div>
<!-- Attempt to add link to image -->
<img src="https://cdn.shopify.com/s/files/1/2355/6001/files/BlackConnector.PushBroom.White.Smooth.jpg?765" alt="Connector" />
IMG tags behave special as they are a mixture of "block" (have height and width) and "inline" (float around text) elements. Here's some good information about this topic if you want to learn more about it.
Images in <a> tags have an extra bit of padding at the footer which you can get rid of by applying display:block; to the element. Also make sure that there is no extra margin or padding applied by some other rules:
a img {
padding: 0;
margin: 0;
display: block;
}
Here's a demo with some colored backgrounds to show you which element applies padding or margin.
The original image is sized at 50% width from the CSS rule on .content img. This only affects img tags that are descendants of elements with the content class. If you apply content to the link, it will work as you expect.
Edit: Noticed this will not work if you place it inside all inside another content container because the relative width is calculated from the parent, which in the second case will be the a element and not the content div. I updated the snippet to size descendant links of content to be sized at 50% width and the contained images to be 100%.
To address the small amount of padding at the bottom of the link, you can use the solution provided in Sascha's answer
/*Image and Advantages*/
.content {
display: flex;
align-items: flex-start;
justify-content: flex-start;
}
.content img {
width: 50%;
}
.link-wrap {
width: 50%;
}
.link-wrap img {
width: 100%;
}
.details {
width: 50%;
}
<div id="PushBrooms" class="tabcontent">
<p>Intro text.</p>
<div class="content">
<img src="https://cdn.shopify.com/s/files/1/2355/6001/files/BlackConnector.PushBroom.White.Smooth.jpg?765" alt="Connector" />
<div class="details">
<p>
More text. </p>
<div>Shop Push Brooms →</div>
</div>
</div>
<!-- Attempt to add link to image -->
<div class="content">
<a class="link-wrap" href="www.flexsweep.com"><img src="https://cdn.shopify.com/s/files/1/2355/6001/files/BlackConnector.PushBroom.White.Smooth.jpg?765" alt="Connector" /></a>
<div class="details">
<p>
More text.</p>
<div>Shop Push Brooms →</div>
</div>
</div>

Flexbox gallery layout without stretching images of different sizes

I've been trying to achieve something like this gallery style layout using flexbox: Example of desired outcome
I want images (regardless of size) to sit next to each other in a two column layout until mobile layout where it's only 1 image for each line. When the two images sit next to each other I want them to scale to the size of the largest one of the two without stretching or distorting either picture.
My current attempt can be found here: Codepen
You can see that I've tried two methods, each have resulted in different problems.
I'll stick to the stretched image issue as that's currently closest to my desired outcome.
<div class="wrapper">
<header>
MY HEADER
</header>
<section>
<a href="" class= "unitie">
<img src="http://www.landscapes.org/london/wp-content/uploads/sites/8/2015/09/roadmap-to-landscapes-finance.jpg" />
</a>
<a href="" class= "meow">
<img src="https://s-media-cache-ak0.pinimg.com/originals/bd/99/3e/bd993e9921e1131fef606fcd99a03494.png" />
</a>
</section>
<footer>
2016
</footer>
</div>
CSS:
.wrapper {
display: flex;
flex-direction: column;
}
header {
display: flex;
}
section {
display: flex;
flex-flow: row wrap;
}
a {
width: 48%;
margin-left: 10px;
}
img {
max-width: 100%;
height: 100%;
}
I found this idea online: Using aspect ratio for flex property
But I have no idea how to find the aspect ratio of any image and convert it into the flex grow property value like he did.
Any help would be much appreciated.
Lot going on here.
First, make sure all your html tags close correctly.
Second, its class="name" not class "name"
Finally, the only way to make an html, inline image to fit a container is to have remove it from pageflow and then absolute position it so it is either taller or wider than its container based on the image properties.
The easiest way to do this is to move it into a css background image.
<a href="" class="unitie grid--image" style="background-image:url('image.jpg')>
</a>
.grid--image {
background-size: cover;
}

CSS for making an image responsive both to width and visible height of the containing element

I need the image to take the entire width of the container unless the resulting height is bigger then the available container's viewport height.
Basically I want the image to be responsive but also that it should still fit the screen. If it doesn't fit the screen it should be scaled down, horizontally centered, and preferably added with black tiles on its sides.
Currently, my CSS class looks like this:
.img-responsive{
display: block;
max-width: 100%;
min-width: 100%;
height: auto;
}
I've tried to play around with max-height on the image, or on a dedicated container, nothing seemed to do the trick by pure CSS.
Clarifications:
I don't know the images dimensions in advance so can't just put them in a container with a preset size.
Basically, my goal is for the images to be always fully visible on the screen (if you scroll to the image) and take up the largest possible surface.
Here's a more detailed example:
Let's say I have scrollable container with a lot of content. The container takes up the entire viewport width (let's say its 500px) and the available visible height of the container is the entire viewport height minus a navbar height (let's say 1000px).
I can't know in advance what's the container's visible dimensions as it can always change.
Inside the container there's whatever, text, images, etc.
Now, for a given image, here are possible scenarios:
If the image is 500x800, it should be presented as is, as it takes up the entire available width, and height is no bigger then the container's visible height.
If the image is 500x2000, it should be scaled down to 250x1000
and horizontally centered. This will take up the entire visible container's height, and keep the image's aspect ratio
If the image is 250x300, it should be scaled up to 500x600, taking up the entire available width
If the image is 200x500, it should be scaled up to 400x1000, taking up the entire available height
If the image is 1000x1000, it should be scaled down to 500x500, taking up the entire available width
Here's a JSFiddle explaining the problem
I would advise against using the IMG tag for this. Rather use a div tag and then use background image properties. Here is the code for this, set the container size to whatever you like:
<div id="container"></div>
<style>
width: 500px;
height: 500px;
background-image: url('your url');
background-size: contain;
</style>
background-size: contain is what is best for this. It scales the image to the largest the image can be within the div without making it larger than its native size. Hope this helps
EDIT:
Forgot to add that if you want it to be in the center of the container, so that when the image doesnt fit the full size of the container there is the white space around it, you use the css code background-position: center center;
Mostly what you need is to give img elements two properties {max-width:100%} and {height: auto}
If you open the snippet below in full screen and resize your window (Note: image sizes are randomly chosen)
you will see how nice they play. They adhere to the max width and they don't overstretch themselves in any direction.
I added some code in there just to make this easier to show
like making giving images {display:block} and {padding-bottom}
body {
background: #131418;
text-align: center;
color: white;
font-size: 25px;
}
body,
.image-container,
.image-container img,
.smalldiv {
max-width: 100%;
}
.image-container img {
height: auto;
display: block;
padding-bottom: 1em;
}
.smalldiv {
/*for demnostration only */
width: 600px;
background: darkblue;
}
.smalldiv,
.image-container img {
margin: 0 auto;
}
<h3>Images will always keep their aspect ratio and they will always adhere to the width of their parent containers.</h3>
<hr>
<div class="image-container">
<h4>This is what the image container looks like when it has the entire screen space</h4>
<img src="http://placehold.it/350x150">
<img src="http://placehold.it/650x150">
<img src="http://placehold.it/950x150">
<img src="http://placehold.it/1250x3150">
<img src="http://placehold.it/350x150">
<img src="http://placehold.it/450x350">
<img src="http://placehold.it/550x650">
<img src="http://placehold.it/650x950">
<img src="http://placehold.it/1250x1150">
</div>
<div class="smalldiv">
<div class="image-container">
<h4>This is what the image containing div looks when it's put inside a container smaller then the screen width</h4>
<img src="http://placehold.it/350x150">
<img src="http://placehold.it/650x150">
<img src="http://placehold.it/950x150">
<img src="http://placehold.it/1250x3150">
<img src="http://placehold.it/350x150">
<img src="http://placehold.it/450x350">
<img src="http://placehold.it/550x650">
<img src="http://placehold.it/650x950">
<img src="http://placehold.it/1250x1150">
</div>
</div>
evilgenious448 answer comes really close, just that it only works with background images. What I have is:
<html>
<head>
<style>
body {
margin: 0px;
}
.holder {
background-image: url('image1.JPG');
background-size: contain;
background-position: center center;
width: 100vw;
height: 100vh;
background-repeat: no-repeat;
}
</style>
</head>
<body>
<div class="holder">
<div class="inner">
</div>
</div>
</body>
</html>
I do not know how to size the inner div equally to the image.
Here is an example with code and everything:
You can drag around the page to test.
--- When the viewport is higher / taller than the image, the image's width is the width of the viewport disregarding viewport height. On the other hand, when the viewport is wider than the image, the image uses the viewports height, disregarding its with.
#image {
background-image: url(https://media.cntraveller.com/photos/611bedcd231ed5e8dfa34573/16:9/w_2580,c_limit/sennen-cove-beach-britain-conde-nast-traveller-20april18-rex.jpg);
background-size: contain;
background-position: center center;
width: 100vw;
height: 100vh;
background-repeat: no-repeat;
}
<body id="body">
<div id="image" />
</body>
You can use height: 100% of the parent container (in my case its img-holder). And apply text-align: center to the parent. Like:
.img-holder {
width: 100px;
height: 100px;
border: 1px solid #555;
text-align: center;
}
.img-holder img {
height: 100%;
}
Have al look at the snippet below:
.img-holder {
width: 100px;
height: 100px;
border: 1px solid #555;
text-align: center;
}
img {
height: 100%;
}
<div class="img-holder">
<img src="http://placehold.it/100x200" alt="">
</div>
Hope this helps!
The best and the easiest way is to use vh and vw properties. vh when set to 100 takes up the complete Viewport Height and same goes with vw for width. Further, max height property may be added to stop image from stretching beyond its original dimensions.