How to align a list of elements to bottom? - html

I'd like to align a list of elements inside of a container to bottom. By default it sticks to the top of the container.
Note that this list needs to keep its scroll ability. So I can't use flex. Flex makes elements resize and avoids scroll.
I can't think of an easy way to do this.
JSFiddle
#list {
height: 200px;
}
.item {
height: 30px;
line-height: 30px;
background-color: lightgray;
margin: 3px 0;
}
<div id="list">
<div class="item">Item0</div>
<div class="item">Item1</div>
<div class="item">Item2</div>
<div class="item">Item3</div>
<div class="item">Item4</div>
<div class="item">Item5</div>
<div class="item">Item6</div>
<div class="item">Item7</div>
<div class="item">Item8</div>
<div class="item">Item9</div>
</div>

There is a hack using transform scaling in the y-direction - see demo below:
#list {
height: 200px;
border:1px solid green;
overflow-y: auto;
transform: scaleY(-1);
}
.item {
height: 30px;
line-height: 30px;
background-color: lightgray;
margin: 3px 0;
transform: scaleY(-1);
}
<div id="list">
<div class="item">Item0</div>
<div class="item">Item1</div>
<div class="item">Item2</div>
<div class="item">Item3</div>
<div class="item">Item4</div>
<div class="item">Item5</div>
<div class="item">Item6</div>
<div class="item">Item7</div>
<div class="item">Item8</div>
<div class="item">Item9</div>
</div>

#list {
position: absolute; bottom: 0;
}
make sure to add position: relative; to the above element
https://jsfiddle.net/ege89t3h/

Related

Flex nowrap container not wrapping child. when the width of those are in mentioned in percentage

I have a flex container that wraps some cards. I have implemented a horizontal scroller with flex(using flex-nowrap). The flex wrapper container is subjected to have a 36px left spacing and a 0px right spacing initially. The catch here is after the last card is scrolled I need to have a 36px right spacing.
here is what I did so far
*{
box-sizing: border-box;
}
h2 {
margin: 0;
}
body {
background: cadetblue;
}
.container {
width: 500px;
margin: 0 auto;
background: #000;
padding: 20px 36px;
}
.scroll-wrapper {
overflow: hidden;
margin-right: -36px;
}
.scroll-inner {
display: flex;
flex-flow: row nowrap;
overflow: auto;
margin: 0px -16px;
}
.card {
height: 250px;
width: 75%;
flex: 1 0 75%;
padding: 0px 16px;
}
.inner-wrapper {
background: #fff;
height: 250px;
}
<div class="container">
<div class="scroll-wrapper">
<div class="scroll-inner">
<div class="card">
<div class="inner-wrapper"><h2>Card</h2></div>
</div>
<div class="card">
<div class="inner-wrapper"><h2>Card</h2></div>
</div>
<div class="card">
<div class="inner-wrapper"><h2>Card</h2></div>
</div>
<div class="card">
<div class="inner-wrapper"><h2>Card</h2></div>
</div>
<div class="card">
<div class="inner-wrapper"><h2>Card</h2></div>
</div>
<div class="card">
<div class="inner-wrapper"><h2>Card</h2></div>
</div>
<div class="card">
<div class="inner-wrapper"><h2>Card</h2></div>
</div>
<div class="card">
<div class="inner-wrapper"><h2>Card</h2></div>
</div>
<div class="card">
<div class="inner-wrapper"><h2>Card</h2></div>
</div>
</div>
</div>
</div>
I have given a negative right margin for the wrapper to make it look like it's flowing from the right.
Once the last element is scrolled/reached I want it to look something like this
enter image description here
One thing I noticed is my scroll-inner(flex-nowrap) is not wrapping up the entire children. I presumed if we have five children each having width 50px. The scroll-inner should show a scrollable width of 250px, Unfortunately, it's not how flex is behaving. Any help or suggestion is much appreciated.
Updating few images that show what I'm really looking for
During scrolling
After scrolling till the last card
Try
.scroll-wrapper {
overflow: hidden;
margin: auto;
}
.scroll-inner {
display: flex;
flex-flow: row nowrap;
overflow: auto;
margin: auto;
}
I have found a fix and hope this help someone.
*{
box-sizing: border-box;
}
h2 {
margin: 0;
}
body {
background: cadetblue;
}
.container {
width: 500px;
margin: 0 auto;
background: #000;
padding: 20px 36px;
}
.scroll-wrapper {
overflow: hidden;
margin-right: -36px;
}
.scroll-inner {
display: flex;
flex-flow: row nowrap;
overflow: auto;
margin: 0px;
}
.card {
height: 250px;
width: 75%;
flex: 1 0 75%;
padding-right: 40px;
margin-right: -8px;
}
.inner-wrapper {
background: #fff;
height: 250px;
}
<div class="container">
<div class="scroll-wrapper">
<div class="scroll-inner">
<div class="card">
<div class="inner-wrapper"><h2>Card</h2></div>
</div>
<div class="card">
<div class="inner-wrapper"><h2>Card</h2></div>
</div>
<div class="card">
<div class="inner-wrapper"><h2>Card</h2></div>
</div>
<div class="card">
<div class="inner-wrapper"><h2>Card</h2></div>
</div>
<div class="card">
<div class="inner-wrapper"><h2>Card</h2></div>
</div>
<div class="card">
<div class="inner-wrapper"><h2>Card</h2></div>
</div>
<div class="card">
<div class="inner-wrapper"><h2>Card</h2></div>
</div>
<div class="card">
<div class="inner-wrapper"><h2>Card</h2></div>
</div>
<div class="card">
<div class="inner-wrapper"><h2>Card</h2></div>
</div>
</div>
</div>
</div>
Please do answer if someone has a better solution!! Thanks

