Flexbox flex-wrap: is there a way to force wrap over growth? - multiline

I have a set of flex-items vertically stacked. The flex container is set to wrap. I would like it to wrap as soon as possible so it will fill the page horizontally instead of growing vertically. Plus the items are filled with dynamic text so I don't want to set a fixed height nor see them cropping.
HTML
<div class="fc v menu">
<div class="fa">
<h1>Title</h1>
<ul>
<li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>
<li>Aliquam tincidunt mauris eu risus.</li>
<li>Vestibulum auctor dapibus neque.</li>
</ul>
</div>
<div class="fa">ITEM 2</div>
<div class="fa">ITEM 3</div>
<div class="fa">ITEM 4</div>
<div class="fa">ITEM 5</div>
<div class="fa">ITEM 6</div>
<div class="fa">ITEM 7</div>
<div class="fa">ITEM 8</div>
</div>
CSS
.fc {
display: flex;
}
.fc.menu {
flex-wrap: wrap;
height: 15em;
}
.menu > div {
padding: 1em;
}
.fa {
flex: 1 0 auto;
width: 10em;
height: 5em;
}
.fc.v {
flex-direction: column;
background: pink;
border: 4px fuchsia solid;
}
You can see in the codepen that even if it is possible to force a sort of wrap the content will not fit the container anymore.

Related

Flexbox image with caption in column style

I am currently making a carousel of images. (Carousel is based on a library, not in the scope of this question as i also cannot get it to work outside the carousel).
What i am trying to do is the following: I have a div and within that div i have an image and a caption (just a line of text or 2). I want the image above the caption and as large as possible (taking up all the space the caption does not take up). But the image keeps exceeding the parent div's height. It is never contained in the parent div. And if it is, it loses its ratio (keeps the same width but height is contained which gives a weird result obviously).
I tried a lot with flexbox like this:
<div class="container"> // <---- this wrapper need a specific height depending on screen size.
<img src="/images/thing.png" class="img" alt="pict">
<div class="caption">
<span>Text</span>
</div>
</div>
and the CSS:
.container {
height: 800px;
}
.img {
width: auto;
height: 100%; // this fills the container with the image but i wont see the caption anymore.
// also tried giving this one flex (NOT in combination with above. Just showing all i tried)
flex: 1 1 0%;
}
.caption {
flex: 1 1 0%; // Or 1 1 auto; no difference
}
How do i go about this? Maybe it is just me struggling with flexbox. Maybe i am approaching this wrongly. Any help/tips is appreciated!
/* Horizontal flex: rows
=====================
*/
.row {
display: flex;
}
.item {
flex: 1 1 30%;
padding-left: 1.5rem;
}
.item:first-child {
padding-left: 0;
}
/* Vertical flex: items
===================
*/
.item {
display: flex;
flex-direction: column;
}
.item-heading {
flex: 1;
}
/* Third flex: item heading
========================
*/
.item-heading {
display: flex;
justify-content: center;
flex-direction: column;
}
/* Not so important CSS - base styles:
===================================
*/
body {
margin: 2rem;
}
img {
max-width: 100%;
height: auto;
}
h2,
p {
margin: 0;
padding: 0;
}
.row {
margin-bottom: 1.5rem;
}
.item-heading {
padding: 1rem;
font-size: 1rem;
background: yellow;
text-align: center;
}
.meta {
color: #666;
margin-bottom: 3rem;
}
.meta p {
margin-bottom: .5rem;
}
<div class="meta">
<h1>
Image gallery with a vertically centered captions
</h1>
<p>
Yellow headings we want both vertical and horizontal centered.
</p>
<p>
There are three nested flexbox containers – row, item and item heading.
</p>
</div>
<div class="row">
<div class="item">
<p class="item-image">
<img src="https://parosrentcar.com/wp-content/uploads/2018/05/kawasaki-250-600-200.jpg" alt="Image">
</p>
<h2 class="item-heading">
Lorem ipsum dolor sit amet
</h2>
</div>
<div class="item">
<p class="item-image">
<img src="https://parosrentcar.com/wp-content/uploads/2018/05/kawasaki-250-600-200.jpg" alt="Image">
</p>
<h2 class="item-heading">
Proin pede metus, vulputate nec, fermentum fringilla, vehicula vitae, justo
</h2>
</div>
<div class="item">
<p class="item-image">
<img src="https://parosrentcar.com/wp-content/uploads/2018/05/kawasaki-250-600-200.jpg" alt="Image">
</p>
<h2 class="item-heading">
Consectetuer adipiscing elit
</h2>
</div>
</div>
<div class="row">
<div class="item">
<p class="item-image">
<img src="https://parosrentcar.com/wp-content/uploads/2018/05/kawasaki-250-600-200.jpg" alt="Image">
</p>
<h2 class="item-heading">
Nunc dapibus tortor vel mi dapibus sollicitudin
</h2>
</div>
<div class="item">
<p class="item-image">
<img src="https://parosrentcar.com/wp-content/uploads/2018/05/kawasaki-250-600-200.jpg" alt="Image">
</p>
<h2 class="item-heading">
Mauris elementum mauris vitae tortor
</h2>
</div>
<div class="item">
<p class="item-image">
<img src="https://parosrentcar.com/wp-content/uploads/2018/05/kawasaki-250-600-200.jpg" alt="Image">
</p>
<h2 class="item-heading">
Aliquam ornare wisi eu metus
</h2>
</div>
</div>
codepen : Link
i hope this help you

