Limit the max-height to fit the content size - css

I have a resizable container, I want it to be able to be resized to fit the content inside, but not too large to waste space.
I got the code like
.container {
width: 200px;
height: 200px;
background: red;
resize: vertical;
overflow: hidden;
max-height: max-content;
}
.content {
background: yellow;
}
<div class="container">
<div class="content">
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Saepe, molestiae? Officiis consequatur quod minima cum at ratione, sint ipsum architecto! Sit accusantium tenetur ducimus aut atque, eligendi in ullam sunt! Lorem ipsum dolor sit amet consectetur
adipisicing elit. Maxime explicabo dolor sequi veritatis aut. Recusandae quibusdam maiores doloremque natus, aspernatur minus dignissimos, id soluta amet, blanditiis illum odio ab alias.
</div>
</div>
I try different value of max-height, only fixed value such as 300px works, but it is not what I want. The requirement is that the red space can not be there, like the attachment. Any idea?

Try height: fit-content;
**UPDATE**
At first I didn't understand what you were trying to achieve, but now I'm pretty sure what you need here.
Unfortunately, I think that this is impossible without javascript (I may be wrong).
So here is simple example with ResizeObserver that looks for container and if this element height exceeds content height it will be shrinked back to max height of content.
disconnecting observer before change of height and reconnecting back after this change is mandatory because change of height will trigger ResizeObserver and we will got and infinite loop.
According to this issue, best workaround to prevent logging massive amount of errors into console, is to reconnect observer via requestAnimationFrame
const container = document.querySelector('.container');
const content = container.querySelector('.content');
const resizeObserver = new ResizeObserver(event => {
const maxHeight = window.getComputedStyle(content).height.replace('px', '');
const containerHeight = event[0].contentRect.height;
resizeObserver.disconnect();
if (containerHeight > maxHeight) {
container.style.height = maxHeight + 'px';
}
requestAnimationFrame(() => resizeObserver.observe(container));
});
resizeObserver.observe(container);
.container {
width: 200px;
height: 200px;
background: red;
resize: vertical;
overflow: hidden;
max-height: max-content;
height: fit-content;
}
.content {
background: yellow;
}
<div class="container">
<div class="content">
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Saepe, molestiae? Officiis consequatur quod minima cum at ratione, sint ipsum architecto! Sit accusantium tenetur ducimus aut atque, eligendi in ullam sunt! Lorem ipsum dolor sit amet consectetur
adipisicing elit. Maxime explicabo dolor sequi veritatis aut. Recusandae quibusdam maiores doloremque natus, aspernatur minus dignissimos, id soluta amet, blanditiis illum odio ab alias.
</div>
</div>

I made a change to use JavaScript to set the max-height on the container with the offset set height from the content. That way it will not grow more than the content.
<div id="container" class="container">
<div id="content" class="content">
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Saepe, molestiae? Officiis consequatur quod minima cum at ratione, sint ipsum architecto! Sit accusantium tenetur ducimus aut atque, eligendi in ullam sunt! Lorem ipsum dolor sit amet consectetur
adipisicing elit. Maxime explicabo dolor sequi veritatis aut. Recusandae quibusdam maiores doloremque natus, aspernatur minus dignissimos, id soluta amet, blanditiis illum odio ab alias.
</div>
</div>
<script>
var content = document.getElementById("content");
var container = document.getElementById("container");
container.style.maxHeight = content.offsetHeight + "px";
</script>

Related

Is there a way to resize pictures based on the sibling element which contains text?

I have div container which holds two elements,
one contain text and the other one contains a picture
i want the height of my picture to resize based on its sibling container which holds text
for instance , if my text container's height is 500px, the height of my picture's container resize to 500px without losing its aspect ratio
You can use the type of implementation I have added here.
Make the image height: 100%; and object-fit: cover; to fix the aspect ratio.
body {
max-width: 780px;
margin: auto;
}
img {
max-width: 100%;
}
.parent {
display: flex;
flex-wrap: wrap ;
}
.child {
flex: 0 0 50%;
}
.child img {
height: 100%;
object-fit: cover;
}
<div class="parent">
<div class="child">
<img src="https://images.pexels.com/photos/12004363/pexels-photo-12004363.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1" alt="">
</div>
<div class="child">
<p>
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Quas ipsam eveniet cupiditate recusandae, ratione tenetur suscipit, quia est vel quasi, a ex maxime! Reiciendis quae delectus cum praesentium. Aliquid, necessitatibus?
</p>
<p>
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Quas ipsam eveniet cupiditate recusandae, ratione tenetur suscipit, quia est vel quasi, a ex maxime! Reiciendis quae delectus cum praesentium. Aliquid, necessitatibus?
</p>
<p>
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Quas ipsam eveniet cupiditate recusandae, ratione tenetur suscipit, quia est vel quasi, a ex maxime! Reiciendis quae delectus cum praesentium. Aliquid, necessitatibus?
</p>
<p>
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Quas ipsam eveniet cupiditate recusandae, ratione tenetur suscipit, quia est vel quasi, a ex maxime! Reiciendis quae delectus cum praesentium. Aliquid, necessitatibus?
</p>
<p>
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Quas ipsam eveniet cupiditate recusandae, ratione tenetur suscipit, quia est vel quasi, a ex maxime! Reiciendis quae delectus cum praesentium. Aliquid, necessitatibus?
</p>
</div>
</div>

