Evenly space list items vertically - html

I am trying to find a way with CSS to evenly space list items vertically.
I want each list item to have a fixed height that doesn't change. I want the margin in between each list item to automatically strecth so it has the same amount of space but margin:auto; is not working.
Here is snippet:
.container {
border: 1px solid black;
height: 500px;
width: 400px;
}
.spaced {
padding: 0;
list-style: none;
}
.spaced li {
border: 1px solid blue;
height: 60px;
margin: 15px;
}
<div class="container">
<ul class="spaced">
<li>item </li>
<li>item </li>
<li>item </li>
<li>item </li>
</ul>
</div>
So with this snippet I need it so the blue boxes will remain the same height and be spaced evenly vertically. If the black box changes in height then the blue boxes will still be evenly spaced.
How can I do this?

You can do this with Flexbox and justify-content: space-around;
Flex items are evenly distributed so that the space between two adjacent items is the same. The empty space before the first and after the last items equals half of the space between two adjacent items.
.container {
border: 1px solid black;
height: 500px;
width: 400px;
padding: 10px;
box-sizing: border-box;
}
.spaced {
height: 100%;
padding: 0;
list-style: none;
display: flex;
flex-direction: column;
justify-content: space-around;
margin: 0;
}
.spaced li {
border: 1px solid blue;
height: 60px;
}
<div class="container">
<ul class="spaced">
<li>item </li>
<li>item </li>
<li>item </li>
<li>item </li>
</ul>
</div>

Flexbox can do that:
.container {
border: 1px solid black;
height: 500px;
width: 400px;
}
.spaced {
padding: 0;
margin: 0;
height: 100%;
list-style: none;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.spaced li {
border: 1px solid blue;
height: 60px;
margin-left: 15px;
margin-right: 15px;
}
<div class="container">
<ul class="spaced">
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
</ul>
</div>

You can do this using jQuery.
Here is the updated css,
.container {
border: 1px solid black;
height: 500px;
width: 400px;
}
.spaced {
padding: 0;
list-style: none;
margin:0; //Additional
}
.spaced li {
border: 1px solid blue;
height: 60px;
margin: 15px;
width: 370px; //Additional
float:left; //Additional
}
Js code is below,
function setLiMargin(){
var parentH = $(".container").height();
var liCount = $(".container ul li").length;
var liHeight = 60;
var margin = parseInt((parentH/liCount - liHeight)/2);
$('.spaced li').css('margin',margin+'px 15px');
}
$(document).ready(function(){
setLiMargin();
});

Related

How to have same space between elements in list?

I'm trying to add the same space between li elements but I dont know how. Can someone point me in the right direction? Thanks in advance
.container {
width: 600px;
height: 500px;
margin:auto;
padding:10 ;
border: 1px solid #ccc;
}
#ul_top {
display: flex;
justify-content:space-around;
list-style-type:none;
}
li:not(:first-child) {
padding-right: 50px;
color:red;
}
.title {
padding-top: 80px;
}
.horizontal-line {
width: 490px;
margin: auto;
padding-left:10px;
border-top: 1px solid #cccccc;
position: relative;
top:-20;
}
<div class="container">
<div class="title"></div>
<div class="horizontal-line"></div>
<ul id ="ul_top">
<li>text1</li>
<li>text2</li>
<li>text3</li>
<li>text4</li>
<li>text5</li>
<li>text6</li>
</ul>
</div>
I want the same space distance between each li element and the last element (text6) to be move to the right a little bit so it lines up with the above horizontal line.
Use display: flex and justify-content: space-between/space-around.
Also, a ul has a default padding, so just override it with padding: 0.
And I removed the padding-right for the :not(:first-child)
You can adjust the width of horizontal-line and the flexbox to be the same, and when you use space between you will have the line and text align together.
.container {
width: 600px;
height: 500px;
margin: auto;
padding: 10;
border: 1px solid #ccc;
}
#ul_top {
display: flex;
justify-content: space-between;
list-style-type: none;
padding: 0;
width: 90%;
margin: 20px auto;
}
li:not(:first-child) {
color: red;
}
.title {
padding-top: 80px;
}
.horizontal-line {
width: 90%;
margin: auto;
padding-left: 10px;
border-top: 1px solid #cccccc;
position: relative;
top: -20;
}
<div class="container">
<div class="title"></div>
<div class="horizontal-line"></div>
<ul id="ul_top">
<li>text1</li>
<li>text2</li>
<li>text3</li>
<li>text4</li>
<li>text5</li>
<li>text6</li>
</ul>
</div>
Try this
.container {
width: 600px;
height: 500px;
margin: auto;
padding: 10;
border: 1px solid #ccc;
}
#ul_top {
display: flex;
justify-content: space-between;
list-style-type: none;
padding: 0;
width: 90%;
margin: 20px auto;
}
li:not(:first-child) {
color: red;
}
.title {
padding-top: 80px;
}
.horizontal-line {
width: 90%;
margin: auto;
border-top: 1px solid #cccccc;
position: relative;
top: -20;
}
<div class="container">
<div class="title"></div>
<div class="horizontal-line"></div>
<ul id="ul_top">
<li>text1</li>
<li>text2</li>
<li>text3</li>
<li>text4</li>
<li>text5</li>
<li>text6</li>
</ul>
</div>