Middle of the display flex elements

There are some elements .element that are displayed with flex (the red ones). For some reasons the red elements have to be display as flex, it could not be changed. I would like to get an effect that some text will be placed and center above the middle of the red elements.
The expected result should be:
I use another div with display: flex and put there a legends but it does not display the legends between the elements (legends are not center between the elements), my result is:
.legendContainer,
.elementsContainer {
display: flex;
}
.legendElement,
.element {
flex: 1;
height: 20px;
}
.element {
margin-left: 1px;
margin-right: 1px;
background: red;
}
<div class="legendContainer">
<div class="legendElement"></div>
<div>..oddXXbboo..</div>
<div class="legendElement"></div>
<div>..oddXXbboo..</div>
<div class="legendElement"></div>
<div>..oddXXbboo..</div>
<div class="legendElement"></div>
<div>..oddXXbboo..</div>
<div class="legendElement"></div>
</div>
<div class="elementsContainer">
<div class="element"></div>
<div class="element"></div>
<div class="element"></div>
<div class="element"></div>
<div class="element"></div>
</div>
What should I change to achieve my goal?
I would put the legend elements into the flex items, give them position: absolute (and position: relative to their parent elements to serve as position anchors) and position them using the settings below, which puts them horizontally-centered above the right end of their parent:
.elementsContainer {
display: flex;
margin-top: 50px;
}
.element {
flex: 1;
height: 20px;
margin-left: 1px;
margin-right: 1px;
background: red;
position: relative;
}
.legend {
position: absolute;
top: -1.2em;
right: 0;
transform: translateX(50%);
}
<div class="elementsContainer">
<div class="element">
<div class="legend">..oddXXbboo..</div>
</div>
<div class="element">
<div class="legend">..oddXXbboo..</div>
</div>
<div class="element">
<div class="legend">..oddXXbboo..</div>
</div>
<div class="element">
<div class="legend">..oddXXbboo..</div>
</div>
<div class="element"></div>
</div>
P.S.: If you want the position to be even more exact, change the right value of .legend to -1px, since there are 1px margins left and right on the .elements. This will give them a 1px offset in relation to the parents right border.
Remove the <div class="legendElement"></div> elements - they seem unnecessary.
Add 10 % horizontal padding to the legendContainer element - this will align your four elements with the five elements below.
Lastly, flex: 1; text-align: center on the child divs.
.legendContainer,
.elementsContainer {
display: flex;
}
.legendElement,
.element {
flex: 1;
height: 20px;
}
.element {
margin-left: 1px;
margin-right: 1px;
background: red;
}
.legendContainer {
padding: 0 10%;
}
.legendContainer > div {
text-align: center;
flex: 1;
}
<div class="legendContainer">
<div>..oddXXbboo..</div>
<div>..oddXXbboo..</div>
<div>..oddXXbboo..</div>
<div>..oddXXbboo..</div>
</div>
<div class="elementsContainer">
<div class="element"></div>
<div class="element"></div>
<div class="element"></div>
<div class="element"></div>
<div class="element"></div>
</div>
You should think of your element divs as the white sections in the red background, since that's what you want labeled. Then give your labels a fixed width and position them centered above the elements:
.elements {
display: flex;
background: #f00;
width: 100%;
height: 20px;
justify-content: space-around;
margin-top: 30px;
}
.element {
background: #fff;
width: 5px;
position:relative;
}
.label {
position: absolute;
width: 40px;
top: -20px;
white-space: pre;
left: -20px;
}
<div class='elements'>
<div class='element'>
<div class='label'>Label 1</div>
</div>
<div class='element'>
<div class='label'>Label 2</div>
</div>
<div class='element'>
<div class='label'>Label 3</div>
</div>
<div class='element'>
<div class='label'>Label 4</div>
</div>
</div>

