CSS Grid push rows to top based off content - html

In the below example is it possible to have the grid item's height be based off content and pushed to the top? I tried setting some grid-template-rows and grid-auto-flow but that doesn't seem to work either.
So it would look like this:
.wrapper {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-auto-flow: dense;
list-style: none;
max-width: 500px;
}
.wrapper > li {
border: 1px solid black;
}
<ul class="wrapper">
<li>
Heading
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
</ul>
</li>
<li>
Heading
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>
</li>
<li>
Heading
<ul>
<li>Item 1</li>
<li>Item 2</li>
</ul>
</li>
<li>
Heading
<ul>
<li>Item 1</li>
<li>Item 2</li>
</ul>
</li>
<li>
Heading
<ul>
<li>Item 1</li>
<li>Item 2</li>
</ul>
</li>
<li>
Heading
<ul>
<li>Item 1</li>
</ul>
</li>
<li>
Heading
</li>
</ul>

Related

Overflow-y changes the color of the text

I am learning HTML and CSS and I have the following issue, I have a long list of items and I am applying overflow-y with external CSS. The problem is that it changes the font color of the list. I would also be grateful for any info on how to style the scrollbar and only be visible when scrolling.
#main-div {
position: relative;
}
#container-div {
position: absolute;
right: 0;
margin-top: 15%;
margin-right: 10%;
overflow-y: auto;
width: 600px;
height: 350px;
}
.main-text {
color: aliceblue;
mix-blend-mode: difference;
}
<div id="main-div">
<div id="container-div">
<div id="list" class="main-text">
<h4>title 1</h4>
<ul>
<li>item 1</li>
<li>item 1</li>
<li>item 1</li>
</ul>
<h4>title 2</h4>
<ul>
<li>item 1</li>
<li>item 1</li>
<li>item 1</li>
</ul>
<h4>title 3</h4>
<ul>
<li>item 1</li>
<li>item 1</li>
<li>item 1</li>
</ul>
<h4>title 4</h4>
<ul>
<li>item 1</li>
<li>item 1</li>
<li>item 1</li>
</ul>
<h4>title 5</h4>
<ul>
<li>item 1</li>
<li>item 1</li>
<li>item 1</li>
</ul>
<h4>title 6</h4>
<ul>
<li>item 1</li>
<li>item 1</li>
<li>item 1</li>
</ul>
</div>
</div>
</div>
I didn't see the font-color changing. But to style the scrollbar, check the css snippet below.
#main-div {
position: relative;
}
#container-div {
position: absolute;
right: 0;
margin: 10%;
overflow-y: auto;
width: 600px;
height: 300px;
background: lightblue;
}
/* Styling Scroll Bar */
::-webkit-scrollbar {
width: 10px;
}
/* Track */
::-webkit-scrollbar-track {
background: #f1f1f1;
}
/* Handle */
::-webkit-scrollbar-thumb {
background: #c1c1c1;
}
/* Handle on hover */
::-webkit-scrollbar-thumb:hover {
background: #555;
}
<div id="main-div">
<div id="container-div">
<div id="list">
<h4>title 1</h4>
<ul>
<li>item 1</li>
<li>item 1</li>
<li>item 1</li>
</ul>
<h4>title 2</h4>
<ul>
<li>item 1</li>
<li>item 1</li>
<li>item 1</li>
</ul>
<h4>title 3</h4>
<ul>
<li>item 1</li>
<li>item 1</li>
<li>item 1</li>
</ul>
<h4>title 4</h4>
<ul>
<li>item 1</li>
<li>item 1</li>
<li>item 1</li>
</ul>
<h4>title 5</h4>
<ul>
<li>item 1</li>
<li>item 1</li>
<li>item 1</li>
</ul>
<h4>title 6</h4>
<ul>
<li>item 1</li>
<li>item 1</li>
<li>item 1</li>
</ul>
</div>
</div>
</div>
I think you just made it with the wrong class.
since you set the height on the container-div, you should use your mix-blend-mode on the same one.
Try this:
#main-div {
position: relative;
}
#container-div {
position: absolute;
right: 0;
margin-top: 15%;
margin-right: 10%;
overflow-y: auto;
width: 300px;
height: 150px;
background-color: #e2e2e2;
color: aliceblue;
mix-blend-mode: difference;
}
<div id="main-div">
<div id="container-div">
<div id="list">
<h4>title 1</h4>
<ul>
<li>item 1</li>
<li>item 1</li>
<li>item 1</li>
</ul>
<h4>title 2</h4>
<ul>
<li>item 1</li>
<li>item 1</li>
<li>item 1</li>
</ul>
<h4>title 3</h4>
<ul>
<li>item 1</li>
<li>item 1</li>
<li>item 1</li>
</ul>
<h4>title 4</h4>
<ul>
<li>item 1</li>
<li>item 1</li>
<li>item 1</li>
</ul>
<h4>title 5</h4>
<ul>
<li>item 1</li>
<li>item 1</li>
<li>item 1</li>
</ul>
<h4>title 6</h4>
<ul>
<li>item 1</li>
<li>item 1</li>
<li>item 1</li>
</ul>
</div>
</div>
</div>
I've added a background to see the aliceblue color

