Set row height to fit content height in CSS Grid - html

I have a grid with two columns and two rows. I have to place two grid items in one column (on the right) and one item on the left. Then I want first element from the right column to have maximum height equal to its content height. How can I accomplish this?
The problem that I'm facing right now is that these two items on the right, have 50% height and I can't find a way to to set first one to minimum possible height, and the other one to the rest of height (auto).
Just to clarify - height of each items is not fixed. Below you can see how it look right now.
One more thing, I can't change order of HTML DIV elements due to responsive web design.
.grid{
display: grid;
grid-template-columns: auto 300px;
grid-column-gap: 20px;
grid-template-areas: "main_content top" "main_content bottom";
}
.left{
grid-area: main_content;
}
.top_right{
grid-area: top;
background: #ffa4a4;
}
.bottom_right{
grid-area: bottom;
background: #c7ffae;
}
<div class="grid">
<div class="top_right">I'm top right</div>
<div class="left">Long left content... Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras semper, eros ut cursus semper, dolor felis gravida ligula, et venenatis neque felis quis justo. Duis aliquet ex vitae tincidunt sodales. Fusce neque metus, pharetra eu molestie sed, tincidunt ac eros. Ut vehicula maximus sodales. Curabitur vehicula sollicitudin erat et rutrum. Aliquam id fermentum erat. Nulla pulvinar vel tortor in imperdiet. Nulla sit amet condimentum eros. Vestibulum tempor et massa eu sagittis. Integer eget nisi sagittis, placerat nibh sed, varius mi. Donec vel lorem at dolor euismod porttitor. Curabitur tincidunt magna facilisis, dapibus odio vitae, pretium orci. Aliquam lacus velit, rhoncus non porta vitae, pellentesque at libero. </div>
<div class="bottom_right">I'm bottom right</div>
</div>

You just need to set the first row to auto (content height) and the second row to 1fr (consume remaining space).
.grid{
display: grid;
grid-template-rows: auto 1fr; /* NEW */
grid-template-columns: auto 300px;
grid-column-gap: 20px;
grid-template-areas: "main_content top" "main_content bottom";
}
.left{
grid-area: main_content;
}
.top_right{
grid-area: top;
background: #ffa4a4;
}
.bottom_right{
grid-area: bottom;
background: #c7ffae;
}
<div class="grid">
<div class="top_right">I'm top right</div>
<div class="left">Long left content... Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras semper, eros ut cursus semper, dolor felis gravida ligula, et venenatis neque felis quis justo. Duis aliquet ex vitae tincidunt sodales. Fusce neque metus, pharetra eu molestie sed, tincidunt ac eros. Ut vehicula maximus sodales. Curabitur vehicula sollicitudin erat et rutrum. Aliquam id fermentum erat. Nulla pulvinar vel tortor in imperdiet. Nulla sit amet condimentum eros. Vestibulum tempor et massa eu sagittis. Integer eget nisi sagittis, placerat nibh sed, varius mi. Donec vel lorem at dolor euismod porttitor. Curabitur tincidunt magna facilisis, dapibus odio vitae, pretium orci. Aliquam lacus velit, rhoncus non porta vitae, pellentesque at libero. </div>
<div class="bottom_right">I'm bottom right</div>
</div>

