Css : Handle two flexbox that can overflow - html

I must handle a case where I want to display on one line a value, a category and the number of concerned item in the following format.
[ Item name ] ([ Path start ], [ Item count ])
Example : My item value (My category, 5)
My issue is that the item name and the path start can be too long. I listed the different case in the following drawing
And I can't find a way to handle all the case using CSS only. My biggest issue is to fix the size of the two flex-box when they are both overflowing.
The closest version I have now is the following (you can un-comment the max-width to see an other result I have):
Code:
.search_list {
padding: 5px;
display: flex;
/* only for exemple */
width: 400px;
border: solid 1px black;
}
.search_info {
display: flex;
flex: 1 1 30%;
/*max-width:30%; Get rid of this */
}
.search_info .flex {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.search_info .no_flex {
flex-grow: 0;
flex-shrink: 0;
}
.search_value {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
flex: 1 1 70%;
max-width: fit-content;
}
<div class="search_list" >
<div class="search_value">Short values</div>
<div class="search_info">
<div class="flex">(Category</div>
<div class="no_flex">, 1)</div>
</div>
</div>
<div class="search_list" >
<div class="search_value">Item value with a long long text that overlow</div>
<div class="search_info">
<div class="flex">(Category</div>
<div class="no_flex">, 1)</div>
</div>
</div>
<div class="search_list" >
<div class="search_value">Long category</div>
<div class="search_info">
<div class="flex">(The category will overflow for sure in this case</div>
<div class="no_flex">, 1)</div>
</div>
</div>
<div class="search_list" >
<div class="search_value">Long category and text that will both overflow</div>
<div class="search_info">
<div class="flex">(The category is very</div>
<div class="no_flex">, 1)</div>
</div>
</div>
But, as you can see, this is not the intended results
I tried many things but I can't find a correct solution and I don't want to do thinks like counting the number of character to do a manual overflow and I also would like to avoid JavaScript since this is for a project in Web-assembly and it's a bit annoying to use JavaScript

Related

Flex wrap and flex basis not working using CSS?

I am making this application, and I am using React. Here, I have many items, and I am dynamically adding them using React. Here's my code to help you understand better -
CSS:
.flexContainer {
display: flex;
flex-wrap: wrap;
}
.flexContainer .item {
padding: 5px;
border: 1px solid aqua;
flex: 1 1 50%;
}
.flexContainer .item {
display: block;
width: 500px;
text-align: center;
}
* {
box-sizing: border-box;
}
React:
<div class="flexContainer">
<div key={p.id} class="item">
<div class="item">
<p className="itemTitle">{p.title}</p>
<button onClick={() => addItem(p)}>
{alreadyAdded ? "Add again" : "Add to Cart"}
</button>
</div>
</div>
</div>
Here is a snippet of my items:
{
id: 7,
price: 50,
button: (
<button
onClick={() => {
alert("This function is not ready yet!!!!");
}}
>
Click!
</button>
),
title: "Apple",
},
So, when I run my program, I get this-
My Pic
I had taken another similar code from here
As you can see, the code I had taken from the other stackoverflow is working, but mine is not working. I've used the same technique to do for mine as well but it's not working.
What I want is, 2 of the items to come in a row, with 50% of width, and so on.
Currently, it's not working.
Please help me out, it would help out a ton!
Thanks.
in terms of your question for that row removing some of the the code will allow this to work.
.flexContainer .item {
display: block;
width: 500px;
}
This code is not really needed unless you have other reasons for it to be in your code but doesnt really play part of your question
As you will see from this link your row works
https://jsfiddle.net/ct96dL2o/1/
so from the original code you supplied this answer will work if you need a more elaborate answer you would need to show more code.
change your item style width
.flexContainer .item {
width:50% !important
}
If you are using bootstrap then use row and inside of that and two col-6 class and also checkout link of bootstrap grid
https://getbootstrap.com/docs/5.2/layout/grid/
<div class="container">
<div class="row">
<div class="col-6">
first
</div>
<div class="col-6">
second
</div>
</div>
</div>

CSS expand transition when child element sizes increase

I am using Vuetify and have a v-list-item with a title and a subtitle. But the title length is limited to only show one line. If the title is longer it will be cut off and show "...".
If I click the list item i want the subtitle to disappear and show the full title instead. This might result in a new height of the whole v-list-item. The expansion of the height should be a transition so that the height is not hopping when I am clicking the list item. I have trouble to solve this problem so maybe you have some ideas. This is my code so far:
<v-list-item three-line :class="{ activeListItem: currentPostId === post.id }">
<v-list-item-content>
<v-list-item-title :class="{'full-text': currentPostId === post.id}">
Title
</v-list-item-title>
<v-list-item-subtitle :class="{ 'post-subtitle-hidden': currentPostId === post.id }">
Subtitle
</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
CSS:
.activeListItem {
background-color: #c4e0ff !important;
}
.full-text {
white-space: normal;
}
.post-subtitle-hidden {
display: none;
}
.v-list-item__subtitle, .v-list-item__title {
-webkit-box-flex: 1;
-ms-flex: 1 1 100%;
flex: 1 1 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
Instead of display: none use max-height: 0 then on the active class give it a max-height of like 100px (the maximum height you think it will ever use) than add a transition on max-height
that way it will have a sliding effect
--- edit ---
snippet for what is discussed in the comments
$('.title').click(function() {
$('.subtitle').toggleClass("subtitle-show");
});
.subtitle {
max-height: 0;
overflow: hidden;
transition: max-height .3s;
}
.subtitle-show {
max-height: 100px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper">
<div class="title">
Title
</div>
<div class="subtitle">
The subtitle
</div>
</div>
When I click on the title the subtitle appears/disappears the only problem with this implementation is that when you close it you have a little delay because it is transitioning on the max-height 100px to 0
As far as I know there is no better way to do this in css.

Merge two columns in to one and then continue with two columns again in two columns container

I am currently having an issue with styling my two column container, Below piece of code works perfectly for creating a two column grid. My new requirement is to have a horizontal line (<hr>) in between based on some condition.
Would be really helpful if anyone can help me out in solving this.
HTML:
<div class="two-column-container" >
<div *ngFor="let item of list; let i = index" >
<div class="two-column-item">
<div class="attribute-name">
{{item.id}}
</div>
</div>
</div>
</div>
CSS:
two-column-item {
max-width: 375px;
width: 100%;
margin-top: 25px;
}
two-column-container {
#include columnar-flex();
#include media-breakpoint-down(sm) {
min-width: 250px;
}
#include media-breakpoint-between(sm, md) {
min-width: 500px;
}
#include media-breakpoint-up(lg) {
min-width: 980px;
}
}
Existing output
New Requirement
For the following code
<div class="two-column-container" >
<div *ngFor="let item of list; let i = index" >
<div class="two-column-item">
<div class="attribute-name">
{{item.id}}
</div>
<div class="horizontal-line">
<hr>
</div>
</div>
</div>
</div>
CSS:
horizontal-line {
width: 100%;
margin-top: 25px;
}
the output is as shown below. I would like to have horizontal line in two columns.

