Creating equal height divs in Bootstrap 4 flexbox - html

I use Bootstrap 4 flexbox enabled. I can not make row > col > div box equal heights.
I have tried position: absolute but it is not the best.
Here's a screenshot:
<div class="row" >
<div class="col-xs-12" >
<div class="home_category" ></div>
</div>
<div class="col-xs-12" >
<div class="home_category" ></div>
</div>
</div>
col-xs-12's height always equals but .home_category height varies based on content size.
I'm looking for a solution to have 100% height for .home_category. Same height as col-xs-12.
Live demo at https://officestock.ca/
I appreciate your feedbacks.

In reviewing your code, the boxes are currently getting their height from the content. You'll notice that some image labels are two-line and others are three-line. The differences in those line numbers are causing differing heights for the boxes.
To apply full, equal height to all boxes simply make this adjustment to your CSS:
#media (min-width: 48em) {
.col-md-6 {
flex: 0 0 50%;
display: flex; /* NEW */
}

Related

Zurb Foundation 6 XY Grid using Grid Container within Flex-Container

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>

Flexbox layout losing proportions when reduced in size

I'm reproducing a golden spiral using CSS flexbox and percentage size for cells.
The round shape is drawn using a regular border and border-radius combination.
Everything is proportional until I resize the window to smaller widths.
I tried removing borders completely and turns out the layout is still losing proportions at some point.
Big container:
Small container:
Demo:
https://jsfiddle.net/s09rkwub/1/
html
<div class="wrapper">
<div class="rows fib">
<div class="cols fill">
<div class="rows fill">
<div class="fr tl">3</div>
<div class="fill cols">
<div class="fc bl">4</div>
<div class="fill rows">
<div class="fill cols">
<div class="fill tl fr">7</div>
<div class="fc tr">6</div>
</div>
<div class="fr br">5</div>
</div>
</div>
</div>
<div class="fc tr">2</div>
</div>
<div class="fr br">1</div>
</div>
</div>
css
.rows {
flex-direction: column;
}
.cols {
flex-direction: row;
}
.rows,
.cols {
display: flex;
.fill {
flex: 1;
}
> * {
outline: solid 1px rgba(127,127,127, 0.3);
}
}
...
Update:
Working demo with applied solution.
Update 2
Thanks to Your support guys. I could finish my fib spiral codepen.
Solution
Add this to your code:
* {
flex-shrink: 0;
min-width: 0;
min-height: 0;
}
revised fiddle
Explanation
Two concepts to consider:
An initial setting of a flex container is flex-shrink: 1.
This means that, by default, flex items are allowed to shrink below any defined width, height or flex-basis.
To prevent this behavior use flex-shrink: 0.
More details here: What are the differences between flex-basis and width?
An initial setting of a flex item is min-width: auto.
This means that, by default, a flex item cannot be smaller than the size of its content (regardless of flex-shrink or flex-basis).
To allow flex items to shrink past their content use min-width: 0 (row direction), min-height: 0 (column direction), or overflow: hidden (other values also work, except visible).
More details here: Why doesn't flex item shrink past content size?
With the adjustment below, your flex items can shrink past the text you have in your divs, allowing the scaling to continue without any obstacles:
* {
flex-shrink: 0;
min-width: 0;
min-height: 0;
}
Taking <div class="fr br">5</div> as an example, it's min-width is 26px. Thus, scaling the spiral down to a level, where the mentioned div's height becomes less than 26px, it's getting distorted.
If you change the border width to 1px instead of 5px, you'll see, that suddenly, it's able to scale down to 18px perfectly fine and breaks in smaller sizes.
That's why you probably tried to reduce the border. However, the reason for the distortion is much simpler: You have content inside the divs and they do require some space (even if the font color is transparent). If you remove all the numbers from the div elements, you get the desired result. See the demo at https://jsfiddle.net/s09rkwub/2/

Move a div below another div at a certain screen width