You can use height: fit-content to ensure that the element matches the height of the content contained within... though note that the second box will still retain its original position:
.grid{
display: grid;
grid-template-columns: auto 300px;
grid-column-gap: 20px;
grid-template-areas: "main_content top" "main_content bottom";
}
.left{
grid-area: main_content;
}
.top_right{
grid-area: top;
background: #ffa4a4;
height: fit-content;
}
.bottom_right{
grid-area: bottom;
background: #c7ffae;
}
<div class="grid">
<div class="top_right">I'm top right</div>
<div class="left">Long left content... Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras semper, eros ut cursus semper, dolor felis gravida ligula, et venenatis neque felis quis justo. Duis aliquet ex vitae tincidunt sodales. Fusce neque metus, pharetra eu molestie sed, tincidunt ac eros. Ut vehicula maximus sodales. Curabitur vehicula sollicitudin erat et rutrum. Aliquam id fermentum erat. Nulla pulvinar vel tortor in imperdiet. Nulla sit amet condimentum eros. Vestibulum tempor et massa eu sagittis. Integer eget nisi sagittis, placerat nibh sed, varius mi. Donec vel lorem at dolor euismod porttitor. Curabitur tincidunt magna facilisis, dapibus odio vitae, pretium orci. Aliquam lacus velit, rhoncus non porta vitae, pellentesque at libero. </div>
<div class="bottom_right">I'm bottom right</div>
</div>
While I'm not sure how to have the second box jump up to match the first with the Grid layout, the desired effect would be quite simple to achieve if you're willing to use flexbox.
Simply add display: flex to .grid, and create a new .right to contain .top_right and .bottom_right. Then optionally flex: 1 to both .left and .right:
.grid {
display: flex;
}
.left {
flex: 1;
}
.right {
flex: 1;
background: #c7ffae;
}
.top_right {
background: #ffa4a4;
height: fit-content;
}
<div class="grid">
<div class="left">Long left content... Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras semper, eros ut cursus semper, dolor felis gravida ligula, et venenatis neque felis quis justo. Duis aliquet ex vitae tincidunt sodales. Fusce neque metus, pharetra eu
molestie sed, tincidunt ac eros. Ut vehicula maximus sodales. Curabitur vehicula sollicitudin erat et rutrum. Aliquam id fermentum erat. Nulla pulvinar vel tortor in imperdiet. Nulla sit amet condimentum eros. Vestibulum tempor et massa eu sagittis.
Integer eget nisi sagittis, placerat nibh sed, varius mi. Donec vel lorem at dolor euismod porttitor. Curabitur tincidunt magna facilisis, dapibus odio vitae, pretium orci. Aliquam lacus velit, rhoncus non porta vitae, pellentesque at libero.</div>
<div class="right">
<div class="top_right">I'm top right</div>
<div class="bottom_right">I'm bottom right</div>
</div>
</div>
Note that you'll also need to move the green background from .bottom_right to .right in order for it to stretch the whole height.
This will work across all major browsers.
Hope this helps! :)

Related

Two column layout - content one colulmn centered but the other column top aligned to the top of the centered content

I'm looking for a way to create this two column layout, the content on the right is centred horizontally and vertically but the content on the left is centred horizontally and vertically aligned with the top of the content in column twos as the length of the content in column two changes the content in column one always stays aligned to the top.
Please take a look at the image attached as this is easier to explain visually
This can't just be a padded box because as the content on the right grows the padding reduces to stay centered, and the main columns need to stay a min height
Updated layout image
Based on Кольо Пеев answer below I've modified my codepen
https://codepen.io/nitrokev/pen/RwMQZeJ
<div class="fifty-fifty-project-details-grid">
<article class="fifty-fifty-content left lightblue">
<div class="entry-content" >
<h3>Content 1</h3>
</div>
</article>
<article class="fifty-fifty-content right" >
<div class="entry-content" >
<h3>Content 2</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. In enim lorem, sollicitudin ut accumsan in, porta sed dui. Sed sagittis est risus, ac luctus odio porta at. Vivamus at nibh et mi euismod sagittis et sed justo. Nulla pretium pellentesque eros, vel aliquam elit egestas eu. Aliquam erat lorem, tristique sit amet est eu, elementum porta augue. Morbi consequat magna felis, placerat convallis nisl placerat a. Nullam porttitor suscipit metus a condimentum. Nunc eleifend ex sed tristique tempus. Nunc elementum ligula nec pulvinar mattis. Aenean tincidunt, odio in congue iaculis, ipsum quam hendrerit velit, id commodo mauris ante rhoncus odio. Sed eget nibh vitae ipsum consectetur porta sit amet eget ante. Donec ultricies lacinia ultricies. Nullam id porttitor leo. Quisque sit amet nisl ultrices sapien aliquet gravida. Nam auctor mi ut orci dictum, sit amet tempor metus eleifend. Donec rhoncus et justo ac sollicitudin. </p>
</div>
</article>
</div>
.fifty-fifty-project-details-grid {
display: flex;
flex-flow: row wrap;
overflow: hidden;
min-height:45rem;
}
.fifty-fifty-content {
display: flex;
flex-flow: row wrap;
align-items: center;
flex: 0 0 auto;
width: 50%;
margin-left: 0;
margin-right: 0;
height: auto;
padding:3rem;
}
.left{
background-color:#52AACB;
}
.right{
background-color:#52CB8F;
}
I think if there was a way to calculate the current height of the content in column two and apply it to column one, that might work?
Try running this code snippet. I am not fully aware of what you expect since there is no real content given anywhere from your side, but maybe with a few more lines of CSS you can achieve what you desire.
.container {
min-height: 400px;
background-color: #52CB8F;
display: grid;
}
.container__parent {
display: grid;
grid-template-columns: 1fr 1fr;
align-self: center;
}
.container__child {
padding: 16px;
background-color: #555;
text-align: center;
color: #fff;
}
.container__child:first-child {
border: 1px solid red;
}
.container__child:last-child {
border: 1px solid blue;
}
<div class="container">
<div class="container__parent">
<div class="container__child">
test string
</div>
<div class="container__child">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Facilisis mauris sit amet massa vitae tortor condimentum lacinia quis. Aliquet enim tortor at auctor. Facilisi etiam dignissim diam quis enim lobortis. Eget nulla facilisi etiam dignissim diam quis enim. Amet nisl suscipit adipiscing bibendum est ultricies integer. Id aliquet lectus proin nibh. Interdum consectetur libero id faucibus. Ornare lectus sit amet est placerat in egestas erat imperdiet. Felis imperdiet proin fermentum leo vel. Arcu dui vivamus arcu felis bibendum ut. Amet luctus venenatis lectus magna fringilla urna. Lobortis elementum nibh tellus molestie. Nibh praesent tristique magna sit amet purus gravida. Odio facilisis mauris sit amet massa vitae. Vel quam elementum pulvinar etiam non quam lacus suspendisse faucibus. Orci phasellus egestas tellus rutrum.
</div>
</div>
</div>

