Block elements only inside flex item? - css

Apparently, you can only have block elements (inline, inline-block, float nothing works) inside a flex item container? Thats just weird and doesn't seem useful unless I'm doing it completely wrong?
Here is the pen: http://codepen.io/iaezzy/pen/GggVxe
.fill-height-or-more {
min-height: 100%;
display: flex;
flex-direction: column;
}
.fill-height-or-more > div {
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
}
You might have to increase the preview pane height for the flexbox to work.
Edited for clarity: I'm not talking about the flex items themselves, but the elements INSIDE the flex item. In the codepen above, you'll see h2 and p bordered, they have the float declaration, but don't float.

You have set display: flex on both section as well as div.
If section acts as a container, you give display: flex to the section and leave the div as flex-items. Then the ps and h1s will float.
Fiddle: http://jsfiddle.net/abhitalks/zb12n2dk/
.fill-height-or-more {
display: flex;
flex-direction: column;
...
}
.fill-height-or-more > div {
flex: 1;
...
}
.some-area > div p {
width: 40%;
float: left;
...
}

Flex items are always rendered as blocks because flex layout only makes sense in a block-like layout. There are a few differences between flex items and block-level boxes which are covered in sections 3 and 4 of the spec, one being that flex items cannot float either, again because this would disrupt the flex layout (and conversely, neither can outside floats intrude into a flex layout).
You can apply different values of display to flex items (and hide them altogether with display: none), but this will only have the effect of establishing various formatting contexts for the children of the flex items, not the items themselves.
This includes display: flex, as you're demonstrating; what happens then is that the flex items become flex containers for their own children, which makes those children flex items in your nested flex formatting contexts. Because of this, floating those children won't work.
Note that in order to establish a flex layout, you only need to set display: flex on the flex container, not its children. All the children of a flex container that are not display: none will automatically be made flex items.

for displaing inline elements inside flex dispaly, there is anther solution to use display: inline-table however it does not seem it support float as well but you can workarwond this by wrapping it with anther div or something
check the following jsfiddle https://jsfiddle.net/reda84/eesuxLgu/
.row{
width:100%;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
flex-wrap: wrap;
}
.row > .col {
display: flex;
box-sizing: border-box;
width:50%;
float:left;
flex-direction: column;
border:1px solid #333;
min-height:100px;
padding:15px
}
.tag{
background: #1b8fe7;
color:#fff;
padding:5px 10px;
display: inline-table;
margin:0px 5px 5px 0;
}

For people trying to display inline element inside a flex container and finding this page, you just need to wrap your content one level higher in a flex element.
Example:
Not
<label style="display:flex">
A block label from a form <br>
<i>This idiomatic element is a block box and not its inline default</span>
</label>
but
<div style="display:flex">
<label>
A block label from a form <br>
<i>This idiomatic is an inline box and does not become a block</i>
</label>
</div>

Related

Can't push buttons to bottom of page in CSS

Been awhile since I played with Flexbox. I'm trying to push the buttons to the bottom of the page. Does the parent container always have to have a size to do that? That seems to be the only way I can get the result I want, but then I have to constantly resize based on what else is on the page. What else am I doing wrong?
.all {
display: flex;
flex-direction: column;
justify-content: flex-end;
}
<h2>My lists</h2>
<div class="all">
<div class="top"><button>Top</button></div>
<div class="middle"><button>Midde</button></div>
<div class="bottom"><button>Bottom</button></div>
</div>
Instead of using justify-content: flex-end; try to use justify-content: space-between;so that each element will be spread.
Also you need to set a min-height in the .alt class or the container in order to see the space-between in action.
As you mentioned in your question, you need to define a height from the area you want to align the elements.
Wrap your container
You need to define your parent container as
to make the elements inside don't overflow the box itself. For that use:
flex-wrap: wrap
Make the elements inside your container use the full width
By default flex will shrink the elements. to remove the defaults and use 100% of the width, use
flex: 0 0 100%
Make your elements align itself
This is the key for your question. the elements needs to be aligned not with the other boxes, they have to align themselves. For that you must use align-self: flex-start, align-self: center or align-self: flex-end
Minimal Example
.all {
display: flex;
min-height: 100vh;
flex-wrap: wrap;
}
/* This is going to make full width the divs inside .all */
.all div {
flex: 0 0 100%;
}
.top {
align-self: flex-start;
}
.middle {
align-self: center;
}
.bottom {
align-self: flex-end;
}
<div class="all">
<div class="top"><button>Top</button></div>
<div class="middle"><button>Middle</button></div>
<div class="bottom"><button>Bottom</button></div>
</div>

