How to only make the middle flex component responsive? - javascript

I have a parent component who has three child components. The display is set to flex and flex-direction to row.
here is the code
JS part:
<div className='Container'>
<div className='Text1'>26 Dec 22</div>
<div className='Text2'>Lorem ipsum dolor sit amet</div>
<div className='Text3'>128K</div>
</div>
CSS part:
.Container{
display: flex;
flex-direction: row;
background-color: white;
padding: 20px 20px 20px 20px;
justify-content: space-evenly;
gap:10px;
}
.Text1{
width: 100px;
white-space: nowrap;
}
.Text2{
text-align: left;
width: 400px;
}
.Text3{
width: 100px;
}
Here is the image of the output:
When I change from desktop view to mobile view I want my result to be like this
As one can see only the middle component text was eliminated and ... was added.
In my above code when I change the view I get the result as
Please guide me on how to decrease the width of only the middle component and also add ... when part of the middle component disappears.

In your case, you need the text-overflow: ellipsis; CSS property and use it on the middle element.
The text-overflow CSS property sets how hidden overflow content is signaled to users. It can be clipped, display an ellipsis ('…'), or display a custom string. MDN documentation
.Container {
display: flex;
flex-direction: row;
background-color: white;
padding: 20px 20px 20px 20px;
justify-content: space-evenly;
gap: 10px;
}
.Text1 {
width: 100px;
white-space: nowrap;
}
.Text2 {
text-align: left;
width: 400px;
text-overflow: ellipsis; /* new line */
overflow: hidden; /* new line */
white-space: nowrap; /* new line */
}
.Text3 {
width: 100px;
}
<div class="Container">
<div class="Text1">26 Dec 22</div>
<div class="Text2">Lorem ipsum dolor sit amet</div>
<div class="Text3">128K</div>
</div>

Related

Rules defining which div will shrink when both have overflow hidden

I am designing some cards in React. The sizing of different elements needs to be dynamic as the title and description can vary in length.
The basic structure of the card is (vertically) Title, info, description
<div className={styles.sample}>
<div className={styles.textContainer}>
<h1 className={styles.title}>{title}</h1>
<div className={styles.info}>
<span>
By: {author}
</span>
</div>
<div className={styles.description}>
<span>{description}</span>
</div>
</div>
<ButtonPrimary
classes={styles.button}
onClick={() => function}
text="READ ARTICLE"
/>
</div>
Both my .title and .description css class have overflow: hidden. This is always causing the title block to hide content before the description block.
What I want is for my title block to occupy at most 2 lines of content before hiding any extra content. Sometime the title will be short and in these cases the title should only occupy one line.
My scss
.sample {
display: flex;
flex-direction: column;
height: 100%;
justify-content: space-between;
.textContainer {
display: flex;
flex-direction: column;
overflow-y: hidden;
margin-bottom: 25px;
.title {
#include font-rubik(26px, $black, 700);
line-height: 30px;
vertical-align: top;
height: 60px;
// min-height: 30px;
height: fit-content;
overflow:hidden;
white-space: normal;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
}
.info {
#include font-rubik(12px, #B3B3B3, 300);
margin-bottom: 11px
}
.description {
#include font-rubik(14px, $black, 400);
overflow: hidden;
}
}
}

How to prevent CSS Grid blowout so that text-overflow ellipsis will work

I am having some issues with CSS Grid "blow out" which is causing my text property text-overflow: ellipsis to not work.
I have seen many posts on this, and tried many things, but just don't understand what I have wrong. I can reproduce in a simple example.
In my case, I am using a third part component, where I want to put my UI inside one of it's elements.
For example, below the element third-party-container is the third part component, and my UI is contained in my-containerm where I wish to completely fill the third-party-container
HTML
<div id='third-party-container'>
<div id='my-container'>
<div id='s1'>S1</div>
<div id='s2'>S2</div>
<div id='s3'>aaaaaaaabbbbbbbbbbbccccccccccccccccccccccccccddddddddddddddd</div>
</div>
</div>
CSS
#third-party-container {
height: 40px;
width: 140px;
background: orange;
}
#my-container {
background: yellow;
height: 100%;
width: 100%;
display:grid;
align-items: center;
justify-items: left;
grid-template-columns: min-content 13px minmax(0, 1fr);
grid-template-rows: 1fr;
column-gap: 2px;
white-space: nowrap;
}
#s1 {
background: red;
grid-row: 1;
justify-items: left;
grid-column: 1;
align-items: stretch;
}
#s2{
background: green;
grid-row: 1;
overflow: hidden;
grid-column: 2;
}
#s3 {
background: pink;
grid-row: 1;
justify-items: left;
display: grid;
align-items: center;
grid-column: 3;
min-width: 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
Also available at this Plunkr
So in my-container I have a single row, and 3 columns. The first two columns have quite small widths. The first columns may vary slightly, but will always be quite small. The 2nd is just fixed.
The third column s3 (coloured pink) is the one that may sometimes have longer text than can fit in the containers. However, this is what I see in the above example...
When I look at this in dev tools, I can see the s3 is "blowing out", ie not being contained within its container.
I had got around this before by using the minmax(0, 1fr) but it is not working here.
The outer container has a fixed width, and my-container is 100% of this.
What am I doing wrong and how I can get this to work?
The issue is the use of display:grid on #s3. Remove it and also add width:100%
#third-party-container {
height: 40px;
width: 140px;
background: orange;
}
#my-container {
background: yellow;
height: 100%;
display: grid;
align-items: center;
justify-items: left;
grid-template-columns: min-content 13px minmax(0, 1fr);
grid-template-rows: 1fr;
column-gap: 2px;
white-space: nowrap;
}
#s1 {
background: red;
}
#s2 {
background: green;
overflow: hidden;
}
#s3 {
background: pink;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
width:100%;
}
<div id='third-party-container'>
<div id='my-container'>
<div id='s1'>S1</div>
<div id='s2'>S2</div>
<div id='s3'>aaaaaaaabbbbbbbbbbbccccccccccccccccccccccccccddddddddddddddd</div>
</div>
</div>