I have a mobile website with 4 banners that appear side by side. When I get to a certain screen width, I want 2 of them to drop below the other 2. Part of the problem is that I have used width: 24.96% to obtain the right total width of all 4 divs to fit the body.
CSS
.small_banners .banner_block {
display: block;
max-width: 100%;
height: auto;
width: 24.96%; }
.small_banners {
float: left;
clear: both;
width: 100%;
margin: 0 0 15px; }
HTML
<div class="small_banners">
<div class="banner_block">
<div>
Content
</div>
</div>
<div class="banner_block">
<div>
2nd piece of content
</div>
</div>
<div class="banner_block">
<div>
3rd piece of content
</div>
</div>
<div class="banner_block">
<div>
The 4th piece of content
</div>
</div>
</div>
When the screen reaches 958px I want the 3rd and 4th divs to drop below the 1st and 2nd, using a simple media query: #media all and (max-width: 958px) {
this should work.
#media (max-width: 958px) {
.small_banners .banner_block{
width:50% !important;
}
}
Kishan's method does indeed work if implemented correctly! Here's a fiddle that illustrates using the css max-width property to change the width of the 4 .banner_block elements depending on the screen width.
https://jsfiddle.net/evc670st/1/
Note elements with class banner_block use display:block and float:left to stack horizontally. If you don't want to float these elements, you can use display: inline-block, but make sure there is no whitespace in between your html markup.
Source: https://css-tricks.com/fighting-the-space-between-inline-block-elements/

Adding a responsive image to a position fixed div within a Bootstrap column

I have a two column layout, one column is the document content and the other is the navigation. I've set this up using a Bootstrap row, one column is 8 units wide and the other is 3 units wide with an offset of 1 unit. I've set the navigation content to fixed so that it stays on the page.
On some of the pages I want to have an image at the top of the navigation column. I want this image to be responsive and stay within the 3 unit column and be fixed along with the navigation. However, when you set the content to fixed the image is no longer constrained within the 3 unit column.
I've set up a jsfiddle of the problem at http://jsfiddle.net/yKUZW/3/.
Here is the example html:
<div class="container">
<div class="row">
<div class="col-xs-8 content">Content goes here...</div>
<div class="col-xs-3 col-xs-offset-1">
<div class="fixed">
<img class="img-responsive" src="http://placekitten.com/300/200">
Some links go here.
</div>
</div>
</div>
</div>
And the relevant css:
.fixed {
position: fixed;
top: 150px;
}
Notice that when the page is resized horizontally the image stretches outside of the light grey container area. What I want is for the right hand side of the image to always align exactly with the right hand edge of the container, resizing the image as needed.
How would I go about accomplishing this?
The Problem
Ignore the image for a second... .img-responsive just makes the image take up 100% of the available space in the parent container.
Then the question becomes, can I add position: fixed to a div and still have it take up the same width as it's parent which has .col-xs-3 (width: 25%)? Once we resolve that, the image should fall into line.
As you may already know about fixed positioning:
for a fixed positioned box, the containing block is established by the viewport
Meaning Fixed is always relative to the parent window, never an element.
Simple Solution
If the viewport is the same width as the parent div, this can be resolved trivially:
HTML:
<div class="row">
<div class="col-xs-9" id="content">C</div>
<div class="col-xs-3">
<div id="navbar">Navbar</div>
</div>
</div>
Relative - div takes up 100% of width of parent (.col-xs-3):
#navbar {
background: yellow;
position: relative;
}
Fixed - div takes up 100% of screen - apply .col-xs-3 width ourselves:
#navbar {
background: yellow;
position: fixed;
width: 25%;
}
Demo in Fiddle
Better Solution
However, that solution isn't much help to us because the the .container class applies variable widths at different breakpoints to the row. This causes 25% of the parent div and 25% of the viewport to get out of sync.
So how can we get them to sync up again?
To answer that, let's look at exactly what .container is doing:
.container {
#media (min-width: #screen-sm-min) {
width: #container-sm;
}
#media (min-width: #screen-md-min) {
width: #container-md;
}
#media (min-width: #screen-lg-min) {
width: #container-lg;
}
}
So instead of trivially being able to apply a 25% width, we now have to mimic the width applied by .container. Here's how:
Here's some sample markup:
<div class="container">
<div class="row">
<div class="col-xs-8 content">Content</div>
<div class="col-xs-3 col-xs-offset-1" id="sidebar-outer">
<div id="sidebar">
Width: <span id="width-placeholder"></span>px
</div>
</div>
</div>
</div>
Now we can apply a width at all breakpoints with the following CSS:
#sidebar {
background: yellow;
position: fixed;
width: 25%;
}
#media (min-width: 768px) {
#sidebar {
width: 158px; /* 632 * .25 */
}
}
#media (min-width: 992px) {
#sidebar {
width: 213px; /* 852 * .25 */
}
}
#media (min-width: 1200px) {
#sidebar {
width: 263px; /* 1052 * .25 */
}
}
Here's a side by side comparison of using relative vs fixed position with styling:
Demo in Fiddle
Back to our problem at hand:
Just take the demo from above and add back in our responsive image:
Solution Demo in Fiddle
As a note: most sites opt to use a fixed width side navbar when using position:fixed in order to sidestep these kinds of issues.
After messing with it a bit I believe the best way would be to remove the the fixed div from the bootstrap column, and place it higher up in the dom, or at least outside of the row. There is a lot of negative margin and strange padding stuff going on to get the BS cols to work properly and it is pushing your fixed div around. If it were me and this was going to be a main feature on the site I would make a div with width 100%, abs pos, top left right bottom all at 0, and then place the fixed div inside of that. For a fixed pos div you want it to live in a relative pos parent with right set to 0 and top set to 150 in your case. If the parent is 100% of the windows width then you have pretty good control over where it goes using either px or %.
Thanks Kyle for the amazing solution you described at the top.
Here is a solution for 8/4 situation in a normal container (not fluid)
<div class='container'>
<div class='row'>
<div class='col-xs-8> something here </div>
<div class='col-xs-4>
<div id='sidebar'> content
</div>
</div>
</div>
</div>
and here the css
#sidebar {
background: blue;
position: fixed;
width: 33.3333%;
}
#media (min-width: 768px) {
#sidebar {
width: 235px;
}
}
#media (min-width: 992px) {
#sidebar {
width: 309px;
}
}
#media (min-width: 1200px) {
#sidebar {
width: 375px;
}
}