HTML/CSS adjust parent div's height/width automatically according to children content

I want to make this:
stacked cards
the html would look like so:
<div class="container>
<div class="top-card>
<div class="card-content">
...
</div>
</div>
<div class="bottom-card>
</div>
</div>
I am having trouble styling this so that the height of the entire card adjusts automatically according to the content inside the top card. Thank you in advance.
you can use a combination of box-shadow and display: inline-block to accomplish what you are trying to do. I have updated the answer. Here is the code:
.grandparent {
display: inline-block;
position: relative;
}
.parent {
display: inline-block;
background: blue;
position: absolute;
top: 0;
left: 0;
}
.child {
width: 100px;
height: 100px;
background: red;
margin: 5px;
}
.shadow {
margin-left: -7px;
margin-top: -7px;
background: pink;
z-index: -100;
border: 1px solid green;
}
.empty {
opacity: 0;
}
<div class="grandparent">
<div class="parent">
<div class="child"></div>
</div>
<div class="parent shadow">
<div class="child empty"></div>
</div>
</div>

Position sticky with direction rtl not working

I have a wrapper div.container inside are div.children. I am setting position:sticky on the first child. I works fine on direction:ltr, however on direction:rtl sticky don't work.
I'm not sure if this is a browser bug or my styles are just wrong. Please note that I don't have access to the html itself, I can only change the css file and no js as possible.
Tested on:
Firefox - Pass ✅
Google Chrome - Fail ❌
Safari - Fail ❌
.container {
margin: 10px;
padding: 0;
border: 1px solid #000;
overflow-x: scroll;
overflow-y: hidden;
width: 500px;
position: relative;
white-space: nowrap;
}
.container.ltr { direction: ltr; }
.container.rtl { direction: rtl; }
.children {
display: inline-block;
margin: 0;
padding: 0;
width: 100px;
height: 100px;
border: 1px solid rgba(0,0,0,0.08);
}
.children.sticky {
position: sticky;
background: #f30;
color: #fff;
}
.container.ltr .children.sticky { left: 0; }
.container.rtl .children.sticky { right: 0; }
<div class="container ltr">
<div class="children sticky">1</div>
<div class="children">2</div>
<div class="children">3</div>
<div class="children">4</div>
<div class="children">5</div>
<div class="children">6</div>
<div class="children">7</div>
<div class="children">8</div>
<div class="children">9</div>
<div class="children">10</div>
</div>
<div class="container rtl">
<div class="children sticky">1</div>
<div class="children">2</div>
<div class="children">3</div>
<div class="children">4</div>
<div class="children">5</div>
<div class="children">6</div>
<div class="children">7</div>
<div class="children">8</div>
<div class="children">9</div>
<div class="children">10</div>
</div>
Chromium Bug Report
https://bugs.chromium.org/p/chromium/issues/detail?id=1140374
I bumped into this same issue.
Managed to find a workaround by using an extra container div, which seems to work fine on Chrome (v93), but still fails in Safari (v14.1.2), somehow it moves the sticky element to the left (???)
.container {
margin: 10px;
border: 1px solid #000;
overflow: auto;
width: 500px;
white-space: nowrap;
}
.container.ltr {
direction: ltr;
}
.container.rtl {
direction: rtl;
}
.inner {
display: inline-block;
}
.children {
display: inline-block;
width: 100px;
height: 100px;
border: 1px solid rgba(0,0,0,0.08);
}
.children.sticky {
position: sticky;
background: #f30;
color: #fff;
}
.container.ltr .children.sticky {
left: 0;
}
.container.rtl .children.sticky {
right: 0;
}
<div class="container ltr">
<div class="children sticky">1</div>
<div class="children">2</div>
<div class="children">3</div>
<div class="children">4</div>
<div class="children">5</div>
<div class="children">6</div>
<div class="children">7</div>
<div class="children">8</div>
<div class="children">9</div>
<div class="children">10</div>
</div>
<div class="container rtl">
<div class="inner">
<div class="children sticky">1</div>
<div class="children">2</div>
<div class="children">3</div>
<div class="children">4</div>
<div class="children">5</div>
<div class="children">6</div>
<div class="children">7</div>
<div class="children">8</div>
<div class="children">9</div>
<div class="children">10</div>
</div>
</div>
In my real use case there are more sticky elements (like the text in each children box), which are working somehow in Safari as well, but could not replicate that with a simple example. I also have a sticky sidebar, which has the same behavior as in the example above.
position: sticky
has got certain set of limitations in it's behaviour, please refer to https://www.designcise.com/web/tutorial/how-to-fix-issues-with-css-position-sticky-not-working
Please check if position: fixed serves your purpose.
.container {
margin: 10px;
padding: 0;
border: 1px solid #000;
overflow-x: scroll;
overflow-y: hidden;
width: 500px;
position: relative;
white-space: nowrap;
}
.container.ltr { direction: ltr; }
.container.rtl { direction: rtl; }
.children {
display: inline-block;
margin: 0;
padding: 0;
width: 100px;
height: 100px;
border: 1px solid rgba(0,0,0,0.08);
}
.container.ltr .children:nth-child(2){
margin-left: 102px;
}
.container.rtl .children:nth-child(2){
margin-right: 102px;
}
.children.sticky {
/* position: sticky; */
position :fixed;
background: #f30;
color: #fff;
}
/*.container.ltr .children.sticky { left: 0; }
.container.rtl .children.sticky { right: 0; } */
<div class="container ltr">
<div class="children sticky">1</div>
<div class="children">2</div>
<div class="children">3</div>
<div class="children">4</div>
<div class="children">5</div>
<div class="children">6</div>
<div class="children">7</div>
<div class="children">8</div>
<div class="children">9</div>
<div class="children">10</div>
</div>
<div class="container rtl">
<div class="children sticky">1</div>
<div class="children">2</div>
<div class="children">3</div>
<div class="children">4</div>
<div class="children">5</div>
<div class="children">6</div>
<div class="children">7</div>
<div class="children">8</div>
<div class="children">9</div>
<div class="children">10</div>
</div>
am also having the same issue but with table scroll with a sticky header above it & so as a temp solution for now, we can us a bit of js to reset the scroll to start from the right as expected.
so lets say we have a div that have a scrollable table and a header that should be sticky when we scroll right/left
<div class="scrollable" data-scroll-reset>
<div class="sticky">
this should remain still no matter how we scroll to left/right
</div>
<table class="rtl">
<thead>...</thead>
<tbody>...</tbody>
</table>
</div>
<style>
.scrollable {
overflow-x: scroll;
}
.sticky {
left: 0;
right: 0;
z-index: 1;
position: sticky;
}
.rtl {
direction: rtl;
}
</style>
<script>
window.addEventListener('load', () => {
document.querySelectorAll('[data-scroll-reset]').forEach((e) => {
e.scrollLeft = 10000
})
})
</script>
both data-scroll-reset & rtl should be added on condition, otherwise it will mess the scrolling when the direction is changed to ltr.