set height to fit to the container area

I have the following setup:
.layout {
display: flex;
flex-direction: column;
height: 100vh;
}
.appbar {
background-color: blue;
color: white;
}
.sidebar {
flex-grow: 1;
overflow-y: auto;
}
.drawer-container {
height: 100%;
display: flex;
}
.drawer {
position: relative;
background-color: #272b34;
color: lightgray;
border-style: none;
align-self: stretch;
overflow-y: auto;
}
.list {
list-style: none;
padding: 1rem;
}
.drawer-content {
padding: 1rem 1rem 1rem 1rem;
margin-top: 1px;
align-self: stretch;
background-color: #eef5f9;
overflow: auto;
flex: 1 1 auto;
}
.component {
background-color: white;
height: 100%;
box-shadow: 0px 0px 3px 1px rgb(0 0 0 / 10%);
overflow: auto;
border-radius: 4px;
}
.header {
padding: 1rem 1rem 1rem;
background-color: #f8f9fa;
}
.grid-container {
margin: 1rem 1rem;
height: calc(100% - 82px);
background-color: red;
}
.grid {
background-color: yellow;
max-height: 100%;
overflow: auto;
}
.grid-content {
height: 500px;
}
<div id="layout" class="layout">
<div id="appbar" class="appbar">
APPBAR
</div>
<div id="sidebar" class="sidebar">
<div id="drawercontainer" class="drawer-container">
<div id="drawer" class="drawer">
<ul class="list">
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
<li>item 5</li>
</ul>
</div>
<div id="drawercontent" class="drawer-content">
<div id="component" class="component">
<div class="header">HEADER</div>
<div class="grid-container">
<div class="grid">
<div class="grid-content">GRID CONTENT</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
The question is about this piece of css:
.grid-container {
margin: 1rem 1rem;
height: calc(100% - 82px);
background-color: red;
}
Setting the height like this, I can avoid, that the component element has a scrollbar. It means, the grid-container and the header have a total height of the component. But if I test it with different screen size / pixel ratio, I get a scrollbar (with little scrolling). Note, that the component has to have the property overflow set.
The question is, how can I avoid to set the height this way? How can I avoid the use of pixels or any other units? Basically, I want that the grid-container fills always the remaining area from the component element on any screen sizes / resolutions, without showing any scrollbar, it means not extending it.
Hopefully this snippet does what you want:
Sane default of box-sizing: border-box on every element
Removed stupid margin on the body which caused pagewide scrollbar on 100vh height
Swapped margin on grid-container for padding
Tidied up some shorthands etc. padding: 1rem 1rem 1rem 1rem -> padding: 1rem are the same
* {
box-sizing: border-box;
}
body {
margin: 0;
}
.layout {
display: flex;
flex-direction: column;
height: 100vh;
}
.appbar {
background-color: blue;
color: white;
}
.sidebar {
flex-grow: 1;
overflow-y: auto;
}
.drawer-container {
height: 100%;
display: flex;
}
.drawer {
position: relative;
background-color: #272b34;
color: lightgray;
border-style: none;
align-self: stretch;
overflow-y: auto;
}
.list {
list-style: none;
padding: 1rem;
}
.drawer-content {
padding: 1rem;
margin-top: 1px;
align-self: stretch;
background-color: #eef5f9;
overflow: auto;
flex: 1 1 auto;
}
.component {
height: 100%;
box-shadow: 0px 0px 3px 1px rgb(0 0 0 / 10%);
overflow: auto;
border-radius: 4px;
}
.header {
padding: 1rem;
background-color: #f8f9fa;
}
.grid-container {
padding: 1rem;
height: calc(100% - 82px);
}
.grid {
background-color: yellow;
max-height: 100%;
overflow: auto;
}
.grid-content {
height: 500px;
}
<div id="layout" class="layout">
<div id="appbar" class="appbar">
APPBAR
</div>
<div id="sidebar" class="sidebar">
<div id="drawercontainer" class="drawer-container">
<div id="drawer" class="drawer">
<ul class="list">
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
<li>item 5</li>
</ul>
</div>
<div id="drawercontent" class="drawer-content">
<div id="component" class="component">
<div class="header">HEADER</div>
<div class="grid-container">
<div class="grid">
<div class="grid-content">GRID CONTENT</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

