How to set height of flex row but still allow row to expand vertically? - css

Consider this very simple header:
.box {
height: 100%;
width: 50px;
background-color: blue;
}
.row {
display: flex;
height: 60px;
background-color: yellow;
}
<div class="row">
<div class="box"></div>
<h1>This string needs to be able to wrap</h1>
</div>
The blue box needs to be defined by the height of the row and the text needs to be able to wrap. But as you can see, when the text wraps it extends beyond the flexbox. The flexbox can't grow at all because I have defined its height. If I remove the height specification then text wrap works correctly but the blue box disappears. This is a quite frustrating problem that I have spent hours trying to figure out. Is there no way to say to the row "your height is 60px but you can go bigger if you need to".
What I've tried so far:
Use min-height: 60px. For some reason the blue box still doesn't show up when I do this.
Use max-height: 100px. The row defaults to that size which is too big for when the text doesn't wrap.
I guess I could write media queries to manually change the height of the row, but it seems like there should be a more flexboxy way of doing this. Any ideas?
Here is the JS Fiddle if you want to play with it.

You don't need height: 100%; on child element of flex element.
And if you want minimum height of 60px on parent element, use min-height: 60px; instead of height: 60px;
.box {
width: 50px;
background-color: blue;
}
.row {
display: flex;
background-color: yellow;
min-height: 60px;
}
Here is the fiddle
https://jsfiddle.net/3bzeht52/

Related

Is it possible to fill the gap without JavaScript after one element moved out with transform?

The problem is demonstrated here: https://codepen.io/PengXiao/pen/NWwKpgB
As you can see in the above picture, message1 and participant1 was covering the whole width of message-container. participant1 is moved to the right for 50% with translateX and created a gap (shown as orange).
My questions is whether message1 can grow to fill that gap. I understand that transform will not impact the current layout. So we don't have to use flex and transform. I have just used flex for demo. However, we have the following constraints:
content for participant and message is dynamic;
participant must move to the right for 50%;
width of 'message-container' is fixed, but it does not consider the dynamic width of participant.
The final result I am trying to achieve is like this:
Yes, it is for the renderer of ZenUML :)
changes made using the transform property are merely visual, You can use negative margin to move the element.
.message-container {
display: flex;
width: 300px;
height: 50px;
background: orange;
}
.message {
height: 40px;
flex-grow: 1;
background: green;
}
.participant {
height: 40px;
margin-right: -40px;
background: pink;
}
<div class="message-container">
<div class="message">message1</div>
<div class="participant">participant1</div>
</div>

Image first in CSS with responsive

I'm using bootstrap 'featurette' feature. On the page there is a text on the left and image on the right. when you shrink the browser size, they go on top of each other, with the text at the top and the image at the bottom. How do I change this so that the image is frist and then the writing underneath?
Ad example is here http://getbootstrap.com/examples/carousel/
If you notice the feature part you will see what I mean when you resize.
I have tried changing the float position as thats the only thing I can think of but it didnt work.
P.s just to clarify, I still want them the same place when over 756px (or whatever the size is) but just want the image at the top when it changes size in the example above.
You should use display:flex property to the container for both and use order property for the elements for example is below. Try changing the order of the elements and have a look.
.elements-container{
background: #000;
width: 100%;
height: 500px;
display: flex;
}
.text-box{
order: 2;
width: 200px;
height: 200px;
color: #ffffff;
background: #ff0000;
display: block;
}
.image-box{
order: 1;
width: 200px;
height: 200px;
display: block;
}
<div class="elements-container">
<div class="text-box">This is text</div>
<div class="image-box"><img src="http://lorempixel.com/200/200" /></div>
</div>

Force flex element not to grow in cross-axis direction

