Div that takes up least width as possible with set height - html

I'm looking to create a div that only takes up as much width as it needs, with the height set to the height of the viewport. The problem I'm experiencing is that if the viewport height is reduced, the div's width doesn't update and the content overflows on the y-axis.
I've tried using flexbox to create two divs, one taking up the remaining room, but it doesn't force the other div to reduce in width so the words don't wrap.
Here's the first issue scenario:
Flexbox content not wrapping
In the image above, there are two div's using the following code:
.container {
display: flex;
}
.item-1 {
flex-grow: 0;
height: 100vh;
background-color:yellow;
}
.item-2 {
flex-grow: 1;
height: 100vh;
background-color:red;
}
The issue is that the text isn't wrapping to reduce the width of the first box to as little as possible. Here would be the desired result:
Desired flexbox content wrap
The second issue is that when the screen height is reduced, the content overflows instead of widening the div, as shown here:
Code overflowing outside of div
Ideally, these are the two desired results I am looking for:
Initial layout
(no overflow and as little width as possible)
Initial layout of desired result
Modified layout
(no overflow and the div width has widened to accommodate the content within it)
Modified layout of desired result
So far nothing I've tried has worked, am I asking for the impossible? I appreciate any help that can be provided.

Related

Stretch items to fill page with CSS print layout

I am designing a quiz using HTML/CSS. It is meant to be printed on paper.
It currently looks like this:
Originally, the question boxes were being split in half at the page break, but I managed to avoid that with
.questionBox {
break-inside: avoid;
}
Now, I have a more ambitious goal: I want to avoid wasting space at the bottom of each page by stretching each question box out so they're all taller. This should be done dynamically, sort of analogous to how flexbox stretches elements horizontally to fill the space with flex-grow.
I made a few attempts using flexbox and flex-direction: column, but no luck so far. Any recommendations?
Adjust the height property to stretch the .questionBox div to full height.
.questionBox {
height: 100vh;
}
height: 100vh = 100% of the viewport height.

Make a div scroll instead of expanding to fit its contents