Move an element below or to the left of another element depending on the screen size

This might be a silly but still worth asking.
Suppose I have the following:
HTML
div {
width: 200px;
height: 100px;
margin-left: auto;
margin-right: auto;
}
#red {
background: red;
}
#media only screen and (min-width: 630px) {
.left {
clear: left;
float: left;
margin-right: 10px;
}
}
<h1>Heading</h1>
<!-- rectangle -->
<div id="red" class="left"></div>
<!-- paragraph 1 -->
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque consequat auctor enim, finibus porttitor neque condimentum non. Maecenas finibus, ex sed vehicula vehicula, libero dolor maximus elit, eu posuere ex odio in mi. Cras ipsum dolor, lacinia
nec tempus nec, luctus ut diam. Etiam pretium dolor a eros dignissim, vel tempus est condimentum. Phasellus fringilla condimentum arcu eget laoreet. Donec eget enim eget nunc volutpat rhoncus et vel tortor. Morbi tincidunt fermentum sapien sit amet
euismod.
</p>
<!-- paragraph 2 -->
<p>In hac habitasse platea dictumst. Praesent fringilla nulla id risus vehicula, vitae fermentum nisl varius. Nullam bibendum arcu risus, quis volutpat augue fermentum sit amet. Mauris vehicula lacus sed est tempor interdum. Fusce non fermentum metus, eget
posuere lorem. Nulla facilisi. Ut laoreet justo sed neque aliquet, a ultrices nisi consequat. Suspendisse nec sem et metus fermentum venenatis vel a ligula. In hac habitasse platea dictumst. Aenean interdum mi at lorem gravida, ac lobortis mauris mollis.
Nulla eu metus erat. Phasellus et dui ex. Pellentesque nec lectus accumsan, ultrices nunc vitae, dictum sapien. Proin quis tortor tellus. Maecenas in sem eu enim mattis pellentesque.</p>
(1) On a big screen (e.g. >629px), it will float the rectangle to the LEFT of paragraph 1.
(2) On a small screen, it will obviously center and position the rectangle ABOVE paragraph 1.
My problem is with (2). Without using JavaScript, is it possible to move the rectangle BELOW paragraph 1 but still ensure (1) ?
--
If you look at this demo, resize the output window, the first rectangle appears in between the heading and paragraph on a small window.
My goal is to have all paragraphs either appear AFTER a paragraph on a small screen or LEFT/RIGHT on a big screen.
The only way so far that I can think of doing this is to have 2 copies of the rectangle (one before the paragraph, one after the paragraph) and use media queries to toggle between them. So I am just seeing if there is any other way.
Can use a flexbox around the elements and flip them that way.
.rectangle {
width: 200px;
height: 100px;
margin-left: auto;
margin-right: auto;
}
#red {
background: red;
}
.container {
display: flex;
flex-direction: column-reverse;
}
#media only screen and (min-width: 630px) {
.left {
clear: left;
float: left;
margin-right: 10px;
}
.container {
display: block;
}
}
<h1>Heading</h1>
<div class="container">
<!-- rectangle -->
<div id="red" class="left rectangle"></div>
<!-- paragraph 1 -->
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque consequat auctor enim, finibus porttitor neque condimentum non. Maecenas finibus, ex sed vehicula vehicula, libero dolor maximus elit, eu posuere ex odio in mi. Cras ipsum dolor, lacinia
nec tempus nec, luctus ut diam. Etiam pretium dolor a eros dignissim, vel tempus est condimentum. Phasellus fringilla condimentum arcu eget laoreet. Donec eget enim eget nunc volutpat rhoncus et vel tortor. Morbi tincidunt fermentum sapien sit amet
euismod.
</p>
</div>
<!-- paragraph 2 -->
<p>In hac habitasse platea dictumst. Praesent fringilla nulla id risus vehicula, vitae fermentum nisl varius. Nullam bibendum arcu risus, quis volutpat augue fermentum sit amet. Mauris vehicula lacus sed est tempor interdum. Fusce non fermentum metus, eget
posuere lorem. Nulla facilisi. Ut laoreet justo sed neque aliquet, a ultrices nisi consequat. Suspendisse nec sem et metus fermentum venenatis vel a ligula. In hac habitasse platea dictumst. Aenean interdum mi at lorem gravida, ac lobortis mauris mollis.
Nulla eu metus erat. Phasellus et dui ex. Pellentesque nec lectus accumsan, ultrices nunc vitae, dictum sapien. Proin quis tortor tellus. Maecenas in sem eu enim mattis pellentesque.</p>
You can't really physically move the element below the paragraph just with CSS, but you can duplicate it and play with show/hide :
.red {
width: 200px;
height: 100px;
margin-left: auto;
margin-right: auto;
background: red;
}
.left{
display: none;
}
#media only screen and (min-width: 630px) {
.left {
clear: left;
float: left;
margin-right: 10px;
display: block;
}
.below{
display: none;
}
}
<h1>Heading</h1>
<!-- rectangle -->
<div class="red left"></div>
<!-- paragraph 1 -->
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque consequat auctor enim, finibus porttitor neque condimentum non. Maecenas finibus, ex sed vehicula vehicula, libero dolor maximus elit, eu posuere ex odio in mi. Cras ipsum dolor, lacinia
nec tempus nec, luctus ut diam. Etiam pretium dolor a eros dignissim, vel tempus est condimentum. Phasellus fringilla condimentum arcu eget laoreet. Donec eget enim eget nunc volutpat rhoncus et vel tortor. Morbi tincidunt fermentum sapien sit amet
euismod.
</p>
<!-- rectangle -->
<div class="red below"></div>
<!-- paragraph 2 -->
<p>In hac habitasse platea dictumst. Praesent fringilla nulla id risus vehicula, vitae fermentum nisl varius. Nullam bibendum arcu risus, quis volutpat augue fermentum sit amet. Mauris vehicula lacus sed est tempor interdum. Fusce non fermentum metus, eget
posuere lorem. Nulla facilisi. Ut laoreet justo sed neque aliquet, a ultrices nisi consequat. Suspendisse nec sem et metus fermentum venenatis vel a ligula. In hac habitasse platea dictumst. Aenean interdum mi at lorem gravida, ac lobortis mauris mollis.
Nulla eu metus erat. Phasellus et dui ex. Pellentesque nec lectus accumsan, ultrices nunc vitae, dictum sapien. Proin quis tortor tellus. Maecenas in sem eu enim mattis pellentesque.</p>
You can use a wrapper around each paragraph and rectangle pair and apply display: flex and flex-direction: column-reverse to that wrapper on small screens:
.wrapper {
width: auto;
height: auto;
display: flex;
flex-direction: column-reverse;
}
On large screens you simply reset it to display: block
https://codepen.io/anon/pen/wpVyQx

