How to equalise sibling div heights? - css

<div class="wrapper">
<div class="sidebar-wrapper"></div>
<div class="content-wrapper"></div>
</div>
The height of content-wrapper is dynamic (auto). Is there any way to get the height of it and use it for the sidebar-wrapper so that it looks nice?

Displaying them like table cells would do it. Table cells can adjust their height automatically to the content, and all cells on the same row get the same height. If you give the side bar a fixed width (which is likely), you can easily get the content wrapper to fill the remaining space.
Whichever has the longest content will determine the height.
.wrapper {
width: 100%;
display: table;
}
.sidebar-wrapper,
.content-wrapper {
display: table-cell
}
.sidebar-wrapper {
width: 200px;
background-color: silver;
}
.content-wrapper {
background-color: yellow;
}
<div class="wrapper">
<div class="sidebar-wrapper">Here is <br>content<br>that is .....<br><br><br><br><br><br>Quite long</div>
<div class="content-wrapper">Smaller content</div>
</div>

Flexbox is an alternative to #GolezTrol's CSS tables.
.wrapper {
display: flex;
}
.sidebar-wrapper {
width: 200px;
background-color: silver;
}
.content-wrapper {
background-color: yellow;
flex: 1;
}
<div class="wrapper">
<div class="sidebar-wrapper">Here is
<br>content
<br>that is .....
<br>
<br>
<br>
<br>
<br>
<br>Quite long</div>
<div class="content-wrapper">Smaller content</div>
</div>

Related

how to make columns the same width with css flex

