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>
Related
(I use HTML, CSS, Bootstrap 3.3.7 with Gridsystem, I'm new to JS/jQuery)
Hey guys,
I'm building a SPA (single page application) that has multiple elements, each 100vh, so it should look like 4 different "slides".
My problem:
I don't want the DIVs, images, headings and paragraphs to be responsive in terms of stacking elements under and over depending on the window size.
The elements should move pretty much proportionally however I size the browser window. Like if you make a picture bigger and smaller. Everything should shrink together with a pretty much proportional scaling if I make the window smaller.
I am sure there is the knowledge out there but please help me I'm too stupid I googled half an hour and didn't find anything.
Do you know the attributes and styles I need to apply to my elements to get rid of the ugly over-stacking of elements? To give things a proportional scaling.
A thousand thanks!
.wrapper {
display: flex;
flex-direction: row;
height: 100%;
}
.item {
display: flex;
flex-direction: row;
height: 90vh;
}
<div class='wrapper'>
<span class='item'>1</span>
<span class='item'>2</span>
<span class='item'>3</span>
<span class='item'>4</span>
</div>
You can use this snippet as reference. Let me know if I am wrong.
You don't need Flex for this requirement.
You can easily constrain blocks from stacking by simply using col-xs-*
.block {
height: 100vh;
background: gray;
border: 5px solid blue;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<div class="container-fluid">
<div class="row">
<div class="col-xs-3 block"></div>
<div class="col-xs-3 block"></div>
<div class="col-xs-3 block"></div>
<div class="col-xs-3 block"></div>
</div>
</div>
I am using ZURB foundation 6 with XY grid and have run into a little problem and most likely something I'm doing wrong.
I want to center elements vertically so I use
<div class="flex-container">
<div class="grid-x grid-padding-x align-middle">
<div class="small-6 cell">Vertically Centered Left Column</div>
<div class="small-6 cell">Vertically Centered Left Column</div>
</div>
</div>
And using jQuery I set the height of flex-container by using windowHeight = $(window).innerHeight();
Voila the items are vertically aligned... However two issues arise from this:
small-6 cell has a width of 50% that is not being respected and shrinks down to the approx length of the text.
flex-container unlike grid-container does not have a width or padding.
To resolve the issue I added some CSS like so:
.flex-container .align-middle {
max-width: 62.5rem;
margin: 0 auto;
width: 100%;
}
So while I've patched the issue I can't help thinking that there must be an easier way, a proper way using just classes. It seems odd that grid-container is setup to do so but flex-container is not.
The main problem here is that with flex-container, the grid-x element will, along being a flex container of its own, also become a flex row item, having the default flex item value 0 1 auto.
This means the grid-x won't grow wider than its content, hence width: 50% won't work on its children (small-6), as their parent doesn't have a width set.
By adding e.g. flex-child-grow or cell to the grid-x element, it will fill its parent's width, and the inner flex items will start behave as expected.
Note 1: With grid-container this is not needed since it is not a flex container, where the grid-x is a normal div, displayed as flex, which, like a block element, by default take full width of its parent.
Note 2: Both flex-container and grid-container does have a default width of 100%, it is the grid-x, when being a flex item, that cause the issue not taking its parent's width by default.
Stack snippet
/* for demo purpose */
body { margin: 0; }
.flex-container { height: 100vh; }
.grid-x { border: 1px solid red; }
.small-6 { border: 1px solid blue; }
<link href="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.4.3/css/foundation.css" rel="stylesheet"/>
<div class="flex-container">
<div class="flex-child-grow grid-x grid-padding-x align-middle">
<div class="small-6 cell">Vertically Centered Left Column</div>
<div class="small-6 cell">Vertically Centered Left Column</div>
</div>
</div>
Update 2
Following #kidconcept's new update about using the table tag, I have modified it to make a centered
Table Timeline. Note: copy-pasting #kidconcept's into a local project (not on JS Fiddle) did not have this property. I also added css selectors to make changing direction easier.
Thank you for considering my question.
I am trying to make a custom row. What I want to achieve is describe in more detail under the headings description.
In addition I am including a JS Fiddle, which gets me close (maybe) to what I want to achieve (e.g. I put some work in).
I don't really get CSS3 that well, and the tutorials at W3-schools really only cover basics, however a deeper understanding of the difference between display options and what float actually does to the object is not readily given.
So I appreciate your assistance and am eager to learn from you :)
Description
JS Fiddle: A tri-element row with fixed size middle element
I am trying to make a row which contains exactly three elements. I want the middle element to have a fixed size and be centered. I want the other two elements (left / right) to have a fixed spacing to the middle element, but be responsive in size, see below:
In addition, I would like to stack these rows with a fixed spacing:
As well as be responsive to a small window size:
Update
Using the answer from #kidconcept you can make a reasonable timeline.
UPDATE: I think this is more easily solved with a table. Simply create a table with three columns and give a fixed width to the middle column.
<table>
<tr>
<td></td>
<td class="middle"></td>
<td></tr>
</table>
td {
background-color: tomato;
padding: 2rem;
}
.middle {
width: 10rem;
}
Table Fiddle
https://jsfiddle.net/botbvanz/2/
Problematic Flex method: flex. Learn more about flex here.
<section class="tri-element-rows">
<div class="left-element"></div>
<div class="middle-element"></div>
<div class="right-element"></div>
</section>
html, body {
height: 100%
}
section {
display: flex;
height: 50%;
}
div.middle-element {
width: 15rem;
height: 10rem;
}
div.left-element,
div.right-element {
flex-grow: 1;
}
div {
background-color: coral;
margin: 1rem;
}
To achieve the effect simply put three elements within a display: flex box. Set the middle elements width to be fixed, in this case 15rem. Then give the left/right elements flex-grow: 1, which indicates they should fill the remaining space equally. Give all the divs a fixed margin, in this case 1rem.
For the heights, I'm not sure I understood your requirements exactly, but if you want the height of the inner divs to respond to the window you can set their height to be a % of the parent container. For this trick to work you need to remember to set the height of html and body to 100% (this gives them something to be a percentage of. In this case i set the section-height to be 50%, which means that two rows will always fill the screen. One other gotcha is that if you set a padding or a border to the section element, the element will become 50% plus the padding and border. To avoid this, set box-sizing: border-box on the section tag.
Here is a fiddle: https://jsfiddle.net/ksgd6r11/
i would suggest use a framework
Bootstrap
Skeleton
and many more
It saves a lot of time and you can focus on logic
they all have offset as one of their classes
However how we achieve the same in Bootstrap is
<div class="container">
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
<div class="col-xs-2 col-xs-offset-3 col-sm-2 col-sm-offset-3 col-md-2 col-md-offset-3 col-lg-2 col-lg-offset-3">
</div>
<div class="col-xs-2 col-sm-2 col-md-2 col-lg-2"></div>
<div class="col-xs-2 col-sm-2 col-md-2 col-lg-2"></div>
</div>
</div>
what it does it gives a padding left to the left most block
In your case.check this(jsfiddle)
or rather
div.block{
width:32%;
height:50px;
border:1px solid black;
float:left;
margin:2px;
}
div.block-2{
width:31%;
height:50px;
float:left; border:1px solid black;
margin:2px;
}
div.margin-l{
margin-left:50px;
}
div.section-2{
margin:0 auto;
width:60%;
}
<section class="tri-element-rows">
<div class="block">
</div>
<div class="block">
</div> <div class="block">
</div>
<div class="section-2">
<div class="block-2 ">
</div>
<div class="block-2">
</div><div class="block-2">
</div>
</div>
</section>
I agree with kidconcept that the flexbox flex-grow property is your best solution. This article is a good resource for getting started with flexbox. Some developers still shy away from the flexbox module, but it’s extremely useful and browser support is great. That said, in the spirit of trying to help you learn a bit more, I created something close to what you’re asking for using simple floats.
Fiddle
<section class="row">
<div class="left">
<p>Left</p>
</div>
<div class="right-block">
<div class="center">
<p>Center</p>
</div>
<div class="right">
<p>Right</p>
</div>
<div>
</section>
<section class="row">
<div class="left">
<p>Left</p>
</div>
<div class="right-block">
<div class="center">
<p>Center</p>
</div>
<div class="right">
<p>Right</p>
</div>
<div>
</section>
.row {
width: 100%;
height: 180px;
margin-top: 20px;
}
.left p, .right p {
padding: 0 30px;
}
.left {
height: 100%;
background: red;
width: 40%;
float: left;
}
.center {
width: 140px;
height: 120px;
margin: 0 20px;
background: #4FBA49;
float: left;
text-align: center;
}
.right-block {
height: 100%;
margin-left: 20px;
overflow: hidden;
}
.right {
height: 100%;
background: #FDCF1A;
overflow: hidden;
text-align: right;
}
On a more conceptual level, floats pull elements from the normal flow of things on the webpage, shifting them to the left or right and allowing text etc. to wrap around them. Honestly, they’re not all they’e cracked up to be imo and I’ve always found them an imperfect solution. This article gives a helpful overview of floats.
You may also find this answer helpful in understanding how to use floats together with overflow: hidden property, a useful concept that I used in my Fiddle. Finally, you'll probably also benefit from reading up on css grids as well, especially in the context of Bootstrap or some other framework. Hope this helps!
I am trying to create a responsive grid with flexbox:
On large screens, there should be three columns in one row
On smaller screens, just two rows or one
My code so far:
.grid {
display: flex;
flex-wrap: wrap;
}
.gridColumn {
flex: 1 1 0px;
background-color: lightblue;
min-width: 200px;
}
<div class="grid">
<div class="gridColumn">
<p>first column</p>
</div>
<div class="gridColumn">
<p>second column</p>
</div>
<div class="gridColumn">
<p>third column</p>
</div>
</div>
Now, I would like to set margins only between the columns (not on the sides of the grid as well), which should also behave correctly when the screen is resized. Does anybody know of a way to achieve this?
You can add a margin to the grid items...
.gridColumn {
margin: $margin;
}
... which is then offset by its container.
.grid {
margin: -$margin;
}
To avoid overflow, you could apply overflow-x: hidden to the body.
Codepen example
It's crashed on this part of code
.gridColumn + .gridColumn {
margin-left: 20px;
}
You should to try use media query and set margin-left: 0; on small screens.
Above part of code is still working because flex-wrap only changing the position of the "third column", that column still have "sister" before and margin-left is working.
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.