I am trying to use flexbox to create a series of rows that scale to fit the available screen space. This seems to be necessary to create a decent UI on a mobile device, as it prevents all the boxes from clustering at the top, and spaces rows evenly. The problem is that it appears to be ignoring the vertical fill on the container, and gathering elements at the top. My code is as below
CSS:
.fill-vertical-space{
display: -webkit-flex;
display: flex;
flex-direction: column;
background-color: green;
height: 100%;
}
.fill-vertical-space > div, .fill-vertical-space > .row{
-webkit-flex: 1;
flex: 1;
background-color: blue;
}
And the HTML:
<div class="fill-vertical-space">
<div class = "row">
<div class="col col-100 section">
...
</div>
</div>
<div class = "row">
<div class="col col-100 section">
...
</div>
</div>
</div>
Note: I have left the content out of the rows. They are typically a mix of heading, nested flex boxes, and drop down menus.
Note 2: I have looked at other answers on the site, but none of them relate to ionic specifically (Could it be possible that Ionics CSS interferes with flex box?).
The problem was down to an ionic class in their CSS file. Adding:
.scroll{
height: 100%;
}
fixed the issue. I also needed an outer container holding the flex module, that was also set to 100% height, and to declare the .fill-vertical-space class as having static positioning.
Related
This question already has answers here:
Targeting flex items on the last or specific row
(10 answers)
Closed 2 years ago.
I'm creating a nav menu using flex. I want all of the items in my menu to display in a single row when the screen is wide enough to support that, and to snap to two rows of items when it needs to wrap. I have this mostly working:
.content {
width: 400px;
height: 150px;
border: thin solid black;
}
.outer {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.inner {
display: flex;
justify-content: space-around;
flex-grow: 1;
}
span {
font-size: 24pt;
}
<div class="content">
<div class="outer">
<div class="inner">
<span>one</span>
<span>two</span>
<span>three</span>
</div>
<div class="inner">
<span>four</span>
<span>five</span>
<span>six</span>
</div>
</div>
</div>
CodePen here.
This works perfectly when the page is wide enough:
And it works mostly perfectly when the page is narrow (try changing the width of .content to 250px):
However, now I'm trying to make it so the items in each row line up with each other. I'm going for something like this:
I've tried every combination of flex-grow, flex-shrink, and justify-content that I can think of, but I can't get the items to align.
I know I could probably use a media query and swap out the content for a grid when the window gets too narrow, but I'd like to simplify this as much as possible. Is there a way to align the children of two flex divs?
Alternatively, is there a way to use a grid layout that shows as 1 row until it needs to wrap, and then it shows as 2 rows?
It causes by span width.
if span width not fixed, span will have dynamic width;
set width on span;
Try this
Add to te span
span {
flex: 33%;
}
Or change the porcent acording to the amount of items the div has
My sidebar is getting pushed down instead of staying inline with my main class, you can view the issue more in my fiddle. (This is one of the first times I've not used bootstrap for a project in a very long time).
view my fiddle.
Instead of float, using flex is a better approach for responsive design.
Try putting your sidebar and main inside a div with display as flex and flex-wrap as wrap.
Here's an example-
.flexbox {
display: flex;
flex-wrap: wrap;
}
.latest-single {
width: 70%;
background-color: blue;
}
.sidebar {
width: 30%;
background-color: green;
}
<div class="flexbox">
<div class="latest-single">
This is our primary content
</div>
<div class="sidebar">
This is our sidebar content
</div>
</div>
You have to choose a way of how to display them. (block,flex,table)
i made it working by adding the display:flex on .container class.
jsfiddle https://jsfiddle.net/31rjm8qb/7/
You have a couple of problems here.
.main has width 100% so .sidebar can not fit
.sidebar is floated while .main is not, so they will not line up
I think it would be a good idea to try out display: flexbox and remove floats altogether.
Check out the following article: https://css-tricks.com/snippets/css/a-guide-to-flexbox/
I have the following HTML and CSS layout:
html {
position: relative;
min-height: 100%;
}
body {
/* Margin bottom by footer height */
margin-bottom: 100px;
}
.col-md-6 {
display: flex;
justify-content: center;
}
.container_flex {
display: flex;
align-items: center;
justify-content: center;
/* vh refers to viewport height. Very useful! */
height: 100vh;
width: 100%;
}
<div class="container-fluid">
<div class="container_flex">
<div class="row">
<div class="col-md-6 col-xs-12" style="border:solid">
<h1>Column 1</h1>
</div>
<div class="col-md-6 col-xs-12" style="border:solid">
<h1>Column 2</h1>
</div>
</div>
</div>
</div>
Which provides the following result:
Bootply
My aim of using Flexbox is to vertically center the contents of "row" inside the container-fluid. However, this results in the columns adopting a compressed look when in desktop mode. When in mobile view, the columns do stack as expected. I would be grateful if someone could explain why this compressed/stubby look comes about?
In contrast, if I remove the row class, this stubby compressed look no longer is brought about as shown:
Bootply
However, the columns no longer stack when in mobile view. Is there any way that I can rectify this?
If anyone has any tips/pointers on how to effectively use FlexBox with Bootstrap to vertically and horizontally center in a more effective way than what I have attempted here, I would be very grateful.
When you remove the row element the .col elements become your flex-items. In order to get flex-items to wrap in a flex container you need to use the flex-wrap property. However, I don't think removing the row element and using flex-wrap is what you really want.
With regards to your question. The reason it looks stubby in your first example is because you are making the row element your 'flex-item'. The width of the row item then sizes to its contents because you have not set the flex property which controls its size. Once you set the flex property properly then you will see the desired results:
.container_flex {
display: flex;
align-items: center;
justify-content:center;
/* vh refers to viewport height. Very useful! */
height: 100vh;
width: 100%;
}
.row {
flex: 1;
}
<div class="container-fluid">
<div class="container_flex">
<!-- Note that if using Flexbox, then do not need to wrap col- in row class but then does not stack columns on mobile... use #media? -->
<div class="row">
<div class="col-md-6 col-xs-12" style="border:solid">
<h1>Column 1</h1>
</div>
<div class="col-md-6 col-xs-12" style="border:solid">
<h1>Column 2</h1>
</div>
</div>
</div>
</div>
Here is a brief explanation why: flex:1 is a shortcut property that sets three separate flex-item properties to:
flex-grow: 1; If the size of the flex-item is smaller than available space within the flex container then setting this to a value greater than 0 makes the item stretch to fill the available space. If there are multiple flex-items in the same container they grow to share the available space in proportion to the value of their flex-grow property.
flex-shrink: 1; If the size of the flex-item is larger than the available space within the flex container then setting this to a value greater than 0 makes the item shrink to fit the available space. If there are multiple flex-items in the same container they will shrink to share the available space in proportion to the value of their flex-shrink property.
flex-basis: 0%; Defines the starting size of the element before being "flexed".
For general informanton on using flex-box take a look at this article over at css tricks by Chris Coyier; he does a great job explaining how flex-box works.
If you are looking for information on using bootstrap and flex-box together I recommend reading this article as well!
I hope this helps.
you need to give flex:1 to .row which it shorthand for flex-grow, flex-shrink and flex-basis combined. Default is 0 1 auto, using flex:1 means it will be 1 1 0
html {
position: relative;
min-height: 100%;
}
body {
/* Margin bottom by footer height */
margin-bottom: 100px;
}
.row {
flex: 1
}
.col-md-6 {
display: flex;
justify-content: center;
}
.container_flex {
display: flex;
align-items: center;
justify-content: center;
/* vh refers to viewport height. Very useful! */
height: 100vh;
width: 100%;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<div class="container-fluid">
<div class="container_flex">
<div class="row">
<div class="col-md-6 col-xs-12" style="border:solid">
<h1>Column 1</h1>
</div>
<div class="col-md-6 col-xs-12" style="border:solid">
<h1>Column 2</h1>
</div>
</div>
</div>
</div>
You may also use the flex built-in library from bootsrap (it will also be responsive):
http://v4-alpha.getbootstrap.com/layout/flexbox-grid/#responsive-flexbox
.col-md-6.col-xs-12{border:solid}/* CSS neede cause border are not set by default in bootsrap :) */
<link href="http://v4-alpha.getbootstrap.com/assets/css/docs-flexbox.min.css" rel="stylesheet"/>
<link href="http://v4-alpha.getbootstrap.com/dist/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container">
<p>To see cols side by side, run snippet in full page mode and reduce it down to average 720px width to see col stacking </p>
<div class="row">
<div class="col-md-6 col-xs-12" >
col 1
</div>
<div class="col-md-6 col-xs-12" >
col 2
</div>
</div>
</div>
I have two variable-width elements that I'm trying to position the following way:
If they fit next to each other on the screen or in their common container, I want them align to the opposite sides of it (i.e. the second one aligned to right).
If they don't, I want them one above the other, but both aligned to the left.
Something as simple as:
<div class="container">
<div style="display: inline-block;">
I'm a variable width left element
</div>
<div style="display: inline-block; float:right;">
I'm right-floating if there's space
</div>
</div>
takes care of the first case, but obviously when the container is small enough for the second div to be rendered below the first one, it's still right-floating which is not what I want.
Is this even possible with pure CSS? I can't use media queries because of unknown/variable widths.
This layout and behavior is possible without media queries and pure CSS using flexbox.
HTML
<!-- horizontal alignment when two boxes fit -->
<div class="container">
<div class="box box1"><span>1</span></div>
<div class="box box2"><span>2</span></div>
</div>
<!-- vertical alignment when two boxes don't fit -->
<div class="container">
<div class="box box3"><span>1</span></div>
<div class="box box4"><span>2</span></div>
</div>
CSS
.container {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
width: 700px; /* for demo only; can be relative length, as well */
}
.box1 { width: 100px; }
.box2 { width: 150px; }
.box3 { width: 400px; }
.box4 { width: 500px; }
DEMO
NOTES:
When there is enough space to fit both variable-width elements on the same row, they are aligned at opposite ends of the container with justify-content: space-between.
When there is not enough space to fit both elements, they wrap with flex-wrap: wrap and align-left because the justify-content: space-between rule will left-align an element when it is alone on the row.
Note that flexbox is supported by all major browsers, except IE 8 & 9. Some recent browser versions, such as Safari 8 and IE10, require vendor prefixes. For a quick way to add all the prefixes you need, post your CSS in the left panel here: Autoprefixer.
I'm trying to do a responsive design for a menu, you can see the code here.
As you can see flex works pretty well for that design. My only concern is that it won't be compatible with older browsers. Is there an easy way of implementing this without flex, I have tried having only divs inside a container here
The problem is I don't know how to make the My log box appear beside the New log box.
I want to keep responsiveness (boxes stacking up vertically in smaller screens).
Here is the code:
HTML:
<div class="block-menu vertical">
<div class="menu-item">My organizations</div>
<div class="block-menu horizontal">
<div class="block-menu vertical">
<div class="menu-item">
ITPs
</div>
<div class="menu-item">
My log
</div>
</div>
<div class="menu-item">
New log
</div>
</div>
<div class="menu-item">
Profile
</div>
</div>
</div>
CSS:
div.block-menu.horizontal {
display: flex;
width: 100%;
flex-wrap: wrap;
}
div.block-menu.horizontal > div {
flex-grow: 1;
}
div.block-menu.vertical {
display: flex;
flex-direction: column;
}
div.block-menu.vertical > div.menu-item {
width: auto;
}
.menu-container div.menu-item {
padding: 20px;
margin: 10px;
background-color: red;
flex-grow: 1;
}
If you add one extra div (like it is in the flex example), it is kind of simple playing with the values for float and width, you can see an example here: http://jsfiddle.net/ggb2ecu7/3/
Although that one doesn't take into account the margin that you have in the flex example. To fix that, you could use calc, like this: http://jsfiddle.net/ggb2ecu7/4/ (sorry about the extra unnecessary CSS rules). E.g.:
.w2 {
width: calc(100% - 20px);
}
[20px because the margin I set was 10px (on both sides = 20px)]
The problem with calc is that it may not work with all the older versions. You can check the support for calc in here: http://caniuse.com/#feat=calc