hello I need to basicaly display a table but with flex (only because I need to adjust the look for mobile)
.container {
display: flex
}
<div class="container">
<div class="row">
<div>1000</div>
<div>mary</div>
</div>
<div class="row">
<div>1</div>
<div>john</div>
</div>
<div class="row">
<div>11</div>
<div>mike</div>
</div>
</div>
how can I make each column have the same width? or at least the width of the largest item.
If you apply flex-grow: 1 to each div in the .row then it will expand accordingly. Note that the .row divs need the display flex (flex only apply to the DIRECT children of the flexed element.
The width can be set by using flex-basis and calc() and dividing the full-width by the number of columns you want (2 in this case). I added a border to demonstrate.
I would be remiss if I didn't suggest that the best tool to display a table structure - is a ... table... then you can work out how to modifiy for responsive layout - but the semantic structure of a table is correct for tabulr content.
.container {
width: 100%;
}
.row {
display: flex;
width: 100%;
}
.row div {
flex-grow: 1;
flex-basis: calc(100% / 2);
padding: 4px 8px;
border: solid 1px red;
}
<div class="container">
<div class="row">
<div>1000</div>
<div>mary</div>
</div>
<div class="row">
<div>1</div>
<div>john</div>
</div>
<div class="row">
<div>11</div>
<div>mike</div>
</div>
</div>
Use flex-basis to set the 'default' width first.
Use flex-grow and/or flex-shrink to allow it to grow /shrink
Use max-width' and min-width` to define by how much it can grow/shrink
.container{ #Stack the div inside the conainer
display:flex;
flex-flow: columns nowrap;
}
.row{ # Set div as cell in the row.
display:flex;
flex-flow: row nowrap;
flex-basis: 33%; # Calculate width from there.
flex-grow:1; #Allow resizing bigger
flex-shrink:1; #Allow resize smaller.
max-width:50%; #Adjust to your liking
min-width:25%; #Adjust o your liking
}
Please consider this ressource https://css-tricks.com/snippets/css/a-guide-to-flexbox/
You can add a flex-basis to the .row items by doing this:
.row {
flex-basis:calc(100% / 3);
}
.container {
width: 100%;
}
.row {
display: flex;
width: 100%;
}
.row div {
flex-grow: 1;
flex-basis: calc(100% / 2);
padding:10px;
margin: 5px;
background: #eee;
}
<div class="container">
<div class="row">
<div>1000</div>
<div>mary</div>
</div>
<div class="row">
<div>1</div>
<div>john</div>
</div>
<div class="row">
<div>11</div>
<div>mike</div>
</div>
</div>

CSS Grid - How to implement grid items, which don't "stretch" the grid row and have a scroll-able container

My challenge is:
I want to have a grid with a fixed amount of columns (which can later be adjusted via javascript) and a flexible amount of rows of equal height.
The number of rows are determined by the amount of grid items, which are UI cards.
These cards should fill out the entire height of their respective cell but MUST not increase the height of the row. So basically max-height = row-height assigned by grid
Then inside these cards we have the typical three parts: Header, Body and Footer. The body MUST be scroll-able, if more list items exists than the row-height allows.
I've tried to implement this on stackblitz
https://stackblitz.com/edit/angular-3gkmtm
What i don't understand is
Why the cards "stretches" the row when more items appear
How to achieve the scroll-able card body section without manually using a fixed height (like in the example i use max-height)
Why when there are more then 3 rows, it overflows
Please help!
<article>
<section>
<h2>Fixed Gird with scrollable cards</h2>
</section>
<section>
<button (click)="onAdd()">Add</button>
<button (click)="onRemove()">Remove</button>
</section>
<section class="remaining-height">
<div class="grid-container">
<div class="grid-item" *ngFor="let card of cards">
<div class="card">
<div class="card-header">Card #{{card}}</div>
<div class="card-body card-flexible-scroll">
<div class="list-item" *ngFor="let item of list">{{item}}</div>
</div>
<div class="card-footer">
Some Footer
</div>
</div>
</div>
</div>
</section>
</article>
article{
display: flex;
flex-direction: column;
height: 100%;
}
.remaining-height{
flex:1
}
.grid-container {
display: grid;
grid-gap: 0.5rem;
height: 100%;
grid-auto-rows: auto;
grid-template-columns: repeat(5, auto);
}
.grid-item{
display: flex;
padding:24px;
}
.card{
display: flex;
flex-direction: column;
width: 100%;
height:100%;
background:#ccc;
}
.card-body{
.list-item{
padding: 6px;
background:#fcd3d3;
}
.list-item:nth-child(even){
background:#efefef;
}
}
.card-flexible-scroll{
flex:1;
overflow-y:auto;
max-height: 300px; // <= no max height
}
Angular Controller to generate cards and list items
```js
export class AppComponent {
name = "Angular";
cards = new Array(8).fill(0).map((_,idx)=>idx+1);
list = new Array(30).fill(0).map((_,idx)=>idx+1);
onAdd() {
this.cards.push(this.cards.length + 1);
}
onRemove() {
this.cards.pop();
}
}
global style
html , body{
height: 100vh;
overflow: hidden;
}
If I understand correctly what you are trying to do you want that the card body takes all the available row space between the header and footer and not force the card to be bigger than the row if it contains items.
It is possible to achieve that with adding another div with absolute positioning inside the card body div that is sized to the full body height then the items inside will overflow correctly.
Here is the changed template:
<article>
<section>
<h2>Fixed Gird with scrollable cards</h2>
</section>
<section>
<button (click)="onAdd()">Add</button>
<button (click)="onRemove()">Remove</button>
</section>
<section class="remaining-height">
<div class="grid-container">
<div class="grid-item" *ngFor="let card of cards">
<div class="card">
<div class="card-header">Card #{{card}}</div>
<div class="card-body">
<div class="card-flexible-scroll">
<div class="list-item" *ngFor="let item of list">{{item}}</div>
</div>
</div>
<div class="card-footer">
Some Footer
</div>
</div>
</div>
</div>
</section>
</article>
And the updated CSS:
.card-body{
.list-item{
padding: 6px;
background:#fcd3d3;
}
.list-item:nth-child(even){
background:#efefef;
}
position: relative;
flex:1;
}
.card-flexible-scroll{
position: absolute;
width: 100%;
height: 100%;
max-height: 100%;
overflow-y: auto;
}
I created a fork of your StackBlitz where you can see how it works. If this is not what you look for please explain more.

Using calc() with a dynamic value?

I am wondering if this is possible: I have a header that can contain a variable amount of text. Below that I have another element which I want to take up the remaining height of the page.
<div class="header row">
<div class="title column large-5">Potentially very long text</div>
<div class="menu column large-7">Menu items</div>
</div>
<div class="content">
</div>
<div class="footer">
</div>
Normally I would do this using calc, eg:
.content {
height: calc(100vh - 75px);
}
Where 75px is the set height of .header.
But in this example, the .header element is dynamic and does not have a set height. Only a padding and font-size are set.
To complicate things, this also uses the Foundation Grid layout, which makes me nervous about using display: table (.title and .menu sit side by side on desktop, but stacked on mobile) .
Is there anyway to get the height of the dynamic header element (without resorting to JQuery)?
You can use flexbox and set .content to flex-grow: 1 so that it will fill to grow the available space.
body {
display: flex;
flex-direction: column;
min-height: 100vh;
margin: 0;
}
.content {
flex-grow: 1;
background: #eee;
}
<div class="header row">
<div class="title column large-5">Potentially very long text</div>
<div class="menu column large-7">Menu items</div>
</div>
<div class="content">
</div>
<div class="footer">
</div>
I made a small pen to show the way to do this using flex box, it involved changing your markup a bit:
css:
.container {
display: flex;
flex-direction: column;
height: 250px; // whatever you want here
}
.header {
width: 100%;
background: red;
padding: 10px;
}
.content {
background: yellow;
width: 100%;
flex-grow: 1;
}
So the content will always take the available space inside the content div.
check the whole pen: http://codepen.io/anshul119/pen/yMYeLa
hope this helps.

Have div take up 1/6th of remaining parent div height

I am attempting to make a simple calendar using css.
I have a parent div that will contain the calendar, and I have a div within that that contains the header with "Monday", "Tuesday", etc and is of fixed height. I now want to add divs that represent the rows of the calendar and split the remaining space into six even rows. However, I can't figure out how to divide the REMAINING space into 6 parts. Everything I try makes the div 1/6th of the parent div.
Any tips would be appreciated.
HTML:
<div id="parent>
<div id="header">
ST
</div>
<div class="row">
hi
</div>
</div>
CSS:
.row{
width:100%;
height: 16.66%;
background-color:red;
}
When you want to distribute remaining space left by a flexible element, flexbox is the answer.
html, body, #parent {
margin: 0;
height: 100%;
}
#parent {
display: flex;
flex-direction: column;
}
#header {
background-color: green;
}
.row {
width: 100%;
flex: 1; /* Distribute remaining space equally among the rows */
background-color: red;
}
.row:nth-child(odd) {
background-color: blue;
}
<div id="parent">
<div id="header">Header</div>
<div class="row"></div>
<div class="row"></div>
<div class="row"></div>
<div class="row"></div>
<div class="row"></div>
<div class="row"></div>
</div>
There are several ways to do that, and to pick one I need to know more how it should be used.
This sample simply use CSS calc() and subtract 1/6 of the header from 1/6 of the parent.
html, body {
margin: 0;
}
#parent {
height: 100vh;
}
#header {
height: 60px;
background-color:green;
}
.row{
height: calc(16.66% - 10px);
background-color:red;
}
.row:nth-child(odd){
background-color:blue;
}
<div id="parent">
<div id="header">
Header
</div>
<div class="row">
</div>
<div class="row">
</div>
<div class="row">
</div>
<div class="row">
</div>
<div class="row">
</div>
<div class="row">
</div>
</div>

CSS fill remaining width

I have this header bar.
<div id="header">
<div class="container">
<img src="img/logo.png"/>
<div id="searchBar">
<input type="text" />
</div>
<div class="buttonsHolder">
<div class="button orange inline" id="myAccount">
My Account
</div>
<div class="button red inline" id="basket">
Basket (2)
</div>
</div>
</div>
</div>
I need the searchBar to fill whatever the remaining gap is in the div. How would I do this?
Here's my CSS
#header {
background-color: #323C3E;
width:100%;
}
.button {
padding:22px;
}
.orange {
background-color: #FF5A0B;
}
.red {
background-color: #FF0000;
}
.inline {
display:inline;
}
#searchBar {
background-color: #FFF2BC;
}
Use calc!
https://jsbin.com/wehixalome/edit?html,css,output
HTML:
<div class="left">
100 px wide!
</div><!-- Notice there isn't a space between the divs! *see edit for alternative* --><div class="right">
Fills width!
</div>
CSS:
.left {
display: inline-block;
width: 100px;
background: red;
color: white;
}
.right {
display: inline-block;
width: calc(100% - 100px);
background: blue;
color: white;
}
Update: As an alternative to not having a space between the divs you can set font-size: 0 on the outer element.
You can realize this layout using CSS table-cells.
Modify your HTML slightly as follows:
<div id="header">
<div class="container">
<div class="logoBar">
<img src="http://placehold.it/50x40" />
</div>
<div id="searchBar">
<input type="text" />
</div>
<div class="button orange" id="myAccount">My Account</div>
<div class="button red" id="basket">Basket (2)</div>
</div>
</div>
Just remove the wrapper element around the two .button elements.
Apply the following CSS:
#header {
background-color: #323C3E;
width:100%;
}
.container {
display: table;
width: 100%;
}
.logoBar, #searchBar, .button {
display: table-cell;
vertical-align: middle;
width: auto;
}
.logoBar img {
display: block;
}
#searchBar {
background-color: #FFF2BC;
width: 90%;
padding: 0 50px 0 10px;
}
#searchBar input {
width: 100%;
}
.button {
white-space: nowrap;
padding:22px;
}
Apply display: table to .container and give it 100% width.
For .logoBar, #searchBar, .button, apply display: table-cell.
For the #searchBar, set the width to 90%, which force all the other elements to compute a shrink-to-fit width and the search bar will expand to fill in the rest of the space.
Use text-align and vertical-align in the table cells as needed.
See demo at: http://jsfiddle.net/audetwebdesign/zWXQt/
I know its quite late to answer this, but I guess it will help anyone ahead.
Well using CSS3 FlexBox. It can be acheived.
Make you header as display:flex and divide its entire width into 3 parts. In the first part I have placed the logo, the searchbar in second part and buttons container in last part.
apply justify-content: space-between to the header container and flex-grow:1 to the searchbar.
That's it. The sample code is below.
#header {
background-color: #323C3E;
justify-content: space-between;
display: flex;
}
#searchBar, img{
align-self: center;
}
#searchBar{
flex-grow:1;
background-color: orange;
padding: 10px;
}
#searchBar input {
width: 100%;
}
.button {
padding: 22px;
}
.buttonsHolder{
display:flex;
}
<div id="header" class="d-flex justify-content-between">
<img src="img/logo.png" />
<div id="searchBar">
<input type="text" />
</div>
<div class="buttonsHolder">
<div class="button orange inline" id="myAccount">
My Account
</div>
<div class="button red inline" id="basket">
Basket (2)
</div>
</div>
</div>
This can be achieved by wrapping the image and search bar in their own container and floating the image to the left with a specific width.
This takes the image out of the "flow" which means that any items rendered in normal flow will not adjust their positioning to take account of this.
To make the "in flow" searchBar appear correctly positioned to the right of the image you give it a left padding equal to the width of the image plus a gutter.
The effect is to make the image a fixed width while the rest of the container block is fluidly filled up by the search bar.
<div class="container">
<img src="img/logo.png"/>
<div id="searchBar">
<input type="text" />
</div>
</div>
and the css
.container {
width: 100%;
}
.container img {
width: 50px;
float: left;
}
.searchBar {
padding-left: 60px;
}
in css:
width: -webkit-fill-available
I would probably do something along the lines of
<div id='search-logo-bar'><input type='text'/></div>
with css
div#search-logo-bar {
padding-left:10%;
background:#333 url(logo.png) no-repeat left center;
background-size:10%;
}
input[type='text'] {
display:block;
width:100%;
}
DEMO
http://jsfiddle.net/5MHnt/
Include your image in the searchBar div, it will do the task for you
<div id="searchBar">
<img src="img/logo.png" />
<input type="text" />
</div>
I did a quick experiment after looking at a number of potential solutions all over the place. This is what I ended up with:
http://jsbin.com/hapelawake

Resources