Fixed height for scrollbar handle

I am trying to get the handle for the scrolebar to remain a fixed height so that it is a 30px by 30px square, but the height command only makes it bigger than the default size and setting the height any smaller than this has no effect.
::-webkit-scrollbar {
width: 30px;
}
::-webkit-scrollbar-track {
background-color: green;
}
::-webkit-scrollbar-thumb {
height: 30px;
background-color: red;
}
<div id="container">
<ul id="list1">
<li>Item 1</li>
<li>Item 1</li>
<li>Item 1</li>
<li>Item 1</li>
<li>Item 1</li>
<li>Item 1</li>
<li>Item 1</li>
<li>Item 1</li>
<li>Item 1</li>
<li>Item 1</li>
<li>Item 1</li>
<li>Item 1</li>
<li>Item 1</li>
<li>Item 1</li>
<li>Item 1</li>
<li>Item 1</li>
<li>Item 1</li>
<li>Item 1</li>
<li>Item 1</li>
<li>Item 1</li>
<li>Item 1</li>
<li>Item 1</li>
<li>Item 1</li>
<li>Item 1</li>
</ul>
</div>
By the way I never knew that was possible, this is also a learning process for me :}
#list1 {
overflow-y: scroll;
/* Setting overflow-y does the trick here, since the scrollbar is native
to the unordered list only -- as you will see below */
height: 100px;
/* Based on the fiddle, this height determines the state of the scrollbar */
}
/* Increasing specifity(using #list1), ensures the scrollbar sytling affects
the area within the #list1 only making it native to those elements only */
/* It would still work either way but its best to contain it for the specific element */
#list1::-webkit-scrollbar-track {
background-color: steelblue;
width: 30px;
}
#list1::-webkit-scrollbar {
width: 30px;
background-color: green;
}
#list1::-webkit-scrollbar-thumb {
background-color: red;
height: 30px;
}
<div id="container">
<ul id="list1">
<li>Item 1</li>
<li>Item 1</li>
<li>Item 1</li>
<li>Item 1</li>
<li>Item 1</li>
<li>Item 1</li>
<li>Item 1</li>
<li>Item 1</li>
<li>Item 1</li>
<li>Item 1</li>
<li>Item 1</li>
<li>Item 1</li>
<li>Item 1</li>
<li>Item 1</li>
<li>Item 1</li>
<li>Item 1</li>
<li>Item 1</li>
<li>Item 1</li>
<li>Item 1</li>
<li>Item 1</li>
<li>Item 1</li>
<li>Item 1</li>
<li>Item 1</li>
<li>Item 1</li>
</ul>
</div>
Also note that Stackoverflow's "snippet view" area has a max height set to it so it might affect the results here, that's why you see the height is set to 100px so it can live within that snippet area ... since the scrollbar is only native to the #list div block, it requires a height to be assigned to it and you get the results.
Try it in a different workspace, like your own editor then add more elements in the unordered list and see whether it still works

Horizontally Align ULs In Different