I'm making a page with a vertical menu using display: flex;. I want the menu's width to fit snuggly around a few buttons, without having to use a fixed width.
However, I also want the menu box to have a status message, which can have quite a long text. I'd like this status-div to have the width of the menu, while not forcing the menu container to grow its width. Instead, the status-div should grow its height and wrap the text.
Explaining this in words is pretty difficult, so I suggest you checkout out this fiddle: http://jsfiddle.net/bXL3q/
Note the difference when setting .statusmessage to display: none;.
Any ideas, or is what I'm trying to do not feasible? ..should it be?
What I've tried:
width: 100% fails, obviously it just assumes the parent width
width: -webkit-min-content sort of works, but it makes the element too narrow
flex-basis and flex-grow affect the height of the element, and do nothing to affect the width
position: absolute will solve the width issues, but now I have no way to define the height of the status-div.. (for the purpose of forcing a scroll bar in windows with small height - instead it will just flow over the button elements)
body {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
display: flex;
flex-flow: row nowrap;
align-items: stretch;
}
.page {
flex-grow: 1;
background-color: yellow;
}
.menu {
background-color: red;
height: 100%;
display: flex;
flex-flow: column nowrap;
}
.somechildren {
white-space: nowrap;
background-color: green;
border: 1px solid black;
}
.menu>* {
flex-shrink: 0;
}
.separate {
flex-grow: 1;
}
.statusmessage {
background-color: magenta;
align-self: flex-end;
/*display: none;*/
}
<div class=menu>
<div class=somechildren>I'd like the menu's</div>
<div class=somechildren>width to fit nicely</div>
<div class=somechildren>around these children</div>
<div class=separate></div>
<div class=statusmessage>
While forcing this status message to wrap and grow its height, without affecting the width of the container.
</div>
</div>
<div class=page>
The page
</div>
You were almost there with width. What you need to do is set width and min-width (demo):
.statusmessage {
width:0; /* Collapses .statusmessage so it doesn't affect column width */
min-width:100%; /* Expands .statusmessage to width of column */
}
The width can be (and probably should be) set to a value other than 0. It should just be the minimum width of the column or smaller. So use a value that works for you.
I've tested this on Chrome and Firefox and seems to work in both. Now, is it supposed to work? I'm not sure, I haven't read into the spec that much (it could be undefined). Make sure to test in all browsers you need it to work in. (And check the spec to see if this behavior is undefined/incorrect.)
width: 0; min-width: 100%; didn't work for me.
Instead, I set
position: relative;
on the flex child and wrapped its contents in an inner div with
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
This prevents the contents from contributing to the flex container size while still matching the cross-axis size determined by the rest of the flex children.
For me, the issue was that the default value of align-items is stretch. So the items stretch out the cross axis by default.
You can either set align-items: flex-start or align-self: flex-start for the single flex child.
The visual here is quite illustrative.

How to proportionally fill a space around a fixed size div?

Could someone please help me?
I have three divs.
enter code here
The one in the middle should always be 1040px.
The left and right one shall fill the whole left space.
How can I make them proportionally grow/shrink when I resize the window?
Here is the code:
http://codepen.io/christophz/pen/413d31df9d33e1205b73bed3ebee1f5d
Thank you very much in advance!
Here is a pure CSS option using CSS display properties of table and table-cell.
DEMO: http://jsfiddle.net/audetwebdesign/a9J7D/
The markup is the same as you proposed.
The CSS is:
.container {
width: 100%;
min-width: 540px; /* you may want this... */
margin: 0 auto;
outline: 1px dashed blue;
display: table;
}
.bar-light {
width: auto;
height: 52px;
background-color: blue;
display: table-cell;
}
.bar-dark {
width: 540px;
height: 52px;
background-color: red;
display: table-cell;
}
Set display: table to .container and for the child elements, display: table-cell.
For .bar-light, set the width to auto and they will be computed to fill in the remainder of the page width (equally).
In my example, I set the center width to 540px to make it easier to see in the fiddle.
Finally, add a min-width to .container, without any content, the table cells will collapse to zero width as you shrink the window size.
Note About Heights
This layout will create three columns of equal height, the height will be computed to enclose the tallest of the three child elements.
This is real quick so it might be slightly off but you should be able to get the idea
HTML
<div class="a"></div>
<div class="b"></div>
<div class="c"></div>
CSS
div { float: left;}
.b { width: 1040px;}
JQuery
$(document).onload(resize);
$(window).resize(resize);
function resize() {
var ww = $(window).width();
var width = (ww-1040)/2;
$('.a').width(width);
$('.b').width(width);
}
Add a table with 3 column. In the middle column add you div. specify the size you want for this for these column e.g. 10-80-10. or -80-.

Add a DIV that takes up all available vertical space

I have an empty page with one DIV on it:
<div style="height: 20%;
min-height: 10px;
max-height: 100px;
width: 100%;
background-color: blue;"></div>
I want to add a DIV after this one that takes up all remaining vertical space on the page. How do I do it?
I've spent all day on this and CSS is starting to drive me crazy.
What has to be inside this div?
If it's a just a color filler, just put your blue div in a another div wich you give a background color and make that one fit 100% of your browser window?
It will look like 2 divs beneath eachother. If you need content you can always just put another div under your blue one with whatever content you want.
EDIT:
code example:
http://jsbin.com/efefe/2
Assuming you have two divs:
<div id='one'></div>
<div id='two'></div>
where #one has variable height and #two should consume all remaining vertical space you can do:
/* Note you could add a container div instead of using the body */
body {
display: flex;
flex-direction: column;
}
#one {
flex: none;
}
#two {
flex: 1;
}
Furthermore, if you want #two to be scrollable you can add:
height: 100%;
overflow-y: scroll;
which will allow it to scroll vertically to show it's whole contents.
You can read more about display:flex here.

Resources