How to avoid items in flexbox not come out of div when the div's width next to flexbox is increased?

i want the items in flexbox not to come out of flexbox when the div's width next to flexbox is increased.
consider i have a flexbox container which has items such as svg, input field and div with simple text. Next to this flexbox container i have one side panel. This side panel can be resized..meaning when user drags the side panel sideways its width either increases or decreases. In doing so, the flexbox container is shrunk and hence the items in flexbox come out of it...how can i avoid it? how can i make sure that even when the sidepanel is dragged the flexbox items should stay intact?
.wrapper {
display: flex;
flex-grow: 1;
}
.items_container {
position: relative;
width: 40px;
height: 40px;
top: 16px;
margin-left: 16px;
padding-left: 5px;
display: flex;
align-items: center;
justify-content: space-evenly;}}
.items_container.expanded .search_input_field {
display: flex;
align-items: center;
}
<div class="wrapper">
<div class="items_container expanded">
<div class="search_input_field">
<Svgsearch/><input type=text/>
</div>
</div>
<div>dropdown to be added</div>
</div>
Could someone help me with it? thanks.
You can use flex-wrap to make the items drop down to another row if they are larger than their container:
display: flex;
flex-wrap: wrap;
Documentation: https://developer.mozilla.org/en-US/docs/Web/CSS/flex-wrap
If you want the items to remain on one line then i would give them percentage widths.

In flexbox, why do we define the container and not the elements themselves?