Flexbox equal eight 50% width columns not displaying correctly [duplicate]

This question already has answers here:
Using margin on flex items
(5 answers)
Closed 5 years ago.
I am trying to use Flexbox to make 50% width columns with equal height. I have this....
.items {
display: flex;
flex-wrap: wrap;
}
.item {
padding: 10px;
width:50%;
margin: 10px;
background: aqua;
}
<div class="items">
<div class="item">llamcorper id vehicula quis, sollicitudin a nibh. Quisque sed bibendum ipsum, et tempor arcu. Duis ultrices feugiat purus, ut sollicitudin ipsum interdum a. Nam porta vestibulum elit, et feugiat eros viverra et. In hac habitasse platea dictumst. Nullam at tempus libero. Donec pretium risus sit amet lacus imperdiet, vitae lacinia lorem eleifend. Mauris faucibus, dolor vel facilisis ultrices, massa urna tempus urna, vitae euismod felis est nd
</div>
<div class="item">
Item 1sadasdasdasdasd
</div>
<div class="item">
Item 1satricies fermentum erat luctus placerat. Praesent cursus nisl vitae magna tristique lacinia ac ac justo. Nunc euismod, est sed sodales lacinia, nisi leo luctus nulla, id commodo lectus sem vel erat. Vivamus id quam id ligula condimentum fermentum. Nullam commodo, magna sit amet sdasd
</div>
<div class="item">
Item 1sadasdasdasdasd
</div>
</div>
It is just displaying in one column, what am I doing wrong?
since you use padding and margin , item's width is equal to 50% + paddings + margins,
As a workaround, you may set a safe min-width and set flex-grow: 1;
Box-sizing can be reset to include padding in min-width calculation.
.items {
display: flex;
flex-wrap: wrap;
}
.item {
min-width: 40%;
padding: 10px;
flex: 1;
margin: 10px;
background: aqua;
}
<div class="items">
<div class="item">llamcorper id vehicula quis, sollicitudin a nibh. Quisque sed bibendum ipsum, et tempor arcu. Duis ultrices feugiat purus, ut sollicitudin ipsum interdum a. Nam porta vestibulum elit, et feugiat eros viverra et. In hac habitasse platea dictumst. Nullam
at tempus libero. Donec pretium risus sit amet lacus imperdiet, vitae lacinia lorem eleifend. Mauris faucibus, dolor vel facilisis ultrices, massa urna tempus urna, vitae euismod felis est nd
</div>
<div class="item">
Item 1sadasdasdasdasd
</div>
<div class="item">
Item 1satricies fermentum erat luctus placerat. Praesent cursus nisl vitae magna tristique lacinia ac ac justo. Nunc euismod, est sed sodales lacinia, nisi leo luctus nulla, id commodo lectus sem vel erat. Vivamus id quam id ligula condimentum fermentum.
Nullam commodo, magna sit amet sdasd
</div>
<div class="item">
Item 1sadasdasdasdasd
</div>
</div>
What's happening is that the width of the box is set to 50%, but that doesn't include padding or margin. You can have the 50% include padding by setting box-sizing: border-box; but you can't include the margin. One way to solve this is by using the flex-grow attribute, which tells an element how much it can grow to fill empty space in a row (relative to other elements in the row. If all elements have flex-grow: 1; they will all grow the same amount).
.items {
display: flex;
flex-wrap: wrap;
}
.item {
flex-grow: 1;
width: 40%;
padding: 10px;
margin: 10px;
background: aqua;
}
<div class="items">
<div class="item">llamcorper id vehicula quis, sollicitudin a nibh. Quisque sed bibendum ipsum, et tempor arcu. Duis ultrices feugiat purus, ut sollicitudin ipsum interdum a. Nam porta vestibulum elit, et feugiat eros viverra et. In hac habitasse platea dictumst. Nullam at tempus libero. Donec pretium risus sit amet lacus imperdiet, vitae lacinia lorem eleifend. Mauris faucibus, dolor vel facilisis ultrices, massa urna tempus urna, vitae euismod felis est nd
</div>
<div class="item">
Item 1sadasdasdasdasd
</div>
<div class="item">
Item 1satricies fermentum erat luctus placerat. Praesent cursus nisl vitae magna tristique lacinia ac ac justo. Nunc euismod, est sed sodales lacinia, nisi leo luctus nulla, id commodo lectus sem vel erat. Vivamus id quam id ligula condimentum fermentum. Nullam commodo, magna sit amet sdasd
</div>
<div class="item">
Item 1sadasdasdasdasd
</div>
</div>
As you have padding and margin, it adds to your width: 50% of your .item, to compensate padding you should add box-sizing: border-box, and to compensate margins you can wrap .item content to one more div.
.items {
display: flex;
flex-wrap: wrap;
}
.item {
padding: 10px;
width: 50%;
box-sizing: border-box;
}
.item > div {
padding: 10px;
background: aqua;
height: 100%;
box-sizing: border-box;
}
<div class="items">
<div class="item">
<div>llamcorper id vehicula quis, sollicitudin a nibh. Quisque sed bibendum ipsum, et tempor arcu. Duis ultrices feugiat purus, ut sollicitudin ipsum interdum a. Nam porta vestibulum elit, et feugiat eros viverra et. In hac habitasse platea dictumst. Nullam
at tempus libero. Donec pretium risus sit amet lacus imperdiet, vitae lacinia lorem eleifend. Mauris faucibus, dolor vel facilisis ultrices, massa urna tempus urna, vitae euismod felis est nd</div>
</div>
<div class="item">
<div>Item 1sadasdasdasdasd</div>
</div>
<div class="item">
<div>Item 1satricies fermentum erat luctus placerat. Praesent cursus nisl vitae magna tristique lacinia ac ac justo. Nunc euismod, est sed sodales lacinia, nisi leo luctus nulla, id commodo lectus sem vel erat. Vivamus id quam id ligula condimentum fermentum.
Nullam commodo, magna sit amet sdasd</div>
</div>
<div class="item">
<div> Item 1sadasdasdasdasd</div>
</div>
</div>