I have the below code which displays list items horizontally.
However, the horizontal alignment gets broken up between the ULs. Is it possible to have all of the list items aligned across the ULs? ie so that item 6 appears below item 2 etc.
div,
ul,
li {
margin: 0;
padding: 0;
}
li {
width: 24%;
display: inline-block;
border: 1px solid red;
margin-bottom: 20px;
}
ul {
width: 100%;
display: inline-block;
}
.container {
width: 1400px;
}
<div class="container">
<div class="firstdiv">
<ul class="firstul">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
</ul>
</div>
<div class="seconddiv">
<ul class="secondul">
<li>Item 6</li>
<li>Item 7</li>
<li>Item 8</li>
</ul>
</div>
<div class="thirddiv">
<ul class="thirdul">
<li>Item 9</li>
<li>Item 10</li>
<li>Item 11</li>
<li>Item 12</li>
<li>Item 13</li>
<li>Item 14</li>
</ul>
</div>
</div>
Assumming that you need to keep your HTML structure like that, apply display: inline to your lists and their div wrappers:
div,
ul,
li {
margin: 0;
padding: 0;
}
li {
width: 24%;
display: inline-block;
border: 1px solid red;
margin-bottom: 20px;
}
.container div,
.container ul {
display: inline;
}
<div class="container">
<div class="firstdiv">
<ul class="firstul">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
</ul>
</div>
<div class="seconddiv">
<ul class="secondul">
<li>Item 6</li>
<li>Item 7</li>
<li>Item 8</li>
</ul>
</div>
<div class="thirddiv">
<ul class="thirdul">
<li>Item 9</li>
<li>Item 10</li>
<li>Item 11</li>
<li>Item 12</li>
<li>Item 13</li>
<li>Item 14</li>
</ul>
</div>
</div>
A future alternative may be to apply display:grid to your container and display: contents to its descendant <div> and <ul> elements. Granted, the support for display: contents is limited at the moment.
.container {
display: grid;
grid-template-columns: repeat(4, calc(25% - 7.5px));
grid-gap: 20px 10px;
}
.container div,
.container ul {
display: contents;
}
.container li {
list-style: none;
outline: 1px solid #f00;
}
<div class="container">
<div class="firstdiv">
<ul class="firstul">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
</ul>
</div>
<div class="seconddiv">
<ul class="secondul">
<li>Item 6</li>
<li>Item 7</li>
<li>Item 8</li>
</ul>
</div>
<div class="thirddiv">
<ul class="thirdul">
<li>Item 9</li>
<li>Item 10</li>
<li>Item 11</li>
<li>Item 12</li>
<li>Item 13</li>
<li>Item 14</li>
</ul>
</div>
</div>

nested flexbox height vs max-height