I'm trying to understand the flex property.
Why do we apply float and display: inline-block to the elements that are nested inside a container, while with display: flex, we define the container itself?
How can the elements inside be display:block and still be positioned on the same row?
.flex {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
flex-direction: row;
}
#media (max-width: 600px) {
.flex {
flex-direction: column;
}
}
#aaa {
border: 3px solid black;
flex: 2;
}
#aa {
border: 3px solid black;
flex: 1;
}
#a {
border: 3px solid black;
flex: 1;
}
#bbb {
width: 300px;
}
#ccc {
float: left;
border: 5px solid yellow;
width: 200px;
}
#ddd {
clear: both;
}
.one {
background: red;
height: 50px
}
.two {
background: green;
height: 50px
}
.tree {
background: blue;
height: 50px
}
#eee {
display: inline-block;
width: 200px;
}
<div class=flex>
<div id=a class="one">flex</div>
<div id=aa class="two">flex</div>
<div id=aaa class="tree">flex</div>
</div>
<div class=block>
<div id=bbb class="one">block</div>
<div id=bbb class="two">block</div>
<div id=bbb class="tree">block</div>
</div>
<div class=float>
<div id=ccc class="one">float</div>
<div id=ccc class="two">float</div>
<div id=ccc class="tree">float</div>
</div>
<div class=block>
<div id=ddd class="one">block</div>
<div id=ddd class="two">block</div>
<div id=ddd class="tree">block</div>
</div>
<div class=block>
<div id=eee class="one">block</div>
<div id=eee class="two">block</div>
<div id=eee class="tree">block</div>
</div>
CodePen demo
In flexbox, why do we define the container and not the elements themselves?
The reason is twofold:
Flex containers are the only things flex items can appear as children of, since only flex containers generate flex layout.
Unlike anonymous block boxes and anonymous table boxes, there are no such things as anonymous flex container boxes.
So, a hypothetical display: flex-item wouldn't work unless the element's parent was a flex container, and since every child of a flex container automatically becomes a flex item anyway, this makes such a display type completely redundant.
Block-level and inline-level boxes, on the other hand, exist in many, many forms. Even flex containers can appear in block-level and inline-level forms, as display: flex and display: inline-flex respectively. Furthermore, display: block and display: inline-block actually have a lot in common, as they are both block containers. The only difference is that one is block-level and the other is inline-level (and the latter always generates a block formatting context, but that's not pertinent here).
So display: block and display: inline-block are actually very similar to display: flex and display: inline-flex respectively in that regard (see Difference between display:inline-flex and display:flex), the difference being that the former pair handles block layout or inline layout (see section 9.2 of the CSS2 spec), and the latter pair handles exclusively flex layout.
If you're asking why flexbox was designed this way, that's something only the CSSWG can answer with certainty, but I can provide an educated guess based on what I've stated above: Since block-level and inline-level boxes can exist in so many different forms for various internal layout types (block, table, flex, grid, etc), defining flex-level counterparts for every single layout type would become extremely unwieldy, even if they did introduce a concept of anonymous flex container boxes which would allow elements to exist as flex items in their own right. This is why css-display-3 redefines the display property to take the form of <display-outside> <display-inside> along with special and legacy values — to accommodate new layout types without having to redefine entire sets of keywords to go along with them.
Your flex items are display: block simply because that's their specified value of display. But they are laid out as flex items, which always obey a set of rules in flex layout, which are loosely based on a combination of various elements of block and inline layout without falling squarely within the domain of either one. This is similar to how a float or an absolutely positioned element cannot be inline even if you specify display: inline or display: inline-block — because floats and absolutely positioned elements always participate in block layout, never inline layout.
Speaking of floats, FYI, floats participate in block formatting contexts, and are therefore part of a certain subset of block layout. They follow a float model, but the float model is integrated with the rest of block layout rather than existing as a completely separate layout type.

CSS Div under Div

I'm having a lot of trouble setting a div to appear under another div (like they do normally).
I'musing MaterializeCSS. My layout is as follows:
<div class="container valign-wrapper">
<div class="customClass"></div>
<div class="customClass"></div>
</div>
And css:
.valign-wrapper{
display: flex;
align-items: center;
}
.customClass{
margin: 0 auto;
/* text and font css */
}
However , even adding width:100% or changing display class won't make the two divs appear vertically, they appear side by side. I found out that removing valign-wrapper class will work, but my items will obviously appear at the top of the site...
If anyone has encountered the same problem I would appreciate the help!
You need to add the flex direction:
.valign-wrapper { flex-direction: column; }
That way, flex items are positioned as a column. Alternatively, if you need to go with flex-direction: row; (default), you can use
.valign-wrapper { flex-wrap: wrap; }
.customClass { flex-basis: 100%; }
to still maintain the row style but have your two items wrap and eventually positioned above each other.
Even though the post is from 2013, it still teaches the magic of flexbox in a nice way and I can just recommend everyone to read about it: https://css-tricks.com/snippets/css/a-guide-to-flexbox/

Centered flex box with display=none element causing unreadable overflow off screen

I have three columns within the flex box container, two visible and one hidden. The first two have very little content; the third one has several pages of content. I want all three to be initially vertically centered, but since the third one will overflow off the page, I want it (when made visible) to end up filling to the top of the page and then scrolling down. How can I have centred items in the flex box that overflow naturally in this way?
What's happening now in my code below is that when the third column is made visible, it overflows off the top and bottom of the page, without scroll, so that its impossible to read the first part of the content.
HTML:
<div class="flex-container">
<div class="column column-left">
column one
</div>
<div class="column column-right">
column two
</div>
<div class="column-hidden column" data-id="1">
column three
</div>
</div>
CSS:
body{
margin:0;
}
html, body{
height: 100%;
}
.flex-container{
height: 100%;
display: -webkit-flex;
display: flex;
-webkit-flex-direction: row;
flex-direction: row;
-webkit-align-items: center;
align-items: center;
-webkit-justify-content: center;
justify-content: center;
}
.column{
padding: 0 1em 0 1em;
}
.column-left{
display: visible;
}
.column-right{
display: visible;
border: none;
text-align: left;
}
.column-hidden{
display: none;
}
Javascript:
//clicking on button does the following to show hidden column
$('.column-left').removeClass('column-left').addClass('column-hidden');
$('.column-right').removeClass('column-right').addClass('column-left');
$(".column[data-id='" + id + "']").addClass('column-right').removeClass('column-hidden');
Played a bit with your code. I rearranged align-items from .flex-container to .column, which is also display: flex;. For scrolling I think you should have additional absolutely positioned container for the content.. I used P.
Sample here http://codepen.io/vkjgr/pen/gpqLLZ
p.s. Some hints about your code. flex-direction's initial value is row, so you don't have to write it. And visible is not a property of display ;)

Resources