Make flexbox grid have a horizontal scroll bar on mobile

I'm trying to figure out how to make a table have a bottom horizontal scroll bar. This is my HTML:
<div class="grid-block table">
<div class="grid-block header">
<div class="grid-block small-2 column">
times 6
</div>
</div>
<div class="grid-block row">
<div class="grid-block small-2 column">
times 6
</div>
</div>
</div>
I have used this CSS thinking it would fix my problem.
.table {
overflow: auto !important;
width: 1400px !important;
}
I've added the importants at the moment just to make sure these stylings are applied.
I should also point out that every element here is a flex item.
Cheers
This code might help you get started.
.wrapper {
width: 100%;
overflow: auto;
white-space: nowrap;
font-size: 0;
}
.wrapper .child {
font-size: 1rem;
height: 50px;
width: 60px;
display: inline-block;
background-color: cornflowerblue;
text-align: center;
border: 1px solid coral;
margin-left: 10px;
}
.wrapper .child:first-child {
margin-left: 0px;
}
<div class="wrapper">
<div class="child">1</div>
<div class="child">2</div>
<div class="child">3</div>
<div class="child">4</div>
<div class="child">5</div>
<div class="child">6</div>
<div class="child">7</div>
<div class="child">8</div>
<div class="child">9</div>
<div class="child">10</div>
</div>