I have a layout where I have a scrollable list of items in the center, with some stuff above and below it in a column. The list should take up as much empty space as is available to it in the column (I don't want to specify a specific height on it), and should scroll when the empty space in the column is not enough to fit all the items.
Here is a JSFiddle of the situation.
Notice that with just a few items in the scroller, it expands to fill the empty space in the column (as is intended). But then if you add several more items to the scroller, it expands to fit the entirety of its contents instead of staying at its original size, and then scrolling its overflowing contents; even though the it has overflow-y: scroll set!
However, if you then set the scroller to have a height of 0, the problem is fixed and the items scroll as is intended, with the scroller at its original height before the extra items were added.
But WHY!? Can someone please explain to me what's going on here? Also, is there any consequences of this "solution" that I'm not seeing?
<div class="column">
<div class="title">Header</div>
<div class="scroller">
<div class="item">Child</div>
<div class="item">Child</div>
</div>
<div class="title">Footer</div>
</div>
,
.column {
display: flex;
flex-direction: column;
height: 200px;
}
.title {
height: 50px;
flex-shrink: 0;
}
.scroller {
flex-grow: 20;
flex-shrink: 0;
overflow-y: scroll;
}
.item {
height: 20px;
margin-top: 2px;
}
Some quick background for anyone who runs across this later:
Elements that have flex-grow expand to take up x units of the available space minus the other flex content. In your case, .scroller is the only one with flex-grow but the other flex elements have defined heights so their content takes up space.
Elements that have flex-shrink contract as the space decreases. A zero value means they don't contract, a value >=1 allows scaling down.
However flex-shrink ONLY works if the element DOES NOT also have a flex-grow applied to it. Elements with both shrink & grow will only shrink to the size of their content
In your example, overflow doesn't kick in when the element is as big as the content (see above) which it is because you have both grow/shrink applied. Adding an explicit height (height: 0) overrides the computed "content" height allowing the flex-shrink to compress the element smaller than its content. This, in turn, makes the scrollbar work.
I don't know if this will cause any oddities at some point but it's an interesting solution to the problem and does seem to work pretty well.
You need to add a height to your scroller container css:
height: 30px;
Or max-height to allow growth to a limit:
max-height: 30px;
Either way, for the scroll to kick in, the container needs to feel constrained, so maybe:
height: 100%;
Then limit the size of its container.
I was able to get this working by setting flex-shrink on the scroller element to 1. It will cap out at its available space and use the scrollbar.

How to make a div extend to the bottom of the page without getting too tall

I have a div near the bottom of my page that I want to extend all the way to the very bottom edge of the window so that the background color of the page can not be seen below it. Initially, depending on the size screen that the page was rendered on, a small sliver of the background color was still visible below the div. By adding
html, body, .wrapper {
height: 100%;
}
to my CSS ("wrapper" being the class of the div in question), I fixed that issue, but now the div has a height of around 500px (it varies based on the window size) despite the only element in the div having a total height of 132px (which does not change regardless of window size). Because of the positioning of the div, this 500px height makes the page stretch and now there is a large blank space at the bottom of my page, underneath the content inside the div.
I used Chrome's developer tools to inspect the HTML, body, and div tags and there is no strange padding/margins and no defined height (other than the "100%" that I set). If you'd like more code I can gladly provide more but since I don't know exactly what the problem is I didn't know what would be relevant (plus I'm using bootstrap so finding all of the relevant CSS can be a pain sometimes). Thanks in advance.
You can use flexbox to have the .wrapper, or .table in your example, div fill up the remaining height.
For the parent element (in your example, body) set display: flex; flex-direction: column;
For the element that you want to expand (.wrapper or .table) set flex-grow: 1.
Your Example Updated: https://jsfiddle.net/754s67ur/2/
I have updated the fiddle you posted in the comments to add background colors and removed paddings and margins to better visualize the problem here.
What you need is the CSS calc function to have your .table div take up 100% of the page MINUS the nav and body content of your page (represented by the <p> in your fiddle).
In the fiddle they are both 18px, so combined it's 36px and that is what I need to minus from the 100%. So the style would look like this:
height: calc(100% - 36px);
This is how you calculate the remaining space. But this only works for static height elements. Here is a fiddle of the solution.

CSS div with full width but doesn't wrap text

I am trying to create a navigation element (nav) that spans the full width of the page, but when the windows shrinks enough where the text overflows, the text wraps. As this is the navigation bar for the page, I'd prefer it didn't wrap and the page just scrolls when the nav's content overflows it. I was thinking giving it a width in pixels instead of just 100% would work, but I don't know how to make it the full width on every screen using pixels. Any idea how to do this? I am using SASS too if that could help with a solution.
Basically, I need a solution that makes a element act as though its width were set to 100%, but it can't wrap the text if there's overflow. The window should scroll if there's overflow.
Put in the css style white-space:nowrap;
If you want a scroll bar in the div, go for overflow:scroll; and set a height of one line, and don't use nowrap.
Full width should be easy: width: 100%
If you want specifics, show us your code.
I think your best bet would be to set a minimum width on your nav element. This way, it will only scale your div to a certain point so it doesn't wrap. The only downside of this is that you need to specify a width, but the upside is it works without any of the div being cut off.
http://jsfiddle.net/piedoom/Km4Xa/1/
You can see in my CSS I have the following:
div
{
width: 100%;
background: red;
min-width: 250px;
}
The min width specifies how small the div can get before it just stays at that value instead of taking the window as it's width.
You can also apply this to the body so it works on all elements.

Child elements not expanding html body or parent element

Please take a look at this fiddle to go with the explanation:
http://jsfiddle.net/Br3jz/1/
I have a background style set on a containing div, and I want this background filling the entire screen at all times. I have inner .containers that are centered and are at a fixed with of 1064px. The problem arises when the device width is less than 1064px.
When this happens, the containing div, as well as the HTML body element are both stuck at the original device width. Why is this happening and how can I fix it?
The problem is that #main doesn't want to have more width than its parent, so it has a fluid width. But .container has a fixed width, which can be greater than #main's one. In that case, it overflows.
You have two possible solutions, with different effects:
Solution 1: Demo
Instead of width: 1064px, use
.container {
max-width: 1064px;
}
Solution 2: Demo
.container {
width: 1064px;
}
#main {
min-width: 1064px;
}