Flex-grow behaving differently on IE 11

I was experimenting with flexbox on IE and noticed that my navigation bar does not work the same on IE compared to all other browsers.
The navigation bar should appear on two lines as soon as the buttons on the right don't fit in the space right next to the logo. If it doesn't fit, it's pushed on the second line with flex-wrap: wrap. And when it's pushed to the second line it centers all buttons over the entire width of the screen.
I fixed this by using a high flex-grow number on the spacer between the logo and the navigation bar. This works well on chrome, edge, etc, but not on internet explorer 11.
The demo I use for to test this:
https://jsfiddle.net/td2rq4h1/
*{
box-sizing: border-box;
}
body{
background: red;
}
.logo{
background-color: yellow;
width: 145px;
height: 70px;
margin-right: 100px;
}
#headermenu{
background-color: gray;
.telephone {
border: 3px solid pink;
width: 145px;
height: 30px;
margin-right: 100px;
}
}
#menu{
background-color: blue;
}
.spacer {
flex-grow: 1000;
background-color: green;
display: flex;
flex-wrap: wrap;
}
.inner-spacer {
flex-grow: 1;
flex-basis: 100%;
}
.link {
flex-grow: 0;
}
nav{
border: 5px solid black;
flex: 1 1;
display: flex;
justify-content: center;
}
ul{
list-style: none;
margin: 0;
padding: 0;
text-align: center;
}
li{
border: 2px solid purple;
background-color: white;
padding: 1em;
white-space: pre;
margin: 0;
display: inline-block;
}
<div id="menu" class="d-flex flex-wrap">
<div class="logo">Logo</div>
<div class="spacer"></div>
<nav>
<ul class="d-flex flex-row">
<li>Home</li>
<li>Nav item 1</li>
<li>Nav item 2</li>
<li>Nav item 3</li>
<li>Nav item 4</li>
<li>Nav item 5</li>
</ul>
</nav>
</div>
Can anybody explain me why this happens and how i could resolve this? Thanks
you may reduce the use of flex: x properties and play with margin instead ... hudge flex value..
example forked from the broken jsfiddle:
* {
box-sizing: border-box;
}
.d-flex {
display: flex;
}
.flex-wrap {
flex-wrap: wrap;
}
body {
background: red;
}
.logo {
background-color: yellow;
width: 145px;
height: 70px;
margin-right: 100px;
}
#headermenu {
background-color: gray;
}
#headermenu .telephone {
border: 3px solid pink;
width: 145px;
height: 30px;
margin-right: 100px;
}
#menu {
background-color: blue;
}
.spacer {
flex-grow: 1;
background-color: green;
display: flex;
}
nav {
border: 5px solid black;
display: flex;
justify-content: center;
margin: 0 auto;
}
nav ul {
list-style: none;
margin: 0 auto;
padding: 0;
text-align: center;
}
nav ul li {
border: 2px solid purple;
background-color: white;
padding: 1em;
white-space: pre;
margin: 0;
display: inline-block;
}
<div id="menu" class="d-flex flex-wrap">
<div class="logo">Logo</div>
<div class="spacer"></div>
<nav>
<ul class="d-flex flex-row">
<li>Home</li>
<li>Nav item 1</li>
<li>Nav item 2</li>
<li>Nav item 3</li>
<li>Nav item 4</li>
<li>Nav item 5</li>
</ul>
</nav>
</div>
explanation : IE11 will be soon a decade old and did not update bugs on its flex implementation since. it's been edge since, and even edge will stop being updated.

Expand child height based on taller sibling (parent height set to auto)