Responsive row of same-height elements breaks to two rows in small breakpoint

I have 6 cells of data, in medium+ breakpoints, they are all in the same row and the same height; in the small breakpoint, there are 3 per row, and everything within the row is the same height.
I had initially tried to use display: table-cell;, and was able to achieve both scenarios separately, but the markup needed to change. Is there a way to make this approach work?
I know flexbox could be an option, but I cannot use it, as I need to support IE9.
Would like to solve this without the use of any JS.
tl;dr
3 cells in a row for small viewports
6 cells in a row for medium viewports
All cells in a row should be the same height
Dynamic height, based on content length
No JS - CSS/Markup only.
Support for IE9+.
Works in small breakpoint (3 per row):
.table {
display: table;
width: 100%;
}
.row {
display: table-row;
}
.cell {
display: table-cell;
vertical-align: middle;
width: 16.66667%; /* 1/6 */
border: 1px solid #000;
text-align: center;
}
#media (max-width: 500px) {
.cell {
width: 33.33333%; /* 1/3 */
background: #eee; /* Just to see when the breakpoint is applied */
}
}
<div class="table">
<div class="row">
<div class="cell">Cell 1 Pellentesque pretium neque at lacinia faucibus.</div>
<div class="cell">Cell 2</div>
<div class="cell">Cell 3</div>
</div>
<div class="row">
<div class="cell">Cell 4</div>
<div class="cell">Cell 5</div>
<div class="cell">Cell 6 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut eu ornare mi. Ut convallis suscipit sapien, at feugiat tellus commodo nec.</div>
</div>
</div>
Works in medium+ breakpoints (6 per row):
.table {
display: table;
width: 100%;
}
.row {
display: table-row;
}
.cell {
display: table-cell;
vertical-align: middle;
width: 16.66667%; /* 1/6 */
border: 1px solid #000;
text-align: center;
}
#media (max-width: 500px) {
.cell {
width: 33.33333%; /* 1/3 */
background: #eee; /* Just to see when the breakpoint is applied */
}
}
<div class="table">
<div class="row">
<div class="cell">Cell 1 Pellentesque pretium neque at lacinia faucibus.</div>
<div class="cell">Cell 2</div>
<div class="cell">Cell 3</div>
<div class="cell">Cell 4</div>
<div class="cell">Cell 5</div>
<div class="cell">Cell 6 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut eu ornare mi. Ut convallis suscipit sapien, at feugiat tellus commodo nec.</div>
</div>
</div>
Since its a tabular data I would suggest to go with Table...
.table {
width: 100%;
border-collapse: collapse;
}
.cell {
width: 16.66667%;
border: 1px solid #00F;
text-align: center;
}
#media (max-width: 500px) {
.cell {
width: 33.33333%; /* 1/3 */
background: yellow; /* Just to see when the breakpoint is applied */
}
}
<table class="table" >
<tr class="row">
<td class="cell">Cell 1 Pellentesque pretium neque</td>
<td class="cell">Cell 2</td>
<td class="cell">Cell 3</td>
</tr>
<tr class="row">
<td class="cell">Cell 4</td>
<td class="cell">Cell 5</td>
<td class="cell">Cell 6 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut eu ornare mi. Ut convallis suscipit sapien, at feugiat tellus commodo nec.</td>
</tr>
</table>
jsFiddle
If I understood correctly this is what you want to achieve... here I am using bootstrap listGrid concept to achieve this.
.cell {
border: 1px solid #000;
text-align: center;
height: 200px;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
<div class="table">
<div class="cell col-xs-4 col-sm-2">Cell 1 Pellentesque pretium neque at lacinia faucibus.</div>
<div class="cell col-xs-4 col-sm-2">Cell 2</div>
<div class="cell col-xs-4 col-sm-2">Cell 3</div>
<div class="cell col-xs-4 col-sm-2">Cell 4</div>
<div class="cell col-xs-4 col-sm-2">Cell 5</div>
<div class="cell col-xs-4 col-sm-2">Cell 6 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut eu ornare mi. Ut convallis suscipit sapien, at feugiat tellus commodo nec.</div>
</div>
Note1: If in case you do not want to use bootstrap let me know, I can find some other solution.
Note2: Bootstrap has pre-define values in pexels for devices, and if you want to change as per your need you can at http://getbootstrap.com/customize/

Baseline of vertically stacked elements

I have a container of vertically stacked elements.
<div>
<div>line 1</div>
<div>line 2</div>
<div>line 3</div>
<div>line 4</div>
</div>
I want the baseline of the container to be identical to the baseline of a specific one of its elements, let's say the third one. It should look like this:
How can I do this with CSS?
As a related question, how is the baseline of such container of vertically stacked elements usually defined?
I want to give this container a property display: inline-block. This container appears next to other elements on a line, and I want them to be aligned according to the baseline.
This makes the baseline of the container coincide with the baseline of the third child div.
.container > div:nth-of-type(3) ~ div {
float: left;
clear: both;
}
Examples:
.container {
display: inline-block;
background: yellow;
padding: 0 0.5em;
width: 8em;
}
.b1 > div:nth-of-type(1) ~ div {
float: left;
clear: both;
}
.b2 > div:nth-of-type(2) ~ div {
float: left;
clear: both;
}
.b3 > div:nth-of-type(3) ~ div {
float: left;
clear: both;
}
.b4 > div:nth-of-type(4) ~ div {
float: left;
clear: both;
}
.container > div:nth-of-type(1) {
font-size: 14px;
}
.container > div:nth-of-type(2) {
font-size: 16px;
}
.container > div:nth-of-type(3) {
font-size: 24px;
}
.container > div:nth-of-type(4) {
font-size: 20px;
}
<div class="container b1">
<div>baseline</div>
<div>line 2</div>
<div>line 3</div>
<div>line 4</div>
</div>
<div class="container">
Lorem ipsum dolor sit amet
</div>
<div class="container">
consectetur adipiscing elit, sed do eiusmod tempor incididunt
</div>
<hr>
<div class="container b2">
<div>line 1</div>
<div>baseline</div>
<div>line 3</div>
<div>line 4</div>
</div>
<div class="container">
Lorem ipsum dolor sit amet
</div>
<div class="container">
consectetur adipiscing elit, sed do eiusmod tempor incididunt
</div>
<hr>
<div class="container b3">
<div>line 1</div>
<div>line 2</div>
<div>baseline</div>
<div>line 4</div>
</div>
<div class="container">
Lorem ipsum dolor sit amet
</div>
<div class="container">
consectetur adipiscing elit, sed do eiusmod tempor incididunt
</div>
<hr>
<div class="container b4">
<div>line 1</div>
<div>line 2</div>
<div>line 3</div>
<div>baseline</div>
</div>
<div class="container">
Lorem ipsum dolor sit amet
</div>
<div class="container">
consectetur adipiscing elit, sed do eiusmod tempor incididunt
</div>
If I understand your question correctly, something like this could work:
body {
line-height: 18px; /* set a line height and use it to calculate the offsets later */
}
div {
position: relative;
display: inline-block;
vertical-align: baseline;
background: black;
color: white;
}
div > div {
display: block;
}
div.align-1 > div:nth-child(2) {
position: absolute;
bottom: -18px; /* 1 x line-height of parent */
}
div.align-1 > div:nth-child(3) {
position: absolute;
bottom: -36px; /* 2 x line-height of parent */
}
div.align-1 > div:nth-child(4) {
position: absolute;
bottom: -54px; /* 3 x line-height of parent */
}
div.align-2 > div:nth-child(3) {
position: absolute;
bottom: -18px; /* 1 x line-height of parent */
}
div.align-2 > div:nth-child(4) {
position: absolute;
bottom: -36px; /* 2 x line-height of parent */
}
div.align-3 > div:nth-child(4) {
position: absolute;
bottom: -18px; /* 1 x line-height of parent */
}
Text
<div class="align-1">
<div>line 1</div>
<div>line 2</div>
<div>line 3</div>
<div>line 4</div>
</div>
more text
<br>
<br>
<br>
<br>
<hr />
<br> Text
<div class="align-2">
<div>line 1</div>
<div>line 2</div>
<div>line 3</div>
<div>line 4</div>
</div>
more text
<br>
<br>
<br>
<hr />
<br> Text
<div class="align-3">
<div>line 1</div>
<div>line 2</div>
<div>line 3</div>
<div>line 4</div>
</div>
more text
<br>
<br>
<hr />
<br> Text
<div class="align-4">
<div>line 1</div>
<div>line 2</div>
<div>line 3</div>
<div>line 4</div>
</div>
more text
<br>
<hr />
If you are using sass or less you could make it in a dynamic mixin that would work on variable element count.

Align two vertically-stacked rows of flex items next to one full-height flex item

I`m using flexbox and trying to make 6 things like this:
So far this is my code:
<section class="focus-item">
<div class="item focus-item-1">
<h4>Brand </h4>
<p>Identity
aliquam ipsum ante morbi sed ipsum mollis.
Sollicitudin viverra, vel varius eget sit mollis.
</p>
<img src="D:/htmlCss/landing/assets/img/focus-item-1.png" alt="" />
</div>
</section>
CSS
.focus-item {
display: flex;
flex-wrap: wrap;
}
.focus-item .item {
display: flex;
width: 50%;
text-align: left;
}
.focus-item .item p {
display: flex;
flex: 1;
align-items: flex-end;
}
.focus-item .item h4 {
display: flex;
align-items: flex-start;
}
I have problem with placing h4 on top of p. I would be great if someone can point me in the right direction.
As I already posted it in my first comment, you can do it by making the first flex item a flex box as well:
<div class="container">
<div class="item-1">
<h4>Header</h4>
<p>Lorem Ipsum is simply dummy text of the printing and typesetting industry.</p>
</div>
<img src="https://cdn.tutsplus.com/net/uploads/legacy/958_placeholders/placehold.gif" />
</div>
.container {
display: flex;
align-items: flex-end;
}
.item-1 {
display: flex;
flex-direction: column;
align-items: flex-end;
}
See here for the working example: http://jsfiddle.net/0j7abre9/1/
The key to this layout is to create one flex container that holds two flex items – the first holding the <h4> and <p>, and the other holding the <img> – and align them in a row. Then convert the first flex item to a flex container as well, and align its two items in a column.
HTML
<section class="focus-item">
<div class="item focus-item-1"><!-- nested flex container 1 -->
<h4>Brand</h4>
<p>Identity aliquam ipsum ante morbi sed ipsum mollis.
Sollicitudin viverra, vel varius eget sit mollis.</p>
</div>
<div class="item focus-item-2"><!-- nested flex container 2 -->
<img src="http://i.imgur.com/60PVLis.png" height="200" width="200" alt="">
</div>
</section>
CSS
.focus-item {
display: flex;
}
.item {
display: flex;
flex: 1 1 50%;
}
.focus-item-1 {
flex-direction: column;
align-items: flex-end;
}
DEMO

How to align vertically an element to the bottom within a bootstrap column?

I'm using twitter-bootstrap framework, and bootstrap touchspin plugin. And I want to align the touchspin at the bottom of an column .col-md-6 which has variable height.
I tried adding the following (like this solution):
.row {
position: relative;
}
.bootstrap-touchspin {
position: absolute;
bottom:0;
right:0;
}
But nothing changes. (see jsfiddle)
Why does it not work? Do you have another way to do it?
Here is a jsfiddle where you can try: http://jsfiddle.net/R5n9j/1/
ACTUAL OUTPUT
DESIRED OUTPUT
HTML
<div class="container">
<div class="row">
<div class="col-md-7">
<div id="form-guardar-medidas">
<ul class="nav nav-tabs">
<li class="active">Tab1
</li>
<li>Tab2
</li>
</ul>
<div id='content' class="tab-content">
<div class="tab-pane active fade in" id="tab1">
<div class="row">
<div class="col-md-6">
<img class="img-responsive" src="http://placehold.it/200x200">
</div>
<div class="col-md-6">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam blandit mattis pretium. Interdum et malesuada fames ac ante ipsum primis in faucibus.</p>
<input id="input-cm" type="text" class="input-lg" name="input-cm">
</div>
</div>
</div>
<div class="tab-pane fade" id="tab2">Hello tab2</div>
</div>
</div>
</div>
</div>
</div>
CSS
body{
padding: 20px;
}
.tab-content {
border: 1px solid #ccc;
padding: 15px;
}
JS
$(document).ready(function () {
$("input[name='input-cm']").TouchSpin();
$('.nav-tabs a').click(function (e) {
e.preventDefault();
$(this).tab('show');
});
});
By switching to CSS table layout, you can have columns of same height for free, with the constraint of not being able to relatively position "(visual) cells" (in Firefox, at least) so you must do that on the '(visual) table"
EDIT2: .bootstrap-touchspin is also displayed as table and that fails in Chrome. Adding a div around this component that'll be absolutely positioned (and not the component itself anymore) solves this problem.
Demo: http://jsfiddle.net/R5n9j/9/
Compatibility is IE8+ (because of / thanks to display: table and table-cell)
HTML
<div class="table pos-reference">
<div class="cell">
<img class="img-responsive" src="http://placehold.it/200x200">
</div>
<div class="cell has-touchspin">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam blandit mattis pretium. Interdum et malesuada fames ac ante ipsum primis in faucibus.</p>
<div class="pos-abs">
<input id="input-cm" type="text" class="input-lg" name="input-cm">
</div>
</div>
</div>
CSS
.table {
display: table;
table-layout: fixed;
}
.pos-reference {
position: relative;
}
.cell {
display: table-cell;
vertical-align: top;
}
.has-touchspin {
height: 100%;
padding-bottom: 50px; /* Avoids superposition of content and absolutely positioned touchspin */
}
.pos-abs {
position: absolute;
bottom: 0;
border: 1px solid #F00;
}
EDIT: Explanation about why your attempt at positioning the .input-group failed: TWBS .col-AZ-NN are already relatively positioned so the closest ancestor to .input-group being positioned isn't the one you set but .col-md-6. See Firebug screenshot below. Otherwise, your attempt was a good one ;)
The easiest way is to use flex:
.tab-pane .row{
display:flex;
}
If you notice the height of the two col-md-6 containers inside the tabs, they are not equal, flex when used applies equal height to its child containers.
DEMO
Limitation:
The Safari browser does not support the flex property.
My solution is:
I've added col1 and col2 ids to each columns, and with js I set the same height.
col1h = $("#col1").height();
col2h = $("#col2").height();
if (col1h > col2h) {
def_height = col1h;
} else {
def_height = col2h;
}
$("#col1,#col2").height(def_height);
And adding left: 15px; to .bootstrap-touchspin.
The result http://jsfiddle.net/R5n9j/16/embedded/result