Pre code blocks stretch the content beyond screen width in a centered flex container

Here's a simple flex based blog layout:
<div class='Page'>
<div class='Container'>
<div class='Content'>
<h1>Hello</h1>
<p>Cras ac mauris purus. Phasellus at ligula condimentum, pretium nisi eget, aliquet enim. Sed at massa velit. Cras ac mi dolor. Nullam id felis sit amet neque tempus sodales. In ultricies et turpis in faucibus. Morbi fringilla metus pellentesque, varius enim a, dapibus ex. Sed aliquet urna nisi, eu fermentum diam pretium quis. Curabitur vel cursus turpis. Sed a varius leo, in viverra arcu. Donec porttitor, dolor vel laoreet iaculis, magna arcu tempus ex, at porttitor tellus nunc ultricies felis. Quisque congue sapien in quam tempor, non dapibus felis dignissim. Pellentesque ex eros, dignissim eget tortor non, aliquet ullamcorper nisi. Sed interdum non eros quis fringilla. Morbi condimentum tellus at blandit dignissim. Aenean metus elit, interdum et suscipit quis, ullamcorper sit amet risus.</p>
<pre>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse sapien magna, lacinia sit amet quam sed, dignissim tincidunt neque. Duis sed sapien hendrerit, consectetur neque quis, tempor nisl. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Praesent fringilla enim odio, sit amet venenatis ex commodo in. Pellentesque in enim in libero vulputate fermentum. Suspendisse elementum felis neque, in rhoncus diam hendrerit eget. Cras tempor porta bibendum. Fusce eget tellus a enim euismod lobortis in vitae nibh. Duis ornare turpis non ex consectetur, sit amet malesuada elit feugiat.</pre>
</div>
</div>
</div>
With this CSS
.Page {
border: 1px solid blue;
}
.Container {
display: flex;
flex-direction: column;
align-items: center;
}
.Content {
border: 1px solid red;
padding: 10px;
max-width: 700px;
min-width: 0;
}
pre {
overflow: auto;
background: #f2f2f2;
border: 1px solid #ccc;
border-radius: 4px;
padding: 20px;
}
Working example: https://codepen.io/anon/pen/xdeyrY
When the browser width is >700px, the red Container is centered and the pre code block has an overflow scrollbar. But as soon as you resize the browser < 700px, the pre code block stretches the container to the full 700px and the content gets cut off.
Why is the width of the container not limited by the browser/screen width in this case?
If you remove align-items: center; everything works as expected. If you set white-space: normal on pre, it also works as expected. But neither of those is an option.
The only workaround I came up with is to add this media query:
#media only screen and (max-width: 700px) {
.Container {
align-items: initial;
}
}
This does the trick, but seems a bit like a hack. Is this some flexbox bug/edge case, or am I missing some min-width: 0 trick here? It seems like using flex + align-items:center + max-width + pre just doesn't work well together..
In addition to Michael_B's answer, if you need the flex column direction for i.e. multiple .Content elements, you can also simply set width: 100% on the .Content.
To adjust the width to your padding/border you can either use box-sizing: border-box;, which I did, or CSS Calc (width: calc(100% - 22px);)
Also, for the reason Michael gave, I removed the min-width: 0 as it has no effect
Updated codepen
Stack snippet
.Page {
border: 1px solid blue;
}
.Container {
display: flex;
flex-direction: column;
align-items: center;
}
.Content {
border: 1px solid red;
padding: 10px;
max-width: 700px;
width: 100%;
box-sizing: border-box;
}
pre {
overflow: auto;
background: #f2f2f2;
border: 1px solid #ccc;
border-radius: 4px;
padding: 20px;
}
<div class='Page'>
<div class='Container'>
<div class='Content'>
<h1>Hello</h1>
<p>Cras ac mauris purus. Phasellus at ligula condimentum, pretium nisi eget, aliquet enim. Sed at massa velit. Cras ac mi dolor. Nullam id felis sit amet neque tempus sodales. In ultricies et turpis in faucibus. Morbi fringilla metus pellentesque, varius enim a, dapibus ex. Sed aliquet urna nisi, eu fermentum diam pretium quis. Curabitur vel cursus turpis. Sed a varius leo, in viverra arcu. Donec porttitor, dolor vel laoreet iaculis, magna arcu tempus ex, at porttitor tellus nunc ultricies felis. Quisque congue sapien in quam tempor, non dapibus felis dignissim. Pellentesque ex eros, dignissim eget tortor non, aliquet ullamcorper nisi. Sed interdum non eros quis fringilla. Morbi condimentum tellus at blandit dignissim. Aenean metus elit, interdum et suscipit quis, ullamcorper sit amet risus.</p>
<pre>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse sapien magna, lacinia sit amet quam sed, dignissim tincidunt neque. Duis sed sapien hendrerit, consectetur neque quis, tempor nisl. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Praesent fringilla enim odio, sit amet venenatis ex commodo in. Pellentesque in enim in libero vulputate fermentum. Suspendisse elementum felis neque, in rhoncus diam hendrerit eget. Cras tempor porta bibendum. Fusce eget tellus a enim euismod lobortis in vitae nibh. Duis ornare turpis non ex consectetur, sit amet malesuada elit feugiat.</pre>
</div>
</div>
</div>
It is indeed a min-width: 0 problem.
It's applied in your code, but the set-up is not quite right.
The min-width and min-height overrides work only in the direction of the main axis.
This means that the min-width: 0 override works only in flex-direction: row.
Similarly, the min-height: 0 fix applies only in flex-direction: column.
Your flex container is flex-direction: column. Your flex item has min-width: 0. Therefore, the override is having no effect.
Switch your container to row-direction. Since you're not applying flex properties to the content of the flex item, the switch won't change anything, except allow your <pre> tag to shrink.
You will also need to switch align-items: center to justify-content: center.
revised demo
More details here: Why doesn't flex item shrink past content size?