update: I see this strange behavior on Chrome 72. FireFox 64 is OK!
I have a problem with a nested flexbox.
In the snippet below I added a dummy XL height to .root.container, so that the result is exactly what I want when there are many items that overflow the available max-height.
Conversely, when there are few items, the .root.container should not extend to all available height.
In other terms, I want .root.container height to be auto, but I can't figure how.
Removing its dummy height, the overflow is triggered on .root.content instead of .sub.content.
Please, help me understand how flexbox works in this particular situation.
P.S. fiddle also available here
html, body {
height: 100%;
margin: 0;
padding: 0;
}
* {
box-sizing: border-box;
}
div {
padding: 10px;
}
.container {
display: flex;
flex-direction: column;
}
.content {
flex: 1;
max-height: 100%;
overflow: auto;
}
.root.container {
background-color: red;
max-height: 100%;
height: 999999px; /* i want height to be 'auto' */
}
.sub.container {
background-color: purple;
height: 100%;
}
.root.header {
background-color: lightblue;
}
.sub.header {
background-color: lightgreen;
}
.root.content {
background-color: yellow;
}
.sub.content {
background-color: orange;
}
<div class="root container">
<div class="root header">header</div>
<div class="root content">
<div class="sub container">
<div class="sub header">menu</div>
<div class="sub content">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
</ul>
</div>
</div>
</div>
</div>
Your code is working as expected when setting the big height because max-height:100% in the child element need a reference, if you remove the height the max-height will fail to auto. As a side note, Firefox will have the same output even if you remove max-height so the issue isn't related to max-height. 1
Instead, you can keep the cascading flex container and rely on the default stretch alignment to obtain what you want:
html, body {
height: 100%;
margin: 0;
padding: 0;
}
* {
box-sizing: border-box;
}
div {
padding: 10px;
}
.container {
display: flex;
flex-direction: column;
}
.content {
flex: 1;
max-height: 100%;
overflow: auto;
}
.root.container {
background-color: red;
max-height: 100%;
}
.sub.container {
background-color: purple;
width:100%; /*added this*/
}
.root.header {
background-color: lightblue;
}
.sub.header {
background-color: lightgreen;
}
.root.content {
background-color: yellow;
display:flex; /*added this*/
}
.sub.content {
background-color: orange;
}
<div class="root container">
<div class="root header">header</div>
<div class="root content">
<div class="sub container">
<div class="sub header">menu</div>
<div class="sub content">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
</ul>
</div>
</div>
</div>
</div>
To better see the issue let's remove some properties and keep only the needed ones that will trigger the different behavior:
html, body {
height: 100%;
margin: 0;
padding: 0;
}
* {
box-sizing: border-box;
}
div {
padding: 10px;
}
.container {
display: flex;
flex-direction: column;
}
.content {
flex: 1;
overflow: auto;
}
.root.container {
background-color: red;
max-height: 100%;
}
.sub.container {
background-color: purple;
height: 100%;
}
.root.header {
background-color: lightblue;
}
.sub.header {
background-color: lightgreen;
}
.root.content {
background-color: yellow;
}
.sub.content {
background-color: orange;
}
<div class="root container">
<div class="root header">header</div>
<div class="root content">
<div class="sub container">
<div class="sub header">menu</div>
<div class="sub content">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
</ul>
</div>
</div>
</div>
</div>
All the issue is related to the inner height:100% used on the .sub.container. Technically and considering the specification this height should fail to auto because the parent height isn't set BUT Firefox seems to be able to evalute this height. Probably due to the nested flex container where we can evaluate the parent height before knowing the content or simply a bug.
Chrome is not doing this and simply ignoring the height which is the logical behavior.
Maybe height: fit-content is what you're looking for? I'm a little confused on what your desired result is.
html, body {
height: 100%;
margin: 0;
padding: 0;
}
* {
box-sizing: border-box;
}
div {
padding: 10px;
}
.container {
display: flex;
flex-direction: column;
}
.content {
flex: 1;
max-height: 100%;
overflow: auto;
}
.root.container {
background-color: red;
max-height: 100%;
height: fit-content;
}
.sub.container {
background-color: purple;
height: 100%;
}
.root.header {
background-color: lightblue;
}
.sub.header {
background-color: lightgreen;
}
.root.content {
background-color: yellow;
}
.sub.content {
background-color: orange;
}
<div class="root container">
<div class="root header">header</div>
<div class="root content">
<div class="sub container">
<div class="sub header">menu</div>
<div class="sub content">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
</ul>
</div>
</div>
</div>
</div>

Align elements in block with other elements in other block(list)

I have problem with aligning elemnts in div. I have following div:
<div class="lists-wrapper">
<div class="list">
<h4>List 1</h4>
<ul>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
</ul>
</div>
<div class="list">
<h4>List 2</h4>
<ul>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
<li>item 5</li>
</ul>
</div>
<div class="list">
<h4>List 3</h4>
<ul>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
</ul>
</div>
<div class="list">
<h4>List 4</h4>
<ul>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
<li>item 5</li>
</ul>
</div>
</div>
SCSS:
.lists-wrapper {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
.list {
width: 20%;
}
h4 {
margin-bottom: 22px;
}
ul {
display: flex;
flex-direction: column;
flex-wrap: wrap;
margin-bottom: 35px;
margin-left: -5px;
}
}
I'm using React and jquery approaches doesn't work for me
The problem is that .list class blocks aligned properly to each other now but when for example h4 width is very long, it splits to the second line and ul doesn't aligned with other ul's in other list blocks because it goes down a bit because of changing the height of h4. I want alignment to work relatively to ul to other ul's in the row, is it possible to do?