Flexbox: variable/dynamic height items with column wrap - css

I'm struggling with creating a dynamic layout which is different for mobile and desktop. The items should be different sorted based on the screen width and the layout should change.
Below is the main objective, where the left layout is for mobile and the right one is desktop:
The content of the blue, purple and yellow div can vary so the height is adjustable. The purple and yellow block must always be on the side of the gray + blue block on desktop.
Right now I have it working for only 3 columns but the 'dynamic' height is duplicated on all columns: Bootstrap 4: sidebar between columns on mobile. Columns under each other layout
To give you a clear idea of the possibilities here are some desktop variations:
I've managed to get it working with floats but the columns align on each other. Also have fixed it with a static max-height for the parent and use column wrap but I don't want to use a static max-height since the content should have a dynamic height..
I don't want to use some glitchy javascript or unsupported grid-css.
Looking forward to ideas/suggestions! Cheers.

You should be able to get this layout to work with a combination of CSS columns (not CSS grid) on "desktop", and flexbox on "mobile".
<div class="container">
<div class="d-flex d-md-columns flex-column min-vh-100">
<div class="d-md-inline-block light order-0">
light
</div>
<div class="d-md-inline-block blue order-2">
blue
</div>
<div class="d-md-inline-block purple order-1">
purple
</div>
<div class="d-md-inline-block yellow order-3">
yellow
</div>
</div>
</div>
The only extra CSS you'll need is a media query for the columns on larger (md) desktop widths. The the flexbox ordering will kick-in on mobile..
#media (min-width: 768px) {
.d-md-columns {
display: inline-block !important;
column-count: 2;
-webkit-column-gap: 0
-moz-column-gap: 0;
column-gap: 0;
}
}
https://codeply.com/go/QWIlredUTk
This works specifically for this 4 column layout. However, generally speaking flexbox columns do NOT fit together vertically like a "masonry" layout: Is it possible for flex items to align tightly to the items above them?

