Have a little issue to force items to be in one row without a table.
For example I have like this:
Problem is if somehow long text in left block has word break (because of screen width, maybe), then two columns will not match.
I know it is easy to do with table, but is there another way to do it flexible?
html
<div class="data">
<div class="data__name">
<ul>
<li>Lorem ipsum dolor sit amet.:</li>
<li>Lorem ipsum dolor sit amet.:</li>
<li>Lorem ipsum dolor sit amet.:</li>
<li>Lorem ipsum dolor sit amet.:</li>
</ul>
</div>
<div class="data__line"></div>
<div class="data__info">
<ul>
<li>item1</li>
<li>item2</li>
<li>item3</li>
<li>item4</li>
</ul>
</div>
css
.data {
font-size: 15pt;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
margin: 25px 0;
}
.data__name {
color: #666666;
-webkit-box-flex: 0;
-ms-flex: 0 40%;
flex: 0 40%;
}
.data__line {
border-left: 2px solid gray;
}
.data__info {
font-weight: bold;
margin-left: 5%;
white-space: nowrap;
}
you can use word-break: break-word; on li element to wrap text inside component if text is too long
.data {
font-size: 15pt;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
margin: 25px 0;
}
.data__name {
color: #666666;
-webkit-box-flex: 0;
-ms-flex: 0 40%;
flex: 0 40%;
}
.data__name li {
word-break: break-word;
}
.data__line {
border-left: 2px solid gray;
}
.data__info {
font-weight: bold;
margin-left: 5%;
white-space: nowrap;
}
<div class="data">
<div class="data__name">
<ul>
<li>Lorem ipsum dolorvvvvvvvvvvvv sit amet.:</li>
<li>Lorem ipsum dolor sit amet.vvvvvvvvvvvvvvvvvvv:</li>
<li>Lorem ipsum dolor sit amet.:</li>
<li>Lorem ipsum dolor sit amet.:</li>
</ul>
</div>
<div class="data__line"></div>
<div class="data__info">
<ul>
<li>item1</li>
<li>item2</li>
<li>item3</li>
<li>item4</li>
</ul>
</div>
Add flex-wrap: wrap; for the items
Related
I am trying to create a scrollable horizontal timeline with a fixed width. I have overflow-x: auto on the parent container and whenever I add white-space: nowrap to that same element, the child list elements start getting cut off. I assume this is something to do with the behavior of flex-box. I have tried adding min-width: 0 to the flex elements and flex-grow: 1 but no luck.
body {
font-family: Arial, Helvetica, sans-serif;
}
.container {
height: 200px;
width: 500px;
margin: 0 auto;
overflow-x: auto;
overflow-y: hidden;
white-space: nowrap;
}
.timeline {
display: flex;
justify-content: center;
min-width: 0;
}
.timeline ol {
list-style: none;
display: flex;
justify-content: center;
}
.timeline .horizontal-line {
position: relative;
background-color: #0d6a3d;
height: 3px;
border-radius: 4px;
margin: 5em 0;
}
.event {
margin: 0px 10px;
position: relative;
}
.date {
position: relative;
text-align: center;
top: -70px;
width: 100%;
}
.date::after {
content: "";
position: absolute;
bottom: -28px;
left: 50%;
right: auto;
height: 20px;
width: 20px;
border-radius: 50%;
border: 3px solid #00a950;
background-color: #fff;
transition: 0.3s ease;
transform: translateX(-50%);
}
.content {
width: 100%;
text-align: center;
position: relative;
top: -45px;
}
<section class="container">
<div class="timeline">
<div class="horizontal-line">
<ol>
<li class="event">
<h3 class="date">07/02/2020</h3>
<p class="content">Lorem ipsum dolor sit amet, consectetur adipiscing elit</p>
</li>
<li class="event">
<h3 class="date">08/25/2020</h3>
<p class="content">Lorem ipsum dolor sit amet, consectetur adipiscing elit</p>
</li>
<li class="event">
<h3 class="date">08/25/2020</h3>
<p class="content">Lorem ipsum dolor sit amet, consectetur adipiscing elit</p>
</li>
<li class="event">
<h3 class="date">08/25/2020</h3>
<p class="content">Lorem ipsum dolor sit amet, consectetur adipiscing elit</p>
</li>
<li class="event">
<h3 class="date">08/25/2020</h3>
<p class="content">Lorem ipsum dolor sit amet, consectetur adipiscing elit</p>
</li>
<li class="event">
<h3 class="date">08/25/2020</h3>
<p class="content">Lorem ipsum dolor sit amet, consectetur adipiscing elit</p>
</li>
</ol>
</div>
</div>
</section>
Add width: fit-content; to your timeline. That gets all elements to fit in the horizontal scroll. Then you are left with the default padding-inline-start on the ol. You can remove that gap by setting padding: 0; or padding-inline-start: 0;.
body {
font-family: Arial, Helvetica, sans-serif;
}
.container {
height: 200px;
width: 500px;
margin: 0 auto;
overflow-x: auto;
overflow-y: hidden;
white-space: nowrap;
}
.timeline {
display: flex;
justify-content: center;
min-width: 0;
width: fit-content;
}
.timeline ol {
list-style: none;
display: flex;
justify-content: center;
padding: 0;
}
.timeline .horizontal-line {
position: relative;
background-color: #0d6a3d;
height: 3px;
border-radius: 4px;
margin: 5em 0;
}
.event {
margin: 0px 10px;
position: relative;
}
.date {
position: relative;
text-align: center;
top: -70px;
width: 100%;
}
.date::after {
content: "";
position: absolute;
bottom: -28px;
left: 50%;
right: auto;
height: 20px;
width: 20px;
border-radius: 50%;
border: 3px solid #00a950;
background-color: #fff;
transition: 0.3s ease;
transform: translateX(-50%);
}
.content {
width: 100%;
text-align: center;
position: relative;
top: -45px;
}
<section class="container">
<div class="timeline">
<div class="horizontal-line">
<ol>
<li class="event">
<h3 class="date">07/02/2020</h3>
<p class="content">Lorem ipsum dolor sit amet, consectetur adipiscing elit</p>
</li>
<li class="event">
<h3 class="date">08/25/2020</h3>
<p class="content">Lorem ipsum dolor sit amet, consectetur adipiscing elit</p>
</li>
<li class="event">
<h3 class="date">08/25/2020</h3>
<p class="content">Lorem ipsum dolor sit amet, consectetur adipiscing elit</p>
</li>
<li class="event">
<h3 class="date">08/25/2020</h3>
<p class="content">Lorem ipsum dolor sit amet, consectetur adipiscing elit</p>
</li>
<li class="event">
<h3 class="date">08/25/2020</h3>
<p class="content">Lorem ipsum dolor sit amet, consectetur adipiscing elit</p>
</li>
<li class="event">
<h3 class="date">08/25/2020</h3>
<p class="content">Lorem ipsum dolor sit amet, consectetur adipiscing elit</p>
</li>
</ol>
</div>
</div>
</section>
As far as I know, width of a flex item adjusts to its content(when flex-direction: row;).
Here you see, the width of second .item is too long even though I set the width of h1 to 50%.
* {
margin: 0;
padding: 0;
}
.container {
display: flex;
justify-content: space-between;
border: 2px solid red;
padding: 10px;
}
.item {
border: 1px solid black;
}
.test {
width: 50%;
}
<div class="container">
<div class="item">Lorem ipsum dolor sit amet.</div>
<div class="item">
<h1 class="test">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Commodi,
quo.
</h1>
</div>
</div>
But when I use px instead of %, the result that I wanted comes out. (Please view it in a full page)
* {
margin: 0;
padding: 0;
}
.container {
display: flex;
justify-content: space-between;
border: 2px solid red;
padding: 10px;
}
.item {
border: 1px solid black;
}
.test {
width: 400px;
}
<div class="container">
<div class="item">Lorem ipsum dolor sit amet.</div>
<div class="item">
<h1 class="test">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Commodi,
quo.
</h1>
</div>
</div>
I can't understand how % is calculated in the first code. Can somebody help? Thanks
You have to apply the width on the .item element.
* {
margin: 0;
padding: 0;
}
.container {
display: flex;
justify-content: space-between;
border: 2px solid red;
padding: 10px;
}
.item {
border: 1px solid black;
}
.item:nth-child(2) {
width: 50%;
}
<div class="container">
<div class="item">Lorem ipsum dolor sit amet.</div>
<div class="item">
<h1 class="test">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Commodi, quo.
</h1>
</div>
</div>
You are not applying 50% to children (.item) but rather to (.test), which is not child of display:flex. Fix it and you'll get result!
* {
margin: 0;
padding: 0;
}
.container {
display: flex;
justify-content: space-between;
border: 2px solid red;
padding: 10px;
}
.item {
border: 1px solid black;
width: 50%;
}
.test {
background: yellow;
}
<div class="container">
<div class="item">Lorem ipsum dolor sit amet.</div>
<div class="item">
<h1 class="test">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Commodi,quo. </h1>
</div>
</div>
I want to align all the list items perfectly but I am not able to do it.
If you see the image since the second li has more text, it is causing them to not align.
I can't use text-overflow on the name of the person, unlike notes.
Margin and padding are also not working.
Please help me how to solve it .
#data-table .list {
display: flex;
align-items: center;
justify-content: space-between;
text-align: center;
color: #97A1A9;
font-size: .9rem;
white-space: nowrap;
}
#data-table .list>* {
padding: 1rem 2rem;
}
#data-table .list div:first-child {
display: flex;
align-items: center;
justify-content: center;
text-align: center;
}
#data-table .list div:first-child input[type="checkbox"] {
margin-right: 7px;
}
#data-table .list div:last-child {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 221px;
}
<div id="data-table">
<ul>
<li class="list">
<div><input type="checkbox">Customer Name</div>
<div>Seller #</div>
<div>Bill #</div>
<div>Amount</div>
<div>Due Date</div>
<div>Bill Payment Date</div>
<div>Notes</div>
</li>
<!-- Dummy -->
<li class="list">
<div><input type="checkbox">Roshan Ahmad Shaheen</div>
<div>2523532</div>
<div> 73457346735</div>
<div>122.76k</div>
<div>23-Jan-2021</div>
<div> --</div>
<div>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Quasi, accusamus?</div>
</li>
<li class="list">
<div><input type="checkbox">Roshan Ahmad</div>
<div>2523532</div>
<div> 73457346735</div>
<div>122.76k</div>
<div>23-Jan-2021</div>
<div> --</div>
<div>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Quasi, accusamus?</div>
</li>
There is no way to align flexbox elements on different rows without setting fixed widths. Frankly this is tabular data and so you should be using a table.
Or CSS-Tables
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
::before,
::after {
box-sizing: inherit;
}
#data-table ul {
display: table;
}
#data-table .list {
display: table-row;
text-align: left;
color: #97A1A9;
font-size: .9rem;
white-space: nowrap;
}
#data-table .list>* {
padding: 1rem 2rem;
display: table-cell;
}
#data-table .list div:first-child input[type="checkbox"] {
margin-right: 7px;
}
<div id="data-table">
<ul>
<li class="list">
<div><input type="checkbox">Customer Name</div>
<div>Seller #</div>
<div>Bill #</div>
<div>Amount</div>
<div>Due Date</div>
<div>Bill Payment Date</div>
<div>Notes</div>
</li>
<!-- Dummy -->
<li class="list">
<div><input type="checkbox">Roshan Ahmad Shaheen</div>
<div>2523532</div>
<div> 73457346735</div>
<div>122.76k</div>
<div>23-Jan-2021</div>
<div> --</div>
<div>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Quasi, accusamus?</div>
</li>
<li class="list">
<div><input type="checkbox">Roshan Ahmad</div>
<div>2523532</div>
<div> 73457346735</div>
<div>122.76k</div>
<div>23-Jan-2021</div>
<div> --</div>
<div>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Quasi, accusamus?</div>
</li>
Today I've faced with specific design: there is row of cards and text inside card is aligned with another text from other cards. So title is aligned with title from other cards, text is aligned with other texts. It is very difficult for me to explain it clearly so I make a screenshot of the thing I'm trying to reach
By now I'm ready to completely ignore this issue due to impossibility of realization by pure css, but who knows, may be there is some solution?
UPDATE: I'm sorry for lack of explanation. Here is the code. My aim is to make the same alignment as in screeenshot above without using <br>s and fixed heights.
.list {
display: flex;
}
.item {
flex: 0 0 auto;
display: flex;
flex-direction: column;
align-items: center;
width: 120px;
padding: 10px;
background-color: #fff;
border-radius: 10px;
text-align: center;
background-color: rebeccapurple;
color: #fff;
}
.item>* {
flex: 0 0 auto;
}
.item>*+* {
margin-top: 10px;
}
.item+.item {
margin-left: 20px;
}
.icon {
background-color: red;
border-radius: 100%;
width: 20px;
height: 20px;
}
.title {
text-transform: uppercase;
font-weight: bold;
}
.text {
float: left;
clear: left;
}
<div class="list">
<div class="item">
<div class="icon"></div>
<div class="title">Lorem ipsum dolor sit amet.</div>
<div class="text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Est, amet.</div>
</div>
<div class="item">
<div class="icon"></div>
<div class="title">Lorem ipsum.</div>
<div class="text">Lorem ipsum dolor sit amet</div>
</div>
<div class="item">
<div class="icon"></div>
<div class="title">Lorem ipsum dolor.</div>
<div class="text">Lorem ipsum dolor sit amet</div>
</div>
<div class="item">
<div class="icon"></div>
<div class="title">Lorem ipsum dolor sit amet, consectetur.</div>
<div class="text">Lorem ipsum dolor sit amet</div>
</div>
</div>
Thanks in advance.
What you are trying to do can be easily achieved using CSS grids and a bit of HTML restructuring.
The other way to do this would be to give fixed heights to your text elements.
If you are not familiar with CSS grids and don't like the idea of giving fixed heights to your elements, you can achieve similar result by using a little bit of JavaScript. Check the attached snippet.
I have written a small function equalizeClass() to equalize heights of all the elements belonging to a particular class. What it does is basically scans through all the elements belonging to a particular class and finds the element with maximum height. It then sets the heights of all the elements equal to the calculated maximum height.
Don't forget to call equalize() every time you update your related DOM elements.
I have not changed anything in your HTML structure.
In CSS, I have just added justify-content to your item class.
justify-content: space-between;
function equalizeClass(className) {
var images = document.getElementsByClassName(className);
var max_height = 0;
for (var i = 0; i < images.length; i++) {
if (images[i].clientHeight > max_height) {
max_height = images[i].clientHeight;
}
}
for (var i = 0; i < images.length; i++) {
images[i].style.height = max_height + 'px';
}
}
function equalize() {
equalizeClass("title");
equalizeClass("text");
}
window.addEventListener("orientationchange", equalize());
window.addEventListener('resize', equalize());
.list {
display: flex;
}
.item {
flex: 0 0 auto;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
width: 120px;
padding: 10px;
background-color: #fff;
border-radius: 10px;
text-align: center;
background-color: rebeccapurple;
color: #fff;
}
.item>* {
flex: 0 0 auto;
}
.item>*+* {
margin-top: 10px;
}
.item+.item {
margin-left: 20px;
}
.icon {
background-color: red;
border-radius: 100%;
width: 20px;
height: 20px;
}
.title {
text-transform: uppercase;
font-weight: bold;
}
.text {
float: left;
clear: left;
}
<div class="list">
<div class="item">
<div class="icon"></div>
<div class="title">Lorem ipsum dolor sit amet.</div>
<div class="text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Est, amet.</div>
</div>
<div class="item">
<div class="icon"></div>
<div class="title">Lorem ipsum.</div>
<div class="text">Lorem ipsum dolor sit amet</div>
</div>
<div class="item">
<div class="icon"></div>
<div class="title">Lorem ipsum dolor.</8>
</div>
<div class="text">Lorem ipsum dolor sit amet</div>
</div>
<div class="item">
<div class="icon"></div>
<div class="title">Lorem ipsum dolor sit amet, consectetur.</div>
<div class="text">Lorem ipsum dolor sit amet</div>
</div>
</div>
You need to make your title div a fixed height, ideally a height that is taller than the title text itself. See the code below for your title div:
.title {
text-transform: uppercase;
font-weight: bold;
height: 100px;
max-width: 100%;
}
Then give your text div this style:
.text{
display: flex;
justify-content: center;
align-items: top;
}
See this pen.
I'm trying to make the list take up all the blue space, but I don't want to add another item.
I could just give the items the right amount of padding to make it fit perfectly, but I feel like that's not the right way. So I thought there must be a way to do this with flexbox.
See plunker and snippet:
html,
body {
margin: 0px;
height: 100%;
}
main {
display: flex;
}
#art1 {
flex: 2;
margin-right: 20px;
background: red;
display: flex;
}
#art2 {
background: blue;
flex: 1;
}
#art1>img,
#art1>p {
flex: 1;
}
article {}
#media (max-width: 800px) {
main {
flex-direction: column;
}
#art1 {
margin: 0;
}
}
.activiteiten {
background: yellow;
list-style-type: none;
margin: 0;
padding: 0;
}
.activiteiten>li {
background: white;
border: 1px solid green;
padding: 10px;
}
<main>
<article id="art1">
<p>Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum </p>
<img src="http://via.placeholder.com/150x250" alt="">
</article>
<article id="art2">
<ul class="activiteiten">
<li>Lorem ipsum</li>
<li>Lorem ipsum</li>
<li>Lorem ipsum</li>
<li>Lorem ipsum</li>
<li>Lorem ipsum</li>
</ul>
</article>
</main>
Make your ul a flexbox too:
height: 100%;
margin: 0; // reset the margin
display: flex;
flex-direction: column; // list vertically
justify-content: space-around; // spread the li vertically
and add flex: 1 to the lis
See demo below:
html,
body {
margin: 0px;
height: 100%;
}
main {
display: flex;
}
#art1 {
flex: 2;
margin-right: 20px;
background: red;
display: flex;
}
#art2 {
background: blue;
flex: 1;
}
#art1>img,
#art1>p{
flex: 1;
}
article {}
article ul {
height: 100%;
margin: 0;
display: flex;
flex-direction: column;
justify-content: space-around;
}
article ul li {
flex: 1;
}
#media (max-width: 800px) {
main {
flex-direction: column;
}
#art1 {
margin: 0;
}
}
.activiteiten {
background: yellow;
list-style-type: none;
margin: 0;
padding: 0;
}
.activiteiten>li{
background: white;
border: 1px solid green;
padding: 10px;
}
<main>
<article id="art1">
<p>Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum </p>
<img src="http://via.placeholder.com/150x250" alt="">
</article>
<article id="art2">
<ul class="activiteiten">
<li>Lorem ipsum</li>
<li>Lorem ipsum</li>
<li>Lorem ipsum</li>
<li>Lorem ipsum</li>
<li>Lorem ipsum</li>
</ul>
</article>
</main>