This question already has answers here:
Keep the middle item centered when side items have different widths
(12 answers)
Closed 3 years ago.
I have a three divs within a flex div. I'm trying to figure out how to prevent the middle div from moving/changing position when the text in the first or last div changes.
.container {
display: flex;
justify-content: space-between;
}
<div class="container">
<div clas="div1">Text1</div>
<div class="div2">Text2</div>
<div class="div3">Text3</div>
</div>
If Text3 is changed to something different, for example, AnotherText3, note that the center div (Text2) also moves (shifts to the left), I would like Text2 to stay centered and not move.
Text3 could be long in which case it should occupy the space between Text2 and Text3 (while still keeping Text2 in the center) and be truncated when there is no more space left.
Here the link to my jsfiddle.
Try adding this to your code:
.container > div {
width: 33%;
}
Maybe you have to do some other css addings to prevent wrapping of the last div if there are some margins, but this way the content will not expand width of your div.
You can set the flex box's widths to be fixed, don't grow and don't shrink, and use white-space, overflow, and text-overflow properties to truncate the text:
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
For example:
.container {
display: flex;
justify-content: space-between;
}
.div1 {
flex-grow: 0; /* flex-grow: 0 means don't grow, 1 means grow*/
flex-shrink: 0; /* flex-shrink: 0 means don't shrink, 1 means shrink */
flex-basis: 300px; /* Width of the flex box stays 300px */
}
.div2 {
flex-grow: 0;
flex-shrink: 0;
flex-basis: 300px;
/* Truncate text */
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.div3 {
flex-grow: 0;
flex-shrink: 0;
flex-basis: 300px;
}
This 100% expected. Because width of children is not specified, browser checks the remaining space around them and sets its position. Simplest solution would be adding a width to children elements. Like so:
<div class="container">
<div class="div div1">
Text1
</div>
<div class="div div2">
Text2
</div>
<div class="div div3">
I am a super long text here. I am a super long text here. I am a super long text here. I am a super long text here.
</div>
</div>
.container {
display: flex;
}
.div {
flex-basis: 33.3333%;
}
.div1 {}
.div2 {
text-align: center;
}
.div3 {
text-align: right;
}
You can use CSS Grid on the .container like this to achieve the following layout:
<div class="container">
<div class="left-div">
<div clas="div1"> Text1 </div>
</div>
<div class="div2 center-div"> Text2 </div>
<div class="right-div">
<div clas="div3"> Text4 </div>
</div>
</div>
.container {
display: grid;
grid-template-columns: 2fr 1fr 2fr;
}
.left-div {
display: flex;
justify-content: flex-start;
}
.right-div {
display: flex;
justify-content: flex-end;
}
.center-div {
display: flex;
justify-content: center
}
Working Screenshot:
Two of my go to methods for getting centered content
using position relative:
<div class="container">
<div class="div2"> Text1 </div>
</div>
.div {
position:relative;
Left:50%;
}
using display flex property:
<div class="container">
<div clas="div1"> Text1 </div>
<div class="div2"> Text2 </div>
<div class="div3"> Text3 </div>
</div>
.container {
display: flex;
}
.div1 {
text-align: center;
}
Related
In the first picture, the circled areas are two inline-block div elements.
Currently when i make the browser window smaller the second div element jumps under the first one as expected.
What i want is to make the text inside the second div element to wrap when i make the window smaller and to keep the space under the first div element empty.
You could use Flexbox :)
div {
display: flex;
flex-flow: row wrap;
}
div>div:first-child {
display: flex;
flex-direction: column;
margin-right: 20px;
}
div>div>div:last-child {
background: orange;
}
div>div:last-child p {
margin: 0;
}
<div>
<div>
<div>#15</div>
<div>OPEN</div>
</div>
<div>
<p>TODO: add a destination for Hello, User hyperlink</p>
</div>
</div>
Example on Codepen
Thank for your answers. Finally i got the result i wanted with this:
<div id="big">
<div id="left">
<div>#15</div>
<div>OPEN</div>
</div>
<div id="right">
<p>TODO: add a destination for Hello, User hyperlink</p>
</div>
</div>
<style>
#big {
display: flex;
}
#left {
flex-shrink: 0;
width:100px;
display: flex;
flex-direction: column;
}
div, p {
margin:0;
}
</style>
It's simple, just add this CSS property:
word-wrap: break-word;
/* To break the text */
Also, you are not supposed to use inline-blocks for this purpose.
Instead, use flexbox or grid.
Example:
<section>
<div class="details">
</div>
<div class="description">
<p> Text </p>
</div>
</section>
section {
display: grid;
grid-template-columns: 250px 1fr;
}
.details {
grid-column: 1 / 2;
}
.description {
width: 100%;
grid-column: 2 / 3;
}
.description p {
word-wrap: break-word; /* Will break the text*/
}
I have a div with two contents: an image (on top) and text (on bottom).
Height of image plus height of the text is bigger than the height of the parent.
I want an image to shrink, so the whole text will be visible.
So - now it looks like this:
And I want it to look like this:
How to achieve this?
I tried it with display: flex and flex-shrink or flex-grow, but it's not working.
Solution with flex will be much appreciated :)
Here's a codepen with an example:
https://codepen.io/anon/pen/zQXyLb
And here's code used:
<html>
<head></head>
<body style="background: yellow;">
<div style="
width: 150px;
height: 150px;
background: #ddd;
overflow: hidden;
display: flex;
flex-direction: column;
">
<div>
<img src="https://emojipedia-us.s3.dualstack.us-west-1.amazonaws.com/thumbs/120/apple/198/skull_1f480.png">
</div>
<div>
<div>Here i have some text</div>
<div>which is multiline</div>
<div>and it should make</div>
<div>the skull smaller</div>
</div>
</div>
</body>
</html>
Instead of img tag try div with background-image.
flex: is short form of: flex-grow, flex-shrink, flex-basis.
0 0 auto means that element will take just as much space as needed.
1 1 auto means that element will take all available space — so image takes box size minus text size. And text is always visible.
.box {
display: flex;
flex-direction: column;
margin-bottom: 20px;
width: 150px;
height: 150px;
background: #ddd;
}
.image {
flex: 1 1 auto;
background: url(https://emojipedia-us.s3.dualstack.us-west-1.amazonaws.com/thumbs/120/apple/198/skull_1f480.png) 0 0 no-repeat;
background-size: contain;
}
.text {
flex: 0 0 auto;
}
<div class="box">
<div class="image"></div>
<div class="text">
<div>Here I have some text</div>
<div>which is multiline</div>
<div>and it should make</div>
<div>the skull smaller</div>
</div>
</div>
<div class="box">
<div class="image"></div>
<div class="text">
<div>Here I have small text</div>
</div>
</div>
You can also keep image in the HTMl if you inbricate flex boxes to allow img container to shrink and img understand max-height:100%;
body {
background-color: #a3d5d3;
}
[class],
[class]>div {
display: flex;
flex-direction: column;
overflow: hidden;
}
img {
max-height: 100%;
margin-right: auto;
}
[class]>div[id] {
flex-grow: 1;
flex-shrink: 0;
}
<div class style="
width: 150px;
height: 150px;
background: #ddd;
">
<div>
<img src="https://emojipedia-us.s3.dualstack.us-west-1.amazonaws.com/thumbs/120/apple/198/skull_1f480.png">
</div>
<div id>
<div>Here i have some text</div>
<div>which is multiline</div>
<div>and it should make</div>
<div>the skull smaller</div>
</div>
</div>
Resize the image using css.
img{
max-width:50px;
}
The above code should make the image flexible and allow it to be smaller.
Also you can put variable height to the parent div, i.e.
<div style="
width: 150px;
max-height: 250px; //added this part
background: #ddd;
overflow: hidden;
display: flex;
flex-direction: column;
">
But this way the image will stay large but the parent's height will increase. Allowing the text to appear in the enlarged div.
I'm making a card. The card has two stacked divs. The top part of the card has an image and the bottom part is just text. What do I do to make sure the top and bottom divs have the same height? I know i could define heights of the divs in pixels, but I don't want to do that because I don't know much text will be on the other cards.
.card {
display: flex;
flex-direction: column;
flex: 1;
}
.cardTop, .cardBottom {
border: 1px solid;
}
img {
display: block;
}
<div class="card">
<div class="cardTop">
<img src="https://placehold.it/200x100" alt="">
</div>
<div class="cardBottom">
<p>text of the card goes here</p>
</div>
</div>
Just use the styling of the flex-box like this :
.card {
display: flex;
flex: 1;
flex-direction: column;
flex-wrap: nowrap;
padding: 5px;
height: 15em; //chose what you want
width: 15em; //chose what you want
}
.card > div {
flex: 1 1 50%;
overflow: hidden;
}
Your 2 divs will split at 50% height of your global .card container height by doing this.
I made a quick example online : https://stackblitz.com/edit/angular-pechib
so I have X divs and I want to put 2 divs in one row next to each other. If the screen size width is below n px there should be 1 div per row.
Currently I have this
#container {
display: flex;
}
.box {
width: 50px;
background: red;
}
#media(max-width: 300px) {
#container {
display: block;
}
}
<div id="container">
<div class="box"> 1 </div>
<div class="box"> 2</div>
<div class="box"> 3 </div>
<div class="box"> 4 </div>
</div>
How can I limit the flex box to two divs per row?
Add 50% width on .box and flex-wrap:wrap on the container
Additionally, what you did by changing display: flex to block was not required. Just change the .box elements width to 100%
#container {
display: flex;
flex-wrap: wrap;
}
.box {
width: 50%;
background: red;
}
#media(max-width: 300px) {
.box {
width: 100%;
}
}
<div id="container">
<div class="box"> 1 </div>
<div class="box"> 2</div>
<div class="box"> 3 </div>
<div class="box"> 4 </div>
</div>
Just add a property in your container class like
.container {
display: flex;
flex-wrap: wrap;
}
And in box class just specify the width of your box as 50% like
.box {
width: 50%;
background: red;
}
That should do the trick.
Flex will do a trick for you. flex-wrap: wrap for #container will make children wrap when necessary. .box with 50% and after breakpoint 100%.`
According to MDN:
The CSS flex-wrap property specifies whether flex items are forced into a single line or can be wrapped onto multiple lines. If wrapping is allowed, this property also enables you to control the direction in which lines are stacked.
If you are new to flexbox I recommend this guide.
Snippet
#container {
display: flex;
flex-wrap: wrap;
}
.box {
width: 50%;
background: red;
}
#media(max-width: 300px) {
.box {
width: 100%;
}
}
<div id="container">
<div class="box"> 1 </div>
<div class="box"> 2 </div>
<div class="box"> 3 </div>
<div class="box"> 4 </div>
</div>
Following to this answer, I am trying to create a perfect height for my content, But the content height is overflowing instead of getting a scroll over content.
I have created a fiddle for this scenario. Please help me fix my content height such a way that top content and always visible and scroll-able downward.
fiddle
html,
body {
height: 100%;
margin: 0
}
.box {
display: flex;
flex-flow: column;
height: 100%;
}
.box .row {
border: 1px dotted grey;
}
.box .row.header {
flex: 0 1 auto;
}
.box .row.content {
display: flex;
flex-flow: column;
flex: 1 1 auto;
overflow-y: auto;
justify-content: center;
align-items: center;
}
.data {
width: 80%;
min-height: 400px;
}
.box .row.footer {
flex: 0 1 40px;
}
HTML.
<head>
<link href="./test.css" rel="stylesheet">
</head>
<body>
<div class="box">
<div class="row header">
<p>
<b>header</b>
<br />
<br />(sized to content)</p>
</div>
<div class="row content">
<div class="data">
invisible box1
</div>
<div class="data">
visible box2
</div>
<div class="data">
visible box3
</div>
<p>
<b>Bottom Box is visible with scroll.</b> (fills remaining space)
</p>
</div>
<div class="row footer">
<p>
<b>footer</b> (fixed height)</p>
</div>
</div>
</body>
</html>
The issue you encounter is caused by justify-content: center in the .box .row.content rule.
Remove it and your text will overflow properly.
.box .row.content {
display: flex;
flex-flow: column;
flex: 1 1 auto;
overflow-y: auto;
/*justify-content: center; removed */
align-items: center;
}
Updated fiddle
This is the default behavior for justify-content: center, where, on a flex column container, when the content overflow, it will overflow both at its top and bottom.
Read more here, where you find resources and a workaround:
How to use safe center with flexbox?
I think overflow: scroll; will fix your problem.