float:right with correct semantics

I have the following html/css:
#wrapper {
width: 400px;
background-color: red;
}
#text {
margin-right: 50px;
}
#subcontent {
float: right;
width: 50px;
}
<div id="wrapper">
<div id="subcontent">
<img src="http://lorempicsum.com/futurama/50/50/1" width="50">
</div>
<div id="text">Lorem ipsum dolor sit amet, consectetur adipiscing elit. In quis leo sapien. Nunc convallis elit purus, non fringilla quam lobortis at. Integer pharetra auctor luctus. In congue dolor a pretium facilisis. Donec et risus lacinia augue pellentesque mollis
eget a urna. Sed dapibus est enim, id iaculis arcu ultrices sit amet. Donec quis dolor risus. Suspendisse a nunc a enim mattis finibus eget vitae diam. Phasellus dictum commodo metus, ut rutrum dolor pretium a. Aliquam at sem vel tortor mollis tristique.
Proin neque dolor, pellentesque ut euismod id, finibus sed lacus. Mauris varius tempor diam, at varius risus. Etiam dictum metus et augue bibendum commodo. Vestibulum imperdiet elit vitae bibendum finibus. Maecenas mollis dui ex, id suscipit mauris
cursus vitae. Vivamus nec faucibus elit.</div>
</div>
This is achieving the desired effect of making the text stay left and the sub content stay right, without having to specify a width for the text (for responsive behaviour). However, semantically this is incorrect as I have had to place <div id="subcontent"/> before <div id="text"/> in the html, even though the text should appear before the sub content (assuming reading rtl). I can live with this to get the job done but unfortunately when the screen size is very small I need to make <div id="text"/> full width and let the sub content flow naturally afterwards. This currently means the sub content is at the top and I need it to be at the bottom.
How can I change the css so that when the html is ordered
<div id="text"/>
<div id="subcontent"/>
the sub content will float right without being pushed down by the text?
I need to support IE9+
Float is a pain.
Try to use flex and media queries for a responsive design :
Note: since you mention rtl reading, I strongly advise you to have a look on the flex-direction property (MDN)
#wrapper {
display: flex;
width: 400px;
background-color: red;
/* this is the default behavior - you can skip it */
flex-direction: row;
}
#text {
}
#subcontent {
width: 50px;
}
#media (max-width: 400px) {
#wrapper {
flex-direction: column;
}
}
<div id="wrapper">
<div id="text">Lorem ipsum dolor sit amet, consectetur adipiscing elit. In quis leo sapien. Nunc convallis elit purus, non fringilla quam lobortis at. Integer pharetra auctor luctus. In congue dolor a pretium facilisis. Donec et risus lacinia augue pellentesque mollis
eget a urna. Sed dapibus est enim, id iaculis arcu ultrices sit amet. Donec quis dolor risus. Suspendisse a nunc a enim mattis finibus eget vitae diam. Phasellus dictum commodo metus, ut rutrum dolor pretium a. Aliquam at sem vel tortor mollis tristique.
Proin neque dolor, pellentesque ut euismod id, finibus sed lacus. Mauris varius tempor diam, at varius risus. Etiam dictum metus et augue bibendum commodo. Vestibulum imperdiet elit vitae bibendum finibus. Maecenas mollis dui ex, id suscipit mauris
cursus vitae. Vivamus nec faucibus elit.</div>
<div id="subcontent">
<img src="http://lorempicsum.com/futurama/50/50/1" width="50">
</div>
</div>
Something like this?
#wrapper {
width: 400px;
background-color: red;
position: relative;
}
#text {
margin-right: 50px;
}
#subcontent {
position: absolute;
top: 0;
right: 0;
width: 50px;
}
<div id="wrapper">
<div id="text">Lorem ipsum dolor sit amet, consectetur adipiscing elit. In quis leo sapien. Nunc convallis elit purus, non fringilla quam lobortis at. Integer pharetra auctor luctus. In congue dolor a pretium facilisis. Donec et risus lacinia augue pellentesque mollis
eget a urna. Sed dapibus est enim, id iaculis arcu ultrices sit amet. Donec quis dolor risus. Suspendisse a nunc a enim mattis finibus eget vitae diam. Phasellus dictum commodo metus, ut rutrum dolor pretium a. Aliquam at sem vel tortor mollis tristique.
Proin neque dolor, pellentesque ut euismod id, finibus sed lacus. Mauris varius tempor diam, at varius risus. Etiam dictum metus et augue bibendum commodo. Vestibulum imperdiet elit vitae bibendum finibus. Maecenas mollis dui ex, id suscipit mauris
cursus vitae. Vivamus nec faucibus elit.</div>
<div id="subcontent">
<img src="http://moviesalbum.com/wp-content/themes/sunny/timthumb.php?src=http://moviesalbum.com/wp-content/uploads/2013/05/Koala-300x225.jpg&h=120&w=120&zc=1&q=90" width="50">
</div>
</div>
Cool. If I understand your question correctly, you are trying to change the order of the HTML, yet have the output still look the same?
If this is the case, you need to give #text AND #subcontent a float:left; add a clearing div and use a calc width on your text to make sure that the image will always fit in whilst the text can be responsively sized.
Here's a fiddle: https://jsfiddle.net/hk9ntyd2/1/
And here's the code:
#wrapper {
width: 400px;
background-color: red;
}
#text {
width: calc(100% - 50px);
float: left;
}
.clear {
clear: both;
}
#subcontent {
float: left;
width: 50px;
}
<div id="wrapper">
<div id="text">Lorem ipsum dolor sit amet, consectetur adipiscing elit. In quis leo sapien. Nunc convallis elit purus, non fringilla quam lobortis at. Integer pharetra auctor luctus. In congue dolor a pretium facilisis. Donec et risus lacinia augue pellentesque mollis
eget a urna. Sed dapibus est enim, id iaculis arcu ultrices sit amet. Donec quis dolor risus. Suspendisse a nunc a enim mattis finibus eget vitae diam. Phasellus dictum commodo metus, ut rutrum dolor pretium a. Aliquam at sem vel tortor mollis tristique.
Proin neque dolor, pellentesque ut euismod id, finibus sed lacus. Mauris varius tempor diam, at varius risus. Etiam dictum metus et augue bibendum commodo. Vestibulum imperdiet elit vitae bibendum finibus. Maecenas mollis dui ex, id suscipit mauris
cursus vitae. Vivamus nec faucibus elit.</div>
<div id="subcontent">
<img src="http://moviesalbum.com/wp-content/themes/sunny/timthumb.php?src=http://moviesalbum.com/wp-content/uploads/2013/05/Koala-300x225.jpg&h=120&w=120&zc=1&q=90" width="50">
</div>
<div class="clear"></div>
</div>
The margin-left:50px; solution should have worked fine, I personally find that the calc solution is a little neater, but feel free to use margin instead :)