CSS Flexbox fill when content available

I am currently working on a TODO App. This TODO app shows tasks horizontally for the user. In a normal case we have the task which has to be done, with a click on it the user can mark it as done.
However, I now wanted to add the option to assign a due date to it.
What I want to achieve is:
Have the todo text shown in the div box
If a date is given, add the date to the right side of the box
My current code is as following:
.box-task .task-text {
display: flex;
-webkit-box-flex: 1;
-webkit-flex: 1 0 0;
flex: 1 0 0;
font-weight: 400;
font-size: 15px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
margin-left: 8px;
margin-top: 7px;
}
.box-task .task-date {
font-size: 13px;
margin-top: 9px;
color: rgb(50, 138, 214);
display: flex;
-webkit-box-flex: 1;
-webkit-flex: 1 0 0;
flex: 1 0 0;
padding-left: 5px;
padding-right: 5px;
}
My HTML code is (in mix with Laravel blade), I hope you get the idea of what I want to achieve
<div class="col-md-12 col-task-text" style="height:35px;">
<div class="task-checkbox-checked" data-id="1"></div>
<span class="task-text">Test</span>
<span class="task-date">23-05-1995</span>
</div>
</div>
How can I achieve it that the date is always shown on the right side with its own width and the text does get smaller/bigger based on if the date was added?
From everything available so far in your question, I assume the following:
you're trying to display a list of tasks
each task should be displayed on a single row, with a title on left and date on the right side
if the title doesn't fit available space, it should be cut with ellipsis effect.
you're using Bootstrap v3.
If the above is true, this is what you're looking for:
.box-task .task-text {
display: block;
flex: 1 1 auto;
font-weight: 400;
font-size: 15px;
white-space: nowrap;
overflow-x: hidden;
text-overflow: ellipsis;
overflow: hidden;
margin-left: 8px;
margin-top: 7px;
}
.box-task .task-date {
font-size: 13px;
margin-top: 9px;
color: rgb(50, 138, 214);
display: flex;
flex: 0 0 auto;
padding-left: 5px;
padding-right: 5px;
}
.col-task-text {
display: flex;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container">
<div class="row box-task">
<div class="col-md-12 col-task-text" style="height:35px;">
<div class="task-checkbox-checked" data-id="1"></div>
<span class="task-text">Test</span>
<span class="task-date">23-05-1995</span>
</div>
<div class="col-md-12 col-task-text" style="height:35px;">
<div class="task-checkbox-checked" data-id="2"></div>
<span class="task-text">Test</span>
<span class="task-date">23-05-1995</span>
</div>
<div class="col-md-12 col-task-text" style="height:35px;">
<div class="task-checkbox-checked" data-id="3"></div>
<span class="task-text">Test with a lot more text, lorem ipsum dolor sit amet. Test with a lot more text, lorem ipsum dolor sit amet.</span>
<span class="task-date">23-05-1995</span>
</div>
</div>
</div>
There were quite a few details I needed to fix, but the most important ones were:
you need display:inline-block (or block) for text-overflow:ellipsis to work
the display:flex needs to be on the parent, not on the children for flex:{grow} {shrink} {basis}; shorthand to work.
If you're going to use flexbox you need to read CSS documentation*** available on each of its properties. The most important part is to understand which props go on parent and which on children and how they all work together.
*** Candidate Recommendation (oficial spec). You might find this resource useful.
The rest are details.
If the above is not what you're looking for, please update your question with all the info I had to assume and, if I can help, I'll update my answer. If not, I'll delete it.

How to prevent table-cell from expanding

https://jsfiddle.net/pepgw4cz/1/
This is a typical article list scenario, every item has its image, title, introtext and created time. As you can see in the 2nd item, where the title is longer, the table exceeds its designated width. This could be easily solved by flex, but my client is using a 2011 laptop with IE9 and she wouldn't let go.
So I am stuck with table. The container's width is unknown(fit mobile screen) as well as the itemBody's width(actually, setting them to a fixed width doesn't change anything.), and the item Title has to be limited to one line(white-space:nowrap), which contributes to the problem.
Here is the codes, I copy it from my site so the structure looks a little wierd, but look at the fiddle and you will get the idea
<ul>
<li class="card " k2id="84">
<div class="moduleItemImageContainer">
<a class="moduleItemImage">
</a>
</div>
<div class="moduleItemBody">
<div class="moduleItemBodyContainer">
<span class="moduleItemDateCreated">2016-06-11</span>
<a class="moduleItemTitle">Norm</a>
<div class="moduleItemIntrotext">
人民大会堂国庆宴会的细节 </div>
</div>
</div>
</li>
<li class="card " k2id="83">
<div class="moduleItemImageContainer">
<a class="moduleItemImage">
</a>
</div>
<div class="moduleItemBody">
<div class="moduleItemBodyContainer">
<span class="moduleItemDateCreated">2016-06-11</span>
<a class="moduleItemTitle">Looooooooong Title Long titleLooooooooong Title Long titl</a>
<div class="moduleItemIntrotext">
人民大会堂国庆宴会的细节 </div>
</div>
</div>
</li>
</ul>
<style>
li {
width: 100%;
list-style: none;
display: table;
margin-bottom: 16px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.8)
}
li>* {
display: table-cell;
vertical-align: top
}
div.moduleItemImageContainer{width:1%}
a.moduleItemImage {
display: block;
background-image: url('http://placehold.it/100x100');
width: 100px;
height: 100px;
}
a.moduleItemTitle{white-space:nowrap;overflow:hidden;display:block}
div.moduleItemBody {
padding: 16px;
}
div.moduleItemBodyContainer{
height:68px;overflow:hidden
}
span {
float: right
}
ul {
width: 500px
}
</style>
So, how to prevent table from behaving like this?
just give your div.moduleItemBody a max-width:1px; DEMO
and if you want your title to break in multiple lines if it is too long then remove white-space: nowrap; from a.moduleItemTitle DEMO
<table style='table-layout:fixed'>
For those who use bootstrap, please you can add a class class="text-wrap" on the cells.
This will automatically give the required width to the table cells according to the data its holding.