This is really difficult to express in words so I made this quick diagram:
The outer parent is flex with align-items:stretch so that col 1 and col 2 are both the same height. In my case it's because I have some border or background image that will just look better extending the same length. However... as you can see I want to apply the same rules to the columns inside those two columns. In my case I have an announcements widget in one and a news feed in the other. So I can't really combine the two to just make a single combined feed. They pull from different sources and operate independently with differing time stamps and rules SO... they really need to be separate components but because they are nested separately they do not both "fill" the outer columns equally. When the announcements in col 1 are too small, I get dead/neg space with no border or background texture or whatever extending all the way down.
The way I have resolved this in the past is to use JS to watch for which columns are longer and match height as needed. But this seems REALLY anti-flexbox. It feels like one major reason flexbox exists is to allow more layout functionality without needing JS and although it's a minor thing from a functionality standpoint where I could leave it and just say it is what it is... I am left wondering if there is some hidden magic in flexbox that would allow me to say if the parent>parent is stretching, than at least match that.
Is this what you are looking for?
HTML:
<div class="outerContainer">
<div class="innerContainer">
<div class="col">
<h2>Column 1</h2>
<p>some stuff</p>
<p>some stuff</p>
<p>some stuff</p>
<p>some stuff</p>
<p>some stuff</p>
</div>
<div class="col">
<h2>Column 2</h2>
<p>some stuff</p>
<p>some stuff</p>
<p>some stuff</p>
<p>some stuff</p>
<p>some stuff</p>
</div>
</div>
<div class="innerContainer">
<div class="col">
<h2>Column 3</h2>
<p>some stuff</p>
<p>some stuff</p>
</div>
<div class="col">
<h2>Column 4</h2>
<p>some stuff</p>
<p>some stuff</p>
</div>
</div>
</div>
CSS:
.outerContainer {
display: flex;
justify-content: flex-start;
align-items: stretch;
}
.innerContainer {
display: flex;
align-items: stretch;
border: 1px solid red;
}
.col {
padding: 16px;
background-color: pink;
border: 1px solid black;
}
https://codepen.io/McHat/pen/QzZExp
Related
This question already has answers here:
Floated elements of variable height push siblings down
(3 answers)
What is a clearfix?
(10 answers)
Closed 2 years ago.
I defines a column div with width 25%, and the 5th element floats to right in the second row because 2nd element has a bigger height. I can solve the problem by defining a fixed height, so the 2nd row will starts from 1st column in the left. But I wonder if there is a better solution with CSS itself. My goal is to create a photo gallery to display all photos in a folder with filename as description so the height could be different, and I don't want to define another "row" div and specify files for each row.
<style>
.column {
float: left;
width: 25%;
}
</style>
<div class="column" style="background-color:#aaa;">
<h2>Column 1</h2>
<p>Some text..</p>
</div>
<div class="column" style="background-color:#ccc;">
<h2>Column 2</h2>
<p>Some long text..........................................................................................</p>
</div>
<div class="column" style="background-color:#ddd;">
<h2>Column 3</h2>
<p>Some text..</p>
</div>
<div class="column" style="background-color:#eee;">
<h2>Column 4</h2>
<p>Some text..</p>
</div>
<div class="column" style="background-color:#eee;">
<h2>Column 5</h2>
<p>Some text..</p>
</div>
codepen
Flexbox was made for this use case. We put everything in a flexbox container and enable flex-wrap so that items wrap around. The items in the flex container will size and position themselves accordingly. Since you've specified a 25% width, when there's more than 4 items the flex will wrap and put the next item on a next line.
<style>
.container {
display: flex;
flex-wrap: wrap;
}
.column {
width: 25%
}
</style>
<div class="container">
<div class="column" style="background-color:#aaa;">
<h2>Column 1</h2>
<p>Some text..</p>
</div>
<div class="column" style="background-color:#ccc;">
<h2>Column 2</h2>
<p>Some long text..........................................................................................</p>
</div>
<div class="column" style="background-color:#ddd;">
<h2>Column 3</h2>
<p>Some text..</p>
</div>
<div class="column" style="background-color:#eee;">
<h2>Column 4</h2>
<p>Some text..</p>
</div>
<div class="column" style="background-color:#eee;">
<h2>Column 5</h2>
<p>Some text..</p>
</div>
</div>
I have a fixed table-layout div parent with two horizontal table-cell children.
On the left cell, I just simply put in some text. However, when the right cell has a tall image, the text on the left cell is pined to the bottom no matter what html padding & margin styles I put in. When the right cell has some multi-line text, the text on the left cell is placed on top.
I want the text from the left cell to stay on top all the time. Where am I missing?
html
<div class="row-post">
<div class="col-cell col-fixed" style="margin-top: 0px;padding-top: 0px;">
<p>1</p>
</div>
<div class="col-cell pl-3">
<img src="https://i.kym-cdn.com/photos/images/facebook/001/295/524/cda.jpg" style="height:300px">
</div>
</div>
<hr>
<div class="row-post">
<div class="col-cell col-fixed">
<p>1</p>
</div>
<div class="col-cell pl-3">
<p>Some long text</p>
<p>Some long text</p>
<p>Some long text</p>
<p>Some long text</p>
<p>Some long text</p>
<p>Some long text</p>
<p>Some long text</p>
<p>Some long text</p>
<p>Some long text</p>
<p>Some long text</p>
<p>Some long text</p>
</div>
</div>
css
.row-post {
table-layout: fixed;
width: 100%;
word-break: break-all;
}
.row-post .col-cell {
display:table-cell;
}
.row-post .col-cell img {
max-width: 100%;
}
.col-fixed {
width: 26px;
}
js fiddle if you want to play around
https://jsfiddle.net/f1zr6o93/
js fiddle snip
For table render types, you can use:
vertical-align: top;
on any "table cell".
Edited fiddle
For reference, there's a fuller explanation of when vertical align applies in this other SO article.
I have absolutely positioned div.container. div.wrapper inside it. and two divs as flex columns in div.wrapper. These columns have backgrounds.
How can I make these backgrounds go to the end of the longest column (i.e. make them the same height) and not only to the visible height of the container? I can't remove position: absolute from div.container.
.container {
position: absolute;
top: 0;
bottom: 0;
right: 0;
left: 0;
display: flex;
flex-direction: column;
overflow: auto;
}
.wrapper {
display: flex;
align-items: stretch;
width: 100%;
}
.div1 {
background-color: yellow;
}
.div2 {
flex: 1;
background-color: green;
}
<div class="container">
<div class="wrapper">
<div class="div1">
<p>Some long content here</p>
<p>Some long content here</p>
<p>Some long content here</p>
<p>Some long content here</p>
<p>Some long content here</p>
<p>Some long content here</p>
<p>Some long content here</p>
<p>Some long content here</p>
<p>Some long content here</p>
</div>
<div class="div2">
<p>Some even longer content here</p>
<p>Some even longer content here</p>
<p>Some even longer content here</p>
<p>Some even longer content here</p>
<p>Some even longer content here</p>
<p>Some even longer content here</p>
<p>Some even longer content here</p>
<p>Some even longer content here</p>
<p>Some even longer content here</p>
<p>Some even longer content here</p>
<p>Some even longer content here</p>
<p>Some even longer content here</p>
<p>Some even longer content here</p>
<p>Some even longer content here</p>
<p>Some even longer content here</p>
<p>Some even longer content here</p>
</div>
</div>
</div>
CodePen link
Remove the flex properties on the container.
I also removed align-items: stretch; width: 100%; from the .wrapper as it is their default value's and doesn't need to be set.
.container {
position: absolute;
top: 0;
bottom: 0;
right: 0;
left: 0;
/* commented out these 2 lines
display: flex;
flex-direction: column;
*/
overflow: auto;
}
.wrapper {
min-height: 100%;
display: flex;
/* commented out these 2 lines as they are not needed
align-items: stretch;
width: 100%;
*/
}
.div1 {
background-color: yellow;
}
.div2 {
flex: 1;
background-color: green;
}
p {
padding: 20px 10px;
}
<div class="container">
<div class="wrapper">
<div class="div1">
<p>Some long content here</p>
<p>Some long content here</p>
<p>Some long content here</p>
</div>
<div class="div2">
<p>Some even longer content here</p>
<p>Some even longer content here</p>
<p>Some even longer content here</p>
<p>Some even longer content here</p>
<p>Some even longer content here</p>
<p>Some even longer content here</p>
<p>Some even longer content here</p>
<p>Some even longer content here</p>
</div>
</div>
</div>
I'm trying to target the class, .textbox-fill to change the background colour and text colour for each individual box element. For example .textbox-fill's first-child should be grey. The second-child should be white. The third child I want to adjust the height slight and so on.
I have tried using the nth-child selector #About-Container .about-inner-content article:nth-child(1n+2) .textbox-fill nothing seems to work. Example here
<article class="col-sm-6 grid-tile">
<div class="textbox-fill">
<div class="about-textbox">
<h2>Some text</h2>
<p>Some text</p>
</div>
</div>
</article>
I have encounter this issue in the past and I'm not 100% sure how I resolved it. I have read several articles and posts on this subject. I understand the basics, however something more complex like this I always approached with trial and error method.
Does anyone know how I can solve this issue?
Since your .textbox-fill is inside the article, it is the article you need to start with, as target the text-fill using nth-child will not work as it can't see outside its parent
So do like this instead
article:nth-child(1) .textbox-fill {
color: red;
}
article:nth-child(2) .textbox-fill {
color: lime;
}
article:nth-child(3) .textbox-fill {
color: blue;
}
<article class="col-sm-6 grid-tile">
<div class="textbox-fill">
<div class="about-textbox">
<h2>Some text</h2>
<p>Some text</p>
</div>
</div>
</article>
<article class="col-sm-6 grid-tile">
<div class="textbox-fill">
<div class="about-textbox">
<h2>Some text</h2>
<p>Some text</p>
</div>
</div>
</article>
<article class="col-sm-6 grid-tile">
<div class="textbox-fill">
<div class="about-textbox">
<h2>Some text</h2>
<p>Some text</p>
</div>
</div>
</article>
If we talk about the .textbox-fill's .about-textbox's children, the h2 and p, do like this, where you use the global selector * in *:nth-child, as the children is of different types
.textbox-fill .about-textbox *:nth-child(1) {
color: red;
}
.textbox-fill .about-textbox *:nth-child(2) {
color: lime;
}
<article class="col-sm-6 grid-tile">
<div class="textbox-fill">
<div class="about-textbox">
<h2>Some text</h2>
<p>Some text</p>
</div>
</div>
</article>
If you have a .textbox-fill with several children, like:
div.textbox-fill
h1#header
div#firstDiv
div#secondDiv
article#someArticle
div#thirdDiv
Now, .textbox-fill div:first-child will target nothing, because there isn't any div that is a first child of it's parent (.textbox-fill). Although .textbox-fill div:first-of-type will target div#firstDiv. .textbox-fill div:nth-child(2) will also target div#firstDiv. div#thirdDiv will be .textbox-fill div:nth-of-type(3) or .textbox-fill div:nth-child(5) or .textbox-fill div:last-child or .textbox-fill div:last-of-type.
If you want to target specific .textbox-fill located on site, but with different parents, like:
div.something
div.textbox-fill
[...]
article#other
div.textbox-fill
You cannot target it using nth-child nor nth-of-type. You will need to find another way based on your site tree.
I am trying to build an interface with Bootstrap 3 which looks like this:
--------Fieldset-------- -----Fieldset-----
Col 1 Col 2 Some data
Some data Some data Some data
Some data Some data Some data
Some data Some data Some data
------------------------Fieldset------------------------
Some large <textarea>
I am not sure how to go about accomplishing this, though. My concerns are the multiple columns in one fieldset, and the bottom fieldset spanning the length of the two fieldsets above it. I know to make stacked fieldsets all I need to do is nest them, but that then restricts the length of the children fieldsets.
Is what I'm doing even possible? Is it going to get ugly like I feel like it will?
Thanks in advance for any assistance!
I should have provided this anyway - sorry about that. Here's some markup that (should) get you rolling.
HTML
<div class="row">
<div class="col-md-6">
<div class="mycol-1">
<p>Fieldset</p>
<div class="row">
<div class="col-md-6">
<p>Col 1</p>
<p>Some data</p>
<p>Some data</p>
<p>Some data</p>
</div>
<div class="col-md-6">
<p>Col 2</p>
<p>Some data</p>
<p>Some data</p>
<p>Some data</p>
</div>
</div>
</div>
</div>
<div class="col-md-6">
<div class="mycol-2">
<p>Fieldset</p>
<p>Some data</p>
<p>Some data</p>
<p>Some data</p>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="mycol-3">
<p>Fieldset</p>
<p>Some large textarea</p>
</div>
</div>
</div>
CSS:
.mycol-1 { background-color: red; }
.mycol-2 { background-color: pink; }
.mycol-3 { background-color: orange; }
I only used the css as a way to show the boundires. You will probably want to at least rename the classes (or delete them all together). Hope this helps!