This is my flexbox setup:
section[_v-f4d9afa6] { // parent
display: flex;
}
article[_v-e514def2] { // child
display: flex;
flex: 1 1 50%;
}
article header[_v-e514def2] { // child of child
background-color: #484a47;
padding: 5px 0;
border-radius: 3px 3px 0 0;
}
article section[_v-e514def2] { // child of child 2
margin: 10px;
flex: 1 1 50%;
overflow-y: scroll;
}
I get this:
What should I change so the dark gray child is on the top? (Like an OS window)?
JSFiddle: https://jsfiddle.net/qjog7tvu/3/
You need to add flex-direction: column; for article[_v-e514def2]
One thing you can do is remove display: flex from article and just let it default as article and section are block element so header will arrange itself to top of section.
jsfiddle
Related
Using the following CSS:
#menusidebar {
background-color: #6BC9DB;
margin: 0 0 0 0;
height: 100vh;
}
the left hand side sidebar of this page does not reach the bottom of its parent container #content-wrap.
Update: I tried using the flex box model:
.flex {
display: -webkit-flex;
display: flex;
flex-grow: 1;
}
<div id="content-wrap" class="fluid clearfix flex" data-content="content">
<aside role="complementary" class="two columns" id="menusidebar">
but the child of the flex element #menusidebar does not take up all remaining space of the flex parent #content-wrap.
Here is a start for you, using your sample link
Fiddle demo
where I changed these rules
#content-wrap {
background-color: #FFF;
margin: 0;
display: flex;
}
.column, .columns {
display: inline;
flex: 1;
margin-left: 10px;
margin-right: 10px;
}
#menusidebar {background-color: #6BC9DB; margin: 0 0 0 0;}
Stick with the flexbox strategy, as that one is the most forward-thinking. Add the following style to the container:
align-items: stretch;
And take off any heights set on the child elements (specifically #menusidebar).
Can i get the height of the previous element using only CSS?
I am using calc() function to set dynamically height of the div B.
#b{
height:calc(100vh - heightOfPreviousElement);
}
I need to know the height of the previous element.
what i know is that, 100vh is equal to 100% of the screen height.
I used the code in the answer below.Using flex,
I have one problem. The height of the color orange become smaller.
You can easily achieve the effect you're looking for using flexbox. The trick is to allow the blue container (the one with the flexible height) to grow in size whenever the need arises, using flex: 1 1 auto, which is simply a shorthand for:
flex-grow: 1;
flex-shrink: 1;
flex-basis: auto;
See proof-of-concept code snippet below:
body {
padding: 0;
margin: 0;
}
.wrapper {
display: flex;
flex-direction: column;
flex-wrap: no-wrap;
align-items: center;
justify-content: center;
height: 100vh;
}
.wrapper > div {
width: 100%;
}
#c1 {
background-color: #880015;
color: #fff;
height: 60px;
margin-bottom: 10px;
}
#c2 {
background-color: #ff7f27;
}
#c3 {
background-color: #00a2e8;
flex: 1 1 auto;
margin-bottom: 10px;
}
<div class="wrapper">
<div id="c1">height: 60px</div>
<div id="c2">height: auto (determined by content?)</div>
<div id="c3">flexible height</div>
</div>
No you can't select a previous element in CSS.
You might be interested in JQuery Prev OR Parents method for selecting previous element and apply height using .css() method?
I am using css flex layout to build a dashboard and would like to put two widgets (one on top of the other) inside of a flex item and make them 50% height of their parent at all times (regardless of content). So if my html is:
<div class="flex-container">
<div class="flex-item">
<div class="widget" id="w1">
widget 1 content
</div>
<div class="widget" id="w2">
widget 2 content
</div>
</div>
</div>
and my css looks like:
.flex-container {
display: flex;
flex-direction: column;
}
.flex-item {
flex: 1;
}
How can I get the two .widgets to always occupy 50% height of .flex-item?
I've tried:
.flex-item {
flex: 1;
display: flex;
}
.widget {
flex: 1;
}
But this only works when the content in both widgets are the same.
I've worked up a more elaborate jsfiddle to better illustrate my issue.
Thanks in advance!
When you say that flex: 1 only works when the content in both widgets are the same, that is not correct. That would defeat the purpose of flex: 1.
flex: 1 tells flex items to distribute container space evenly among themselves. If there are four flex items with flex: 1, each will take 25%. Three would take 33.33%. And two flex items will take 50%. This is regardless of content quantity.
See this illustration: DEMO
The problem you're having is not clear in the code you posted in the question. However, it's apparent in your fiddle demo.
You have a main container with a height: 400px. You also have a rule adding 10px padding all-around to your divs. This adds 20px height to each div. You also have a header with height: 2em.
When you account for the extra heights the layout works.
Try these adjustments:
HTML (no changes)
CSS
div {
box-shadow: inset 0 0 0 1px rgba(30, 100, 200, 0.5);
padding: 10px; /* sneaky villain */
font-family: arial;
}
h1, p { margin: 0; }
#main-wrapper {
height: 400px; /* primary height */
display: flex;
flex-direction: column;
}
#header {
flex-shrink: 0;
height: 2em; /* header height */
}
#main-column-wrapper {
flex: 1;
display: flex;
flex-direction: row;
height: calc(100% - 2em - 20px); /* primary height - header height - padding */
}
#side-column {
width: 20%;
flex-shrink: 0;
}
#main-column {
flex: 1;
display: flex;
flex-direction: column;
height: calc(100% - 40px); /* main-column-wrapper height - padding (2 divs) */
}
#widget1,
#widget2 {
flex: 1;
flex-shrink: 0;
overflow: auto;
}
Revised Fiddle
Another option would be to use box-sizing: border-box to adjust for the padding. Learn more here: https://css-tricks.com/box-sizing/
I have a fixed-size div in which I am positioning several inline a's using the flexbox layout. My problem is that I also need to respond to clicks on the div, outside the text of the anchors, but flexbox is forcing their display to block so they take up all the available space, leaving no room for the user to click on the background div.
HTML:
<div class="poem">
<a class="title">Title</a>
<a>1919</a>
<a>Lead</a>
<a>Bachus</a>
</div>
Compiled CSS (I'm using SASS):
.title {
font-size: 1.85em;
}
.poem {
width: 12.5em;
height: 12.5em;
padding: .0625;
background-color: rgba(gray, 0.5);
display: inline-flex;
flex-direction: column;
}
.poem > a {
flex: 0 0 auto;
}
.poem > a:first-child {
flex: 1 1 auto;
}
.poem > a:first-child:hover {
background-color: rgba(255, 165, 0, 0.5);
}
This pen shows how I want to lay out the elements, and here is how they should actually work when hovered/clicked.
My question is whether there is any way to stop flexbox from forcing the elements' display to block and keep them inline or, alternatively, to detect whether a click was made specifically on an element's text.
I realize I could probably wrap each a in a div, but that would be non-semantic, so I'd rather leave it as a last resort.
Thank you.
.poem {
align-items: flex-start;
}
.poem > a:first-child {
flex: 0 1 auto;
margin-bottom: auto;
}
http://codepen.io/anon/pen/yGArn
I'm playing with css3's flexbox in Chrome (no need to worry about cross-browser for this). I'm having a hard time convincing it to lay out my content the way I'd like. Here's a sketch of my goal:
Here's a jsFiddle of my attempt: http://jsfiddle.net/Yht4V/2/ This seems to work great except each .group will expand its height rather than create multiple columns.
I'm using flexbox pervasively here. The body lays out vertically, with the #content div taking the remaining height of the page. Each .group is laid out horizontally. Finally, each .item is laid out within a .group vertically with wrapping.
Unfortunately, each .group ends up as a single column by expanding the #content height, which causes a vertical scrollbar (unwanted). If I set the height of each .group to a fixed pixel size, the items break out into multiple columns, but this defeats the fluidity of the flexbox. Here's what it looks like with fixed heights: http://jsfiddle.net/Yht4V/3/
So, how can I get my #content div to not expand vertically since everything is managed with flexboxes without setting a fixed height? I was expecting the flexbox to trigger more columns instead of expanding the height of its parent and causing a scrollbar.
From what I've seen with the Chrome and Opera implementations for Flexbox, a flex-direction of column requires restricting the height of the element, otherwise it will continue expanding vertically. It doesn't have to be a fixed value, it can be a percentage.
That said, the layout you want for your .group elements can also be achieved by using the CSS Columns module. The flow of the elements will be similar to that of the flexbox column orientation, but it will create columns as long as there's enough width for them, regardless of how long the document is.
http://jsfiddle.net/Yht4V/8/ (you'll have to excuse the lack of prefixes)
html {
height: 100%;
}
body {
height: 100%;
display: flex;
flex-flow: column nowrap;
}
h1 {
padding: 1em;
}
#content {
padding: 10px;
background-color: #eee;
display: flex;
flex-grow: 1;
}
#content > .group {
margin: 10px;
padding: 10px;
border: 1px solid #cfcfcf;
background-color: #ddd;
flex: 1 1 auto;
}
#content > .group:first-child {
columns: 10em;
flex-grow: 2;
}
#content > .group .item {
margin: 10px;
padding: 10px;
background-color: #aaa;
break-inside: avoid;
}
#content > .group .item:first-child {
margin-top: 0;
}
Leaving it as a bunch of nested flexboxes, this was about as close as I could get it:
http://jsfiddle.net/Yht4V/9/ (again, no prefixes)
html {
height: 100%;
}
body {
height: 100%;
display: flex;
flex-flow: column nowrap;
}
h1 {
padding: 1em;
}
#content {
padding: 10px;
background-color: #eee;
display: flex;
flex: 1 1 auto;
height: 100%;
width: 100%;
}
#content > .group {
margin: 10px;
padding: 10px;
border: 1px solid #cfcfcf;
background-color: #ddd;
display: flex;
flex-flow: column wrap;
flex: 1 1 30%;
max-height: 100%;
}
#content > .group .item {
margin: 10px;
padding: 10px;
background-color: #aaa;
}
Replace the following in your css -
display: -webkit-flex;
to the following -
display: -webkit-box;
This worked very well for me :-)