Simple question (snippet below):
<ul> with display: flex
each <li> should have the same size and together must occupy the full width of the <ul>
each <li> has a <a> which the content may have 1 or 2 lines of text.
each <li> has height set to auto to adjust to the <a> content
My problem:
I need the "one-line" links to auto expand to the height of the "two-line" links. Setting height: 100% doesn't work because their parent height it's intentionally set to auto to adjust for content.
But in some cases I'll get two-line links, and some cases all will be one-line. So I need the one-line links to auto-expand when that happens.
How is this possible?
#root {
width: 140px;
box-sizing: border-box;
}
ul {
display: flex;
justify-content: space-between;
margin: auto;
padding: 0;
}
li {
flex-grow: 1;
flex-basis: 30px;
list-style-type: none;
display: inline-block;
border: 1px dotted blue;
height: auto;
}
a {
cursor: pointer;
border: 1px dotted green;
display: inline-block;
background-color: lightblue;
padding: 8px 0px;
}
<div id="root">
<ul>
<li><a>Link 1</a></li>
<li><a>Long Link 2</a></li>
</ul>
</div>
You don't need to use inline-block with flex. Just use display: flex for li and display: block for a. Finally, add the width: 100% for a. It seems match your requirement.
#root {
width: 140px;
box-sizing: border-box;
}
ul {
display: flex;
justify-content: space-between;
margin: auto;
padding: 0;
}
li {
flex-grow: 1;
flex-basis: 30px;
list-style-type: none;
display: flex;
border: 1px dotted blue;
height: auto;
}
a {
cursor: pointer;
border: 1px dotted green;
display: block;
background-color: lightblue;
padding: 8px 0px;
width: 100%;
}
<div id="root">
<ul>
<li><a>Link 1</a></li>
<li><a>Long Link 2</a></li>
</ul>
</div>
you can omit padding from top and bottom of the anchor and use height 100% a{height: 100%;}
#root {
width: 140px;
box-sizing: border-box;
}
ul {
display: flex;
justify-content: space-between;
margin: auto;
padding: 0;
}
li {
flex-grow: 1;
flex-basis: 30px;
list-style-type: none;
display: inline-block;
border: 1px dotted blue;
height: auto;
}
a {
cursor: pointer;
border: 1px dotted green;
display: inline-block;
background-color: lightblue;
height: 100%;
}
<div id="root">
<ul>
<li><a>Link 1</a></li>
<li><a>Long Link 2</a></li>
</ul>
</div>

How can i make list items in a horizontal container fill the entire container evenly without spacing between?

I've made a horizontal list using flexbox that fills its container evenly.
But when i try to change the background of the list items during hover etc. you can see there is empty space between each element. Is there any way to get rid of this while still making the list items fill the entire width of the container?
.wrapper {
margin-top: 30px;
border: 1px solid lightblue;
width: 100%;
}
ul {
display: flex;
justify-content: space-around;
flex-wrap: wrap;
}
li {
color: black;
cursor: pointer;
list-style: none
}
li:hover {
background-color: lightblue;
color: white;
}
<div class="wrapper">
<ul>
<li>123</li>
<li>ABC</li>
<li>789</li>
<li>XYZ</li>
</ul>
</div>
For example here the items are evenly spaced, but there's lots of space between each item.
What i want is something like this when i hover over a list item:
Any ideas how to do this?
Remove all extern padding/margin then use flex:1 and padding within li:
.wrapper {
margin-top: 30px;
border: 1px solid lightblue;
width: 100%;
}
ul {
padding:0;
margin:0;
display: flex;
flex-wrap: wrap;
}
li {
color: black;
flex:1;
text-align:center;
padding:10px 0;
cursor: pointer;
list-style: none
}
li:hover {
background-color: lightblue;
color: white;
}
<div class="wrapper">
<ul>
<li>123</li>
<li>ABC</li>
<li>789</li>
<li>XYZ</li>
</ul>
</div>
.wrapper {
margin-top: 30px;
border: 1px solid lightblue;
width: 100%;
}
ul {
display: flex;
list-style: none;
padding: 0;
margin: 0;
}
li {
width: 100%;
color: black;
cursor: pointer;
list-style: none;
text-align: center;
padding: 15px 0;
}
li:hover {
background-color: lightblue;
color: white;
}
<div class="wrapper">
<ul>
<li>123</li>
<li>ABC</li>
<li>789</li>
<li>XYZ</li>
</ul>
</div>