Setting a fixed height for 3 div's

Im having an issue with the header of my code. The header is split into 3 different column's two of which are currently populated with text and an image. (center is yet to be filled).
I notice that when i reduce the size of my browser (zoom in,out) two of the header column's start to break away from the content. The right column stays fixed to the content below because it is populated with text however the center column and the left column being less populated start to break away.
Is it possible to force my 3 column header to stay attached to the content below? Im worried that if someone views the site on a large screen or perhaps a retina display it is going to break away.
<div class="col span_1_of_3 a">
<div class="col span_1_of_3 b">
<div class="col span_1_of_3 c">
CSS is as follows:
.span_3_of_3 {
width: 100%;
}
/* line 28, ../sass/test.scss */
.span_2_of_3 {
width: 66.1%;
height:100%;
}
/* line 32, ../sass/test.scss */
.span_1_of_3 {
width: 33.32%%;
height:100%;
}
Wrap the divs in a parent div. Then float the children and give them a relative width.
<div class="header">
<div class="col span_1_of_3 a">
<div class="col span_1_of_3 b">
<div class="col span_1_of_3 c">
</div>
css:
.header { width:100%; overflow:auto; }
.col { float:left; width:30% }
You can use display: table-cell on each .col and display: table on parent (*). That will force your "cells" to have the same height and stay on the same row.
Though I wonder how you managed your witdths? Is it in percentage or em? You didn't include any CSS so it's impossible to figure.
(*) Add table-layout: fixed on this same parent if you want precise widths to be applied, otherwise the browser will also adapt to the content of each "cell".
Image re sizing will be out of control unless you set the Width/Height to percentage or relative values.
if you don't want to do this, simply set the min-width and min-height CSS Properties.
i prefer the relative sizing (ex. width: 30%; text-align: left;)