Span at the bottom of Parent div

I have a flex container in which I have two boxes which are side by side (and collapse in one column when the screen is too small).
Now, when boxes are side by side, I've set that they have the same height, like in the following image.
Now, what I want to achieve is to put the EDIT button of both boxes at the bottom (this means that only the EDIT button of the box with less content will need to move).
I've searched, but the solution are to use position absolute, because one of the two boxes won't need it, and if I put position absolute on both EDIT button, the box on the right will have less height because it won't count the EDIT button anymore.
I tried to play with flex, but I rather not set the boxes as display flex.
There may be some solution with Jquery, I've read something about it, but it was just something like "You could achieve that with Jquery!" but.. I honestly don't know how.
#parent {
flex-flow: row wrap;
display: flex;
align-items: stretch;
}
.box {
margin: 10px;
padding: 15px;
flex: 0 1 calc(50% - 50px);
}
.box:last-of-type {
background-color: green;
}
.box:first-of-type {
background-color: red;
}
.cool-form {
display: flex;
flex-direction: column;
}
.button-container {
display: block;
margin-left: 5px;
margin-top: auto;
align-self: center;
}
.button {
background-color: white;
display: inline-block;
width: 120px;
height: 48px;
line-height: 48px;
border: 1px solid black;
text-align: center;
cursor: pointer;
}
<div id="parent">
<div class="box">
<form class="cool-form">
<h1>Box on left</h1>
<p>This is a shorter box</p>
<span class="button-container">
<span class="button">EDIT</span>
</span>
</form>
</div>
<div class="box">
<form class="cool-form">
<h1>Box on right</h1>
<p>This is</p>
<p>a</p>
<p>bigger</p>
<p>waaay bigger</p>
<p>Box</p>
<span class="button-container">
<span class="button">EDIT</span>
</span>
</form>
</div>
</div>
Adding flexbox to these divs (using flex-direction:column) seems minimally invasive (which was, perhaps a concern).
.box {
display: flex;
flex-direction: column;
}
Then you can give the button container margin-top:auto and it's auomatically pushed to the bottom.
Then it's just a matter of aligning it horizontally/centrally
.button-container {
margin-top: auto;
align-self: center;
}
#parent {
flex-flow: row wrap;
display: flex;
align-items: stretch;
}
.box {
margin: 10px;
padding: 15px;
flex: 0 1 calc(50% - 50px);
display: flex;
flex-direction: column;
}
.box:last-of-type {
background-color: green;
}
.box:first-of-type {
background-color: red;
}
.button-container {
display: block;
margin-left: 5px;
margin-top: auto;
align-self: center;
}
.button {
background-color: white;
display: inline-block;
width: 120px;
height: 48px;
line-height: 48px;
border: 1px solid black;
text-align: center;
cursor: pointer;
}
<div id="parent">
<div class="box">
<h1>Box on left</h1>
<p>This is a shorter box</p>
<span class="button-container">
<span class="button">EDIT</span>
</span>
</div>
<div class="box">
<h1>Box on right</h1>
<p>This is</p>
<p>a</p>
<p>bigger</p>
<p>waaay bigger</p>
<p>Box</p>
<span class="button-container">
<span class="button">EDIT</span>
</span>
</div>
</div>

Dropdown menu scroll bar issue

I want to make a dropdown list looking under the list but it automatically creates scroll bar and inproper height for the list.
Though there are 5 elements on the list, it just shows one and the other ones are not shown because of the inproper height, I guess.
This is the css codes;
NOTE: Please inform me if anything is needed
The containing element probably has the default value (overflow: auto), so it will create a scroll bar when the content is bigger than it's size.
Just make sure your containing element has overflow: visible.
.div1 {
overflow: hidden;
}
.div2 {
overflow: visible;
}
.div3 {
overflow: scroll;
}
.div4 {
overflow: auto;
}
.inner {
height: 200px;
width: 50px;
background-color: red;
color: white;
}
body {
display: flex;
flex-direction: row;
justify-content: space-around;
}
.space {
width: 80px;
height: 100px;
border: 1px solid black;
background-color: blue;
}
<div class="space div1">
<div class="inner">hidden</div>
</div>
<div class="space div2">
<div class="inner">visible</div>
</div>
<div class="space div3">
<div class="inner">scroll</div>
</div>
<div class="space div4">
<div class="inner">auto</div>
</div>