I think there is no pure CSS solution for this (at least without using CSS-grid or display:contents). Every CSS way I thought had bugs: float & column flexbox simple don't work in this particular case.
Column flexbox cannot wrap correctly an item if we work with a content without fix height and float can't create a "masonry" layout. Also Bootstrap card-columns are not a solution because your main objective is to align left and right column in height.
I know, you don't want glitchy javascript, but I think it is necessary to create your layout. So, I post you my solution (a jquery solution) without use any d-none class to prevent duplicate HTML & SEO problems.
Moreover, you are using Bootstrap and this framework makes extensive use of jQuery so, I think, it not a problem to ask jQuery for a little help. This help:
function move(){
if($(".main .col-lg-8").css('display')=='block'){
$('.purple').insertAfter('.gray');
} else {
$('.purple').insertBefore('.yellow');
}
}
$(window).resize(function(){move()})
$(document).ready(function(){move()})
To move our purple div in second position when .col-lg-8 have display:block
This is all code in action:
function move(){
if($(".main .col-lg-8").css('display')=='block'){
$('.purple').insertAfter('.gray');
} else {
$('.purple').insertBefore('.yellow');
}
}
$(window).resize(function(){move()})
$(document).ready(function(){move()})
.gray{
background-color: gray;
}
.blue{
background-color: blue;
}
.purple{
background-color: purple;
}
.yellow{
background-color: yellow;
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<div class="container mt-5">
<div class="row main">
<div class="col-lg-4 d-lg-flex flex-lg-column">
<div class="gray mb-4">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque sodales finibus faucibus. Morbi blandit neque a diam laoreet pellentesque. Vivamus in orci sed turpis posuere iaculis quis sed augue. Curabitur lorem magna, bibendum vitae vestibulum nec faucibus. Morbi blandit neque a diam laoreet pellentesque. Vivamus in orci sed turpis posuere iaculis quis sed augue. Curabitur lorem magna, bibendum vitae vestibulum nec, feugiat eget justo. Ut aliquam quis velit non euismod. Ut vehicula, sem quis cursus pretium, purus libero tincidunt eros, vitae hendrerit nisi mi vitae erat. Curabitur augue purus, sagittis tempor volutpat quis, congue sed mi. Sed gravida odio sed orci iaculis tincidunt. Etiam ac mauris sit amet turpis consequat fermentum ut vitae sem. Aliquam tincidunt convallis sem.</div>
<div class="blue flex-fill mb-4 mb-lg-0">
Lorem ipsum dolor sit amet, consectetur.Quisque sodales finibus </div>
</div>
<div class="col-lg-8 d-lg-flex flex-lg-column">
<div class="purple mb-4">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. faucibus. Morbi blandit neque a diam laoreet pellentesque. Vivamus in orci sed turpis posuere iaculis quis sed augue. Curabitur lorem magna, bibendum vitae vestibulum nec, feugiat eget justo. Ut aliquam quis velit non euismod. Ut vehicula, sem quis cursus pretium, purus libero tincidunt eros, vitae hendrerit nisi mi vitae erat. Curabitur augue purus, sagittis tempor volutpat quis, congue sed mi. Sed gravida odio sed orci iaculis tincidunt. Etiam ac mauris sit amet turpis consequat fermentum ut vitae sem. Aliquam tincidunt convallis sem. </div>
<div class="yellow flex-fill">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.</div>
</div>
</div>
</div>
Waiting a pure CSS solution, this could be a way.

Related

Why is this image resized inside container with flex-wrap value different than wrap?

I am playing with Bootstrap 4 and I have noticed that when I put <img> inside <div class="row"> that has flex-wrap: nowrap, Firefox will automatically resize the image. Code and link to pen is below.
Why does Firefox do that, how does it calculate resizing ratio and how can I make it stop?
Codepen with issue (compare upper and lower image)
Screenshot on Firefox 59
.nowrap {
flex-wrap: nowrap;
}
<div class="container">
<div class="row nowrap">
<img src="https://www.w3schools.com/howto/img_fjords.jpg">
Lorem ipsum dolor sit amet enim. Etiam ullamcorper. Suspendisse
a pellentesque dui, non felis. Maecenas malesuada elit lectus felis, malesuada
ultricies. Curabitur et ligula. Ut molestie a, ultricies porta urna.
Vestibulum commodo volutpat a, convallis ac, laoreet enim.
</div>
</div>

Bootstrap: Background colour 100% screen width?

I'm trying to create a fairly simple website in bootstrap. I'd like each section to have its own background colour similar to what is done here: https://flaticons.co/. Do you happen to know if there's a class or css styling that will allow the background to be 100% width?
<div id="main" class="container">
<section class="row">
<p class="col-md-4 col-sm-6" col-sm-push-7><img src="images/an_image.gif"></p>
<h1 class="col-md-8 col-sm-6" col-sm-pull-7>Some content...</h1>
</section>
<!-- ===== background colour wanted here 100% window width===== -->
<section id="about" class="row">
<div>
<p>Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Maecenas faucibus mollis interdum. Donec id elit non mi porta gravida at eget metus. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Etiam porta sem malesuada magna mollis euismod. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor.</p>
<p>Integer posuere erat a ante venenatis dapibus posuere velit aliquet. Donec ullamcorper nulla non metus auctor fringilla. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Aenean lacinia bibendum nulla sed consectetur.</p>
</div>
</section>
</div>
-----------This works:
Guys! Guys!
Thanks for those answers. They're great for when bootstrap isn't involved. When bootstrap IS involved... this works. So many divs :( But it's working great!
<div class="secondary">
<section class="row container">
<div class="row">
<p class="col-md-4 col-sm-6" col-sm-push-7><img src="images/temp_riley.gif"></p>
<h1 class="col-md-8 col-sm-6" col-sm-pull-7>Hi. I'm Riley: a problem solving UX designer (and front-end developer) who is intrigued by change and loves a good challenge. </h1>
</div>
</section>
css:
.secondary {
background: green;
}
To make an element 100% the screen width in CSS you can use the following:
width: 100vw;
The vw stands for view width. This is new to CSS3. See here for compatibility in browsers (Current browsers almost universally support it).
In your simple example, setting the width of each section and div to 100% will stretch them across your browser's window. Here's a fiddle showing what you're looking for, http://jsfiddle.net/MPQVu/, but the basic idea at play is:
.parent_div { width: 100%; }
.child_div { width: 100%; }

Always content to stay in middle of next child?

I am using Boostrap 3 for some website I am creating, what i want to make i next.
Here is a code
<section class="container-fluid">
<div class="container">
<div class="row">
<div class="col-md-6"><img class="img-responsive" src=
"http://webdesignledger.com/wp-content/uploads/2009/09/logo_design_4.jpg" /></div>
<div class="col-md-6">
<h2">Lorem ipsum dolor</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Aenean eu sollicitudin felis. Vestibulum vitae imperdiet nibh. Curabitur euismod
auctor libero sit amet varius. Maecenas eu porta libero. Pellentesque et sem et
turpis scelerisque hendrerit vel ac nibh. Nam tempor ullamcorper scelerisque.
Aenean accumsan ac justo ac laoreet. Aliquam eu libero</p>
</div>
</div>
</div>
<section>
Here is working fiddle
http://jsfiddle.net/gSmRw/
On big screen text always to be allign in the middle of the picture, i dont know how big picture will it be, maybe small maybe big, any idea, or help.
Here is picture what i want to make and how it has to look up
http://jsfiddle.net/gSmRw/3/
I've basically added a calss table to the .container element and changed the CSS of this container to be styled as table.
it's important to give the image div wrapper a width of 1% so the cell will not be wider than the image.

Twitter Bootstrap Preferred Way to Align Span Content

So this might seem like an obvious question to some, but what is the best practice for aligning versatile span content in a responsive grid? I know you could simply set a pixel height, but wouldn't that kind of defeat the purpose of keeping things responsive?
Take the below screenshot for instance:
<div class="container">
<div class="row">
<div class="span3 well"><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec facilisis venenatis sollicitudin. Nam eros risus, lobortis a ultricies sed, interdum in mi. Donec elementum ullamcorper odio, vel gravida velit pretium quis. Donec sagittis, sem nec rhoncus tristique, dui ante volutpat nisl, sit amet feugiat velit lorem sagittis turpis. Quisque laoreet arcu et sapien volutpat nec porta augue iaculis. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean accumsan feugiat libero, vel fringilla neque euismod vitae. Nullam justo mi, faucibus sagittis pharetra non, egestas sit amet nulla.</p></div>
<div class="span3 well"><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec facilisis venenatis sollicitudin. Nam eros risus, lobortis a ultricies sed, interdum in mi. Donec elementum ullamcorper odio, vel gravida velit pretium quis. Donec sagittis, sem nec rhoncus tristique, dui ante volutpat nisl, sit amet feugiat velit lorem sagittis turpis. Quisque laoreet arcu et sapien volutpat nec porta augue iaculis. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean accumsan feugiat libero, vel fringilla neque euismod vitae. Nullam justo mi, faucibus sagittis pharetra.</p> </div>
<div class="span3 well"><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec facilisis venenatis sollicitudin. Nam eros risus, lobortis a ultricies sed, interdum in mi. Donec elementum ullamcorper odio, vel gravida velit pretium quis. Donec sagittis, sem nec rhoncus tristique, dui ante volutpat nisl, sit amet feugiat velit lorem sagittis turpis. Quisque laoreet arcu et sapien volutpat nec porta augue iaculis. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean accumsan feugiat libero.</p> </div>
</div>
</div>
You can find the relevant JSfiddle here.
Note: Responsiveness seems to be broken in this JSFiddle for some reason, works fine in my own Twitter Bootstrap application however.
If you take a look on DigitalLabs which is a website I worked on then if you look at the profiles I came across a similar error - i wanted them all to be the same height.
See my JSFiddle here:
http://jsfiddle.net/LDtRr/2/
(scroll down to the bottom and press resize to see them all dynamically resize)
I used some javascript to fix the heights - I will show you the code that I used.
function resize(resize, resizeinner) {
var max = 0;
//reset height back to 0
$(resize).each(function(index, element) {
$(element).css({ 'height' : '0' });
});
//find height of the profiles
$(resizeinner).each(function(index, element) {
var height = $(element).height();
console.log(' height=' + height);
if(height > max) {
max = height;
}
});
//set the height dynamically based on the maximum so they are all uniform
$(resize).each(function(index, element) {
$(element).css({ 'height' : max });
console.log(' resizedTo=' + $(element).height());
});
console.log('max - ' + max);
}
Then for the html i used
<div class="span4">
<div class="well profile">
<div class="profile-resize">
<!-- content -->
</div>
</div>
</div>
What the code does is it gets the maximum height for the divs with the profile class, then sets all of the divs with that class to the maximum height - you can also bind this to the window resize so it automatically resizes the heights with the window.
$(window).load(function() {
//initially size the elements
resize('.profile', '.profile-resize');
});
Maybe not the most elegant solution but I couldnt think of a better one at the time.
Although your markup doesn't keep the hierarchy recommended by the bootstrap doc (.container > .row > .span > .well), have you thought about absolute positioning ? No JS involved.
Demo (jsfiddle)
<div class="container" style="position: relative;">
<div class="row faux-row">
<div class="span3 well"></div>
<div class="span3 well"></div>
<div class="span3 well"></div>
</div>
<div class="row vrai-row">
<div class="span3"><p>...</p></div>
<div class="span3"><p>...</p></div>
<div class="span3"><p>...</p></div>
</div>
</div>
.vrai-row { position: relative;z-index: 101; }
.faux-row { position: absolute;top: 0;left: 0;right: 0;bottom: 0;z-index: 100; }
.faux-row .well {
height: 100%;
/* The following is because .span* elements should not have paddings, margins nor borders see http://stackoverflow.com/a/11299934/1478467 */
box-sizing: border-box;
}
If you want to set padding, margin, borders (styling that actually take space), it should be applied to the real one and the faux one - not the columns themselves, but their children for example.
The downside is that (as it is in the demo) you have to stick to the non-responsive grid (fluid or static). But it should work with a few more rules encapsulated in media queries.
Update
Responsiveness is actually not so hard to get, if you keep the .well class on all spans :
Demo responsive (jsfiddle)
#media (max-width: 767px) {
.faux-row { display: none!important; }
}
#media (min-width: 768px) {
.vrai-row .well { /* Deactivate well styles */
background-color: transparent;
border-color: transparent;
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
}
}