Article layout with CSS Grid: how to wrap text around images (or float them)?

I know that direct children of a grid item cannot be floated. I'm trying to create an article layout where something like this is achieved: pull an image to either side, and have the text flow around it.
Here's what I have so far on Codepen. With named template columns, I can have an image fill up only part of the width of the grid, but is there any way to let the surrounding text flow around it?
Hopefully my Codepen example makes sense; please let me know if I can provide additional information or clarification!
figure {
margin: 0;
}
img {
max-width: 100%;
height: auto;
}
article {
max-width: 800px;
margin: auto;
display: grid;
grid-template-columns: [wide-start] minmax(1em, 1fr) [main-start] minmax(0, 16em) [main-half] minmax(0, 16em) [main-end] minmax(1em, 1fr) [wide-end];
}
article>* {
grid-column: main;
}
figure {
grid-column: wide-start / main-half;
}
div {
grid-column: main-half / main-end;
padding-left: 1em;
}
<article>
<h1>Article</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Labore dolorem porro vero! In iste nemo repellendus? Doloremque eius officia beatae doloribus autem vitae enim qui. Minus, facere? Quaerat, laboriosam enim?</p>
<figure>
<img src="https://via.placeholder.com/500x300">
<figcaption>
<p>I wish the text could wrap around to my right</p>
</figcaption>
</figure>
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Sunt, obcaecati, blanditiis ad nostrum autem atque error quasi, tempora debitis exercitationem illum. Maiores cum delectus, fugit repellat provident libero hic magni?</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptates consectetur aspernatur est numquam alias consequatur praesentium quaerat totam dicta non asperiores similique inventore, a perspiciatis perferendis laudantium minus ratione animi!</p>
<figure>
<img src="https://via.placeholder.com/500x300">
<figcaption>
<p>Text is now in a column next to me (because I wrapped it in a <code><div></code>, but it won't wrap underneath me automatically</p>
</figcaption>
</figure>
<div>
<p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Fugiat repellat consequatur, voluptas sint eum ea error sit hic dignissimos expedita totam suscipit officia consequuntur non, quaerat odio. Recusandae, consequatur maxime!</p>
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Itaque eveniet, pariatur ipsa fuga hic nihil unde maiores, provident eius minima atque accusamus voluptate aspernatur perferendis. Ab rem inventore omnis at!</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. At vitae ex fugit sequi, natus asperiores? Laudantium optio, doloribus error dolores exercitationem aliquid esse, reiciendis mollitia alias vel illo, amet officiis?</p>
</div>
</article>
If I understood you correctly and you don't have to use only CSS Gird for the whole layout you can wrap your figure and paragraphs in another div, then trough that div give your figure max width of 50%, float:left, and some margin-right... you get the point.
figure { margin: 0; }
img { max-width: 100%; height: auto; }
article {
max-width: 800px;
margin: auto;
display: grid;
grid-template-columns:
[wide-start] minmax(1em, 1fr)
[main-start] minmax(0, 16em)
[main-half] minmax(0, 16em) [main-end]
minmax(1em, 1fr) [wide-end];
}
article > * {
grid-column: main;
}
.floating{
margin-bottom: 20px;
border-bottom: 1px solid #ddd;
}
.floating figure {
float:left;
max-width: 50%;
margin-right: 20px;
}
.floating p {
margin-top:0;
}
<article>
<h1>Article</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Labore dolorem porro vero! In iste nemo repellendus? Doloremque eius officia beatae doloribus autem vitae enim qui. Minus, facere? Quaerat, laboriosam enim?</p>
<div class="floating">
<figure>
<img src="https://via.placeholder.com/500x300">
<figcaption>
<p>I wish the text could wrap around to my right</p>
</figcaption>
</figure>
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Sunt, obcaecati, blanditiis ad nostrum autem atque error quasi, tempora debitis exercitationem illum. Maiores cum delectus, fugit repellat provident libero hic magni?</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptates consectetur aspernatur est numquam alias consequatur praesentium quaerat totam dicta non asperiores similique inventore, a perspiciatis perferendis laudantium minus ratione animi!</p>
</div>
<div class="floating">
<figure>
<img src="https://via.placeholder.com/500x300">
<figcaption>
<p>Text is now in a column next to me (because I wrapped it in a <code><div></code>, but it won't wrap underneath me automatically</p>
</figcaption>
</figure>
<div>
<p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Fugiat repellat consequatur, voluptas sint eum ea error sit hic dignissimos expedita totam suscipit officia consequuntur non, quaerat odio. Recusandae, consequatur maxime!</p>
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Itaque eveniet, pariatur ipsa fuga hic nihil unde maiores, provident eius minima atque accusamus voluptate aspernatur perferendis. Ab rem inventore omnis at!</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. At vitae ex fugit sequi, natus asperiores? Laudantium optio, doloribus error dolores exercitationem aliquid esse, reiciendis mollitia alias vel illo, amet officiis?</p>
</div>
</div>
</article>

when overflow: auto, padding-bottom is not seen

<div class="container">
<div class="content">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Pariatur amet, vitae fuga provident et quae aut minus voluptate quidem maiores at recusandae sit deleniti quia dolore, illum reiciendis! Hic, optio Lorem ipsum dolor sit amet, consectetur adipisicing elit. Fugit accusantium, obcaecati dicta unde repellat illo maxime! Magni officiis, culpa nihil, sequi aliquid vel voluptas quidem laboriosam, omnis nam fuga veniam.</div>
</div>
.content {
width: 200px;
height: 150px;
padding: 20px;
background: yellow;
overflow: scroll;
box-sizing: border-box;
}
http://jsfiddle.net/v6yjLdnp/
Why doesn't the padding-bottom work in this case when scrolling? And how do I make this possible?
I suppose you mean the padding at the bottom of the scrolled content. This seems to be a browser issue - see the comments. But with the following code it should work properly in all browsers.
Transfer some of the settings to the container, then it works as desired:
body {
margin: 0;
}
.container {
width: 200px;
height: 150px;
overflow: scroll;
}
.content {
padding: 20px;
background: yellow;
}
<div class="container">
<div class="content">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Pariatur amet, vitae fuga provident et quae aut minus voluptate quidem maiores at recusandae sit deleniti quia dolore, illum reiciendis! Hic, optio Lorem ipsum dolor sit amet, consectetur adipisicing
elit. Fugit accusantium, obcaecati dicta unde repellat illo maxime! Magni officiis, culpa nihil, sequi aliquid vel voluptas quidem laboriosam, omnis nam fuga veniam.</div>
</div>
The problem is probably be caused by the scroll bars.
This is a workaround with using pseudo elements in css, but it might solve your problem:
.content::after { content: ''; display: block; width: 100%; height: 20px; }
EDIT: Remove the padding bottom of the content element to make it work in all browsers:
.content { padding-bottom: 0px; }

Flexbox - Same height columns inside row

Is it possible to make the columns inside each row the same height as each other? For example to make both the blue headings the same size and so on
Apologies if this has been asked before but I couldn't see an answer to this when searching.
<div class="row">
<div class="column">
<h2>heading</h2>
<div class="block-1">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Debitis, nesciunt.</div>
<div class="block-2">Lorem ipsum dolor sit amet.</div>
</div>
<div class="column">
<h2>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quod, maiores!</h2>
<div class="block-1">Lorem ipsum</div>
<div class="block-2">Lorem ipsum dolor sit amet, consectetur adipisicing elit. In quam praesentium suscipit laudantium illo voluptatibus eligendi, est exercitationem commodi reiciendis.</div>
</div>
</div>
.row {
display: flex;
}
.column {
display: flex;
flex-direction: column;
* {
flex: 1;
}
}
https://jsfiddle.net/vdLaq7t1/
You can do it with align-items: stretch (which is the default value for align-items), but you should redesign your HTML structure.
.column {
background: silver;
}
h2 {
background: cornflowerblue;
margin: 0;
}
.block-1 {
background: tomato;
}
.block-2 {
background: brown;
}
.row {
display: flex;
/* Not required because it's already the default value */
align-items: stretch;
}
.row > *{
flex: 1;
}
<div class="row">
<h2>heading</h2>
<h2>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quod, maiores!</h2>
</div>
<div class="row">
<div class="block-1">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Debitis, nesciunt.</div>
<div class="block-1">Lorem ipsum</div>
</div>
<div class="row">
<div class="block-2">Lorem ipsum dolor sit amet.</div>
<div class="block-2">Lorem ipsum dolor sit amet, consectetur adipisicing elit. In quam praesentium suscipit laudantium illo voluptatibus eligendi, est exercitationem commodi reiciendis.</div>
</div>
Flexbox works in both X and Y axis. When you use flex-direction: column you are changing the main axis from X to Y. You can manage the main axis with the justify-content property, and the secondary axis with the align-items property.
The thing is that align-items work with the stretch value, but justify-content cannot.
So if you want the height to be the same (Y axis), you need to stretch it with align-items: stretch, but align-items only works in the secondary axis, so the main axis needs to be the X axis in this case, and that means that you cannot use flex-direction: column in order to make them the same height.
It can be done with many technics.
For example, you can place 6 columns in 1 row.
.row {
display: flex;
flex-wrap: wrap;
}
.column {
flex-basis: 70%;
}
.column.sm {
flex-basis: 30%;
}
.blue {
background: blue;
}
.silver {
background: silver;
}
.cornflowerblue {
background: cornflowerblue;
}
<div class="row">
<div class="column blue sm">heading</div>
<div class="column blue">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quod, maiores!</div>
<div class="column silver sm"><div>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Inventore quaerat, facilis qui placeat! Voluptatem reprehenderit similique rerum officia iste error ab, animi nobis quaerat culpa possimus, nisi laboriosam aliquid hic.</div>
<div>Tempora eius eaque harum, temporibus sequi porro, minima quia, necessitatibus amet nisi unde reiciendis iure ipsa, facilis rerum qui dolores doloribus sed voluptatum! Dicta at, qui, exercitationem molestiae voluptas natus.</div></div>
<div class="column silver">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iusto nemo ipsum voluptates mollitia eius enim, esse voluptatibus eaque doloremque vel asperiores quos unde similique rerum perspiciatis iure, ipsam eum soluta.</div>
<div class="column cornflowerblue sm">lorem</div>
<div class="column cornflowerblue"><div>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore enim recusandae veniam optio delectus doloremque maiores quidem, impedit vel reprehenderit quam vitae, fugit atque assumenda molestiae debitis laboriosam blanditiis fugiat.</div>
<div>Excepturi ea minima accusantium delectus totam quae fugiat, ex eos inventore deleniti odit, commodi eveniet, eum ullam consectetur ipsa quasi odio similique. Doloribus tempore accusantium soluta, id deserunt maxime accusamus.</div></div>
</div>

Overflow : scroll is ignored

So basically, I have this structure (sample) :
<div class="container">
<div class="header">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Deleniti odio pariatur numquam aspernatur ex iste praesentium. Aliquid quo voluptas eaque sequi autem voluptatem alias ullam provident tempora adipisci optio error!
</div>
<div class="content">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Qui odit esse assumenda eligendi obcaecati quas sapiente voluptatum a enim quam officia aliquid exercitationem earum at sint harum ullam nostrum distinctio! Lorem ipsum dolor sit amet, consectetur adipisicing elit. Qui odit esse assumenda eligendi obcaecati quas sapiente voluptatum a enim quam officia aliquid exercitationem earum at sint harum ullam nostrum distinctio!
</div>
</div>
And this stylesheet :
.container {
height: 100px;
}
.header {
background-color: blue;
}
.content {
background-color: green;
overflow-y: auto;
}
I would like to apply an overflow: auto on the .content as its content overflows the container height, however this simply does not work (see in this fiddle). I can apply an overflow: auto to .container and it will work but I don't want to apply the scroll on the .header element.
Furthermore, the .header height may change, so I can't set a fixed height to .content.
Any idea/suggestion ?
Thanks :)
EDIT : To clarify, I set a height to the container, I cant set a height to neither .header (which may change but won't be bigger than .container) nor .content (which may overlap the .container height because of .header)
You won't be able to do this in CSS unfortunately, but with little javascript it will work.
var container = document.querySelector(".container");
var header = document.querySelector(".header");
var content = document.querySelector(".content");
content.style.height = (container.offsetHeight - header.offsetHeight) + "px";
http://jsfiddle.net/q26cL/3/
It's because you don't have a height. So the div expands accordingly to the content.
I set a height of 120px for .content and it works now.
.content {
height: 120px;
}

Resources