How can you use flexbox to vertically center text in a fixed-height div without overflowing above?

The first line of text in the third .box is raised above the top of the div and cut off. I would like it to appear the same as the second box (well actually ideally like the second box plus a ...).
Can this be done with flexbox?
If not, can it be done with other CSS?
If not, what's the best way to do it with JS?
And on a separate note, why isn't the first box's text center-aligned?
http://codepen.io/loren/pen/ojxORN
<div class='box'>
one line of text
</div>
<div class='box'>
two lines of text lorem ipsum
</div>
<div class='box'>
thre lines of text lorem ipsum sin dolor whatever etc
</div>
.box
height 40px
font-size 16px
width 150px
border 1px solid black
margin-bottom 40px
display flex
align-items center
text-align center
overflow-y hidden
When align-self computes to center, the flex item is centered in the cross axis within the line.
That's problematic if the flex item is bigger than the flex container, because it will overflow it both from above and below. And in case overflow is not visible, the upper part will be cut.
To avoid this, you can center by using auto margins:
.box {
display: flex;
height: 40px;
width: 150px;
overflow: auto;
border: 1px solid black;
margin-bottom: 20px;
font-size: 16px;
text-align: center;
}
.box > div {
margin: auto;
}
<div class='box'>
<div>one line of text</div>
</div>
<div class='box'>
<div>two lines of text lorem ipsum</div>
</div>
<div class='box'>
<div>thre lines of text lorem ipsum sin dolor whatever etc</div>
</div>
Note margin: auto needs to be added to each flex item. However, you can't select the anonymous flex item which wraps contiguous run of texts in the flex container. Therefore, I wrapped the text in div elements, which can be selected.
If you don't want to alter the HTML, you can use pseudo-elements.
.box {
display: flex;
flex-direction: column;
height: 40px;
width: 150px;
overflow: auto;
border: 1px solid black;
margin-bottom: 40px;
font-size: 16px;
text-align: center;
}
.box::before, .box::after {
content: '';
margin-top: auto;
}
<div class='box'>
one line of text
</div>
<div class='box'>
two lines of text lorem ipsum
</div>
<div class='box'>
thre lines of text lorem ipsum sin dolor whatever etc
</div>
Question 1/2
Yes! You can do it with flexbox:
.box {
/* Firefox */
display: -moz-flex;
-moz-justify-content: center;
-moz-align-items: center;
/* IE */
display: -ms-flex;
-ms-justify-content: center;
-ms-align-items: center;
/* Chrome | Safari */
display: -webkit-flex;
-webkit-justify-content: center;
-webkit-align-items: center;
/* Modern browsers */
display: flex;
justify-content: center;
align-items: center;
height: 40px;
width: 150px;
overflow: hidden;
border: 1px solid black;
margin-bottom: 40px;
font-size: 16px;
text-align: center;
}
.truncate {
white-space: nowrap;
overflow: hidden;
-ms-text-overflow: ellipsis; /* IE */
-o-text-overflow: ellipsis; /* Opera */
text-overflow: ellipsis; /* Other browsers */
}
<div class='box'>
<p class="truncate">one line of text<p>
</div>
<div class='box'>
<p class="truncate">two lines of text lorem ipsum<p>
</div>
<div class='box'>
<p class="truncate">thre lines of text lorem ipsum sin dolor whatever etc<p>
</div>
If you like to use Sass/SCSS and Compass your stylesheet will be like:
#import 'compass';
.box {
#include flexbox((
display: flex,
justify-content: center,
align-items: center
), 1 2 3);
height: 40px;
width: 150px;
overflow: hidden;
border: 1px solid black;
margin-bottom: 40px;
font-size: 16px;
text-align: center;
}
.truncate {
#include ellipsis();
}
Question 3
Javascript is required only if you want to truncate your text in multiple lines (on second/third line and so on..)
So if it's a single line, CSS is the right way. Otherwise use Succinct
Question 4
You don't see text centered because your .box has display: flex property. Remove it and you will see it centered
You can center the single line of text by simply wrapping it in a <span> and giving it a width.
<div class='box'>
<span>one line of text</span>
</div>
div.box > span { width: 100%; }
OR, you can apply the justify-content property to the flex container:
.box {
display: flex;
align-items: center; /* center vertically */
justify-content: center; /* center horizontally */
height: 40px;
font-size: 16px;
width: 150px;
border: 1px solid black;
margin-bottom: 40px;
text-align: center;
overflow-y: hidden;
}
In terms of adding ellipsis ("...") to overflow text, yes it's possible, but it's tricky with multi-line text.
CSS has a text-overflow property that takes several values, including ellipsis. Unfortunately, ellipsis only works on single-line text.
CSS doesn't provide a standard way to apply ellipsis to multi-line text. There are various workarounds, but they can be hit and miss depending on the method and the situation. See my answer here for more details: Applying Ellipsis to Multiline Text

Categories

Resources