IE not clearing subsequent floats

I'm trying to get two divs to float to opposite sides of the page, with text flowing between them. The top of the second (left-aligned) div should be even with the bottom of the first (right-aligned) div. The code below works fine in FF, Chrome, Opera, etc. fine, but they do not clear properly in IE. Both divs appear at the top of the text.
If I move the left-aligned div low enough within the text, it works fine in IE, but that's not really a sustainable solution.
I've found multiple pages on IE CSS float bugs, but I haven't found anything speaking directly to this.
CSS
div {
width: 200px;
margin-top: 10px;
border-style: solid;
border-width: 1px;
position: relative;
}
.wrapper {
width: 600px;
border-color: #FF0000;
}
.right {
float: right;
border-color: #00FF00;
}
.left {
float: left;
clear: both;
border-color: #0000FF;
}
HTML:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<link rel="stylesheet" href="float.css" />
</head>
<body>
<div class="wrapper">
<div class="right">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Nulla pretium tempor leo. Vivamus mi risus, dapibus ac,
consectetur quis, pellentesque eget, sem.
</div>
<div class="left">
Proin malesuada. Ut vel lorem. Cras rhoncus nisl accumsan
turpis tristique consequat. Sed lacinia ligula at nibh.
Morbi in quam. Morbi commodo nibh.
</div>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Nulla pretium tempor leo. Vivamus mi risus,
dapibus ac, consectetur quis, pellentesque eget, sem.
Maecenas est dui, imperdiet nec, fermentum ut,
pretium a, orci. Quisque hendrerit interdum orci.
Nulla sit amet risus non enim ultrices bibendum.
Aenean arcu purus, rhoncus at, vestibulum vel,
volutpat et, nunc. Integer eget risus eget purus viverra
congue.</p>
<p>Nullam vel libero ut purus semper ullamcorper.
Pellentesque mattis tincidunt odio. Nullam pulvinar
orci at dolor. Sed volutpat eros ac elit.
Praesent porttitor libero sed felis. Vivamus lobortis
pellentesque diam.
Proin laoreet massa ac metus. Integer faucibus lorem
molestie nibh. Integer id massa. Integer ligula ipsum,
pellentesque id, interdum at, pretium eget, orci.
Proin malesuada. Ut vel lorem.</p>
</div>
</body>
</html>
IE7 and IE6 have a variety of problems with elements that have both float and clear on them. In IE7, using clear on an element with float only clears the float below other floats floated in the same direction.
A modified version of the easyclearing fix may do the trick, but don't get your hopes up. See this page for details: New clearing method needed for IE7?.
Bottom line is that you're probably not going to get this to work in IE6/7 without cheating: moving the div down in the text, embedding the divs in paragraphs, etc.
I'm fairly sure this is one of those rare bugs in ie6 that doesn't have a pure CSS solution.
Try using the ie7 javascript - it may fix the problem for you: http://code.google.com/p/ie7-js/

Resources