Why does flex-grow not work next to wrapped sibling? [duplicate] - css

This question already has answers here:
Make container shrink-to-fit child elements as they wrap
(4 answers)
CSS when inline-block elements line-break, parent wrapper does not fit new width
(2 answers)
Closed 2 years ago.
I have a parent div with two child divs. The 2nd child is set to flex-grow. This works great, unless text has wrapped within the first column. In this case, it leaves a big empty space. Why is that, and can it be fixed?
This is the result I would Expect:
This is what is actually happening:
body {
font-family: sans-serif;
}
.parent {
display: flex;
max-width: 225px;
border: 1px solid green;
padding: 3px;
}
.parent > div {
border: 1px solid red;
pading: 3px;
padding: 2px;
}
.child2 {
flex-grow: 1;
display: flex;
align-items: center;
}
<div class="parent">
<div class="child1">
Short
</div>
<div class="child2">
+
</div>
</div>
<div class="parent">
<div class="child1">
Long NamedItem Thingamagig AnotherBigLong WordHere1234
</div>
<div class="child2">
+
</div>
</div>
<br>
Why is this space here ↑

Because you have a long string.
Add word-break: break-all to .parent > div and you'll understand what is happening.
You'll want to tweak .child1 with :
flex-grow: 0;
flex-shrink: 0;
flex-basis: 0;
or maybe
flex-grow: 0;
flex-shrink: 0;
flex-basis: 80%;
(I put this syntax because it works better with IE)

Related

How can I display an element to the left and other to the center using flexbox? [duplicate]

This question already has answers here:
Center one and right/left align other flexbox element
(11 answers)
Closed 1 year ago.
I want to accomplish something like the image, but without the third element, having one element fixed on the left and another in the center.
Is there an easier way without flexbox?
<div style="display: flex; justify-content: space-between">
<button>Left Header</button>
<button>middle</button>
</div>
Im sure there is a better way, but how about just hiding last column?
.container {
display: flex;
justify-content: space-between;
}
.item {
/* no important; just to visualize*/
width: 50px;
height: 50px;
background-color: blue;
border: 1px solid;
}
.item.last { /* :last-child doesn't work */
visibility: hidden;
background-color: red;
}
<div class="container">
<div class="item">A</div>
<div class="item">B</div>
<div class="item last">C</div>
<div>
You can use postion for first div and margin for the second div, like this
.container {
postion: relative;
}
.item {
width: 50px;
height: 50px;
background-color: teal;
border: 1px solid grey;
}
.item.one {
position: absolute;
}
.item.two {
margin: auto
}
<div class="container">
<div class="item one">A</div>
<div class="item two">B</div>
<div>
you can follow this code
<div style="display: flex; justify-content: space-between">
<button>Left Header</button>
<button style="margin-right: auto; margin-left: auto">middle</button>
</div>
You can just use flexbox "self-align".
Just check it here.

CSS technique for a horizontal line between two words [duplicate]

This question already has answers here:
Horizontal line between two words
(3 answers)
Closed 2 years ago.
I'm trying to add a horizontal line in the middle of two words. For example:
First word ----------------------------------- Second word
Is there a way to do that in CSS or flex?
I'm providing a solution using Flexbox because I didn't see one from the link in #Awais's comment above.
.container {
display: flex;
justify-content: space-between;
}
.container .middle {
margin: 0 5px;
transform: translateY(-50%);
border-bottom: 1px dashed;
flex-grow: 1;
}
<div class="container">
<span>First word</span>
<span class="middle"></span>
<span>Second word</span>
</div>
jsFiddle
Pure CSS Flex solution with minimal line of code.
.container {
display: flex;
}
.middle {
flex-grow: 1;
align-self: center;
}
.dash {
border-bottom: 1px dashed #aaa;
}
<div class="container">
<div>First word</div>
<div class="middle">
<div class="dash"></div>
</div>
<div>Second word</div>
</div>

pseudo-elements disappear in ie10 in combination with flexbox [duplicate]

This question already has an answer here:
ie10 and flexboxes? (nightmare)
(1 answer)
Closed 5 years ago.
I've a problem with the IE10 and flexbox. At the moment I use code like the snippet below.
The content of col 2 has got a variable length (with multiple small elements) and it should take the width it needs. I want to have to rows with a line between them. Therefor I added an pseudo-element, put it on the correct position via order with a width of 100%.
Chrome, Firefox, etc. can render this example, but if I run it with IE10, the pseudo-element disappears and the content of the second row moves itself to the first row.
Isn't the IE10 able to render pseudo-elements together with flexbox? Do you know a 'hack' to force this break?
/* Container */
.container {
display: flex;
flex-direction: row;
flex-wrap: wrap;
width: 200px;
}
.container:after {
background-color: #000;
content: '';
height: 2px;
margin: 5px 0;
order: 3;
width: 100%;
}
/* Child */
.child {
width: 100px;
border: 1px solid red;
box-sizing: border-box;
height: 50px;
line-height: 50px;
text-align: center;
}
/* Positioning of the childs */
.c1 {
order: 1
}
.c2 {
order: 2
}
.c3 {
order: 4
}
.c4 {
order: 5
}
<div class="container">
<div class="child c1">row 1 col 1</div>
<div class="child c2">row 1 col 2</div>
<div class="child c3">row 2 col 1</div>
<div class="child c4">row 2 col 2</div>
</div>
You need to add this styles for .container to work in IE10:
display: -ms-flexbox;
-ms-flex-wrap: wrap;

CSS Mask a line [duplicate]

This question already has answers here:
Line before and after title over image [duplicate]
(2 answers)
Closed 8 years ago.
Okay, i am not allowed to upload an image yet, so i will try to explain it this way:
I am trying to create this effect:
(update: text replaced with an image)
= : background div with background-image
the dashed line has a width of 100% and does not cross the name.
I don't want the line to go over the name, so
i am looking for some kind of mask that i can place
over the line.
Thanks in advance!
You could add the line with ::before and ::after pseudo-elements, styled with a border:
#wrapper {
display: flex;
border: 3px double;
/* You can add a backgound here */
}
#wrapper::before, #wrapper::after {
content: '';
flex-grow: 1;
border-top: 1px dashed;
align-self: center;
}
<div id="wrapper">
<div>Peter</div>
</div>
You can do this with flexbox.
Here is an example on codepen
.wrapper {
width: 400px;
display: flex;
flex-direction: row;
background: lightgray;
}
.wrapper div {
flex-grow: 1;
}
.line {
height: 1px;
background: black;
flex-grow: 1;
position: relative;
top: 7px;
}
<div class="wrapper">
<div class="line"></div>
<span>hello</span>
<div class="line"></div>
</div>
Try z-index in the css.
Let the upper layer get the larger number.

How to justify a single flexbox item (override justify-content) [duplicate]

This question already has answers here:
In CSS Flexbox, why are there no "justify-items" and "justify-self" properties?
(6 answers)
Closed 1 year ago.
You can override align-items with align-self for a flex item.
I am looking for a way to override justify-content for a flex item.
If you had a flexbox container with justify-content:flex-end, but you want the first item to be justify-content: flex-start, how could that be done?
There doesn't seem to be justify-self, but you can achieve similar result setting appropriate margin to auto¹. E. g. for flex-direction: row (default) you should set margin-right: auto to align the child to the left.
.container {
height: 100px;
border: solid 10px skyblue;
display: flex;
justify-content: flex-end;
}
.block {
width: 50px;
background: tomato;
}
.justify-start {
margin-right: auto;
}
<div class="container">
<div class="block justify-start">justify-start</div>
<div class="block"></div>
</div>
¹ This behaviour is defined by the Flexbox spec.
AFAIK there is no property for that in the specs, but here is a trick I’ve been using:
set the container element ( the one with display:flex ) to justify-content:space-around
Then add an extra element between the first and second item and set it to flex-grow:10 (or some other value that works with your setup)
Edit: if the items are tightly aligned it's a good idea to add flex-shrink: 10; to the extra element as well, so the layout will be properly responsive on smaller devices.
If you aren't actually restricted to keeping all of these elements as sibling nodes you can wrap the ones that go together in another default flex box, and have the container of both use space-between.
.space-between {
border: 1px solid red;
display: flex;
justify-content: space-between;
}
.default-flex {
border: 1px solid blue;
display: flex;
}
.child {
width: 100px;
height: 100px;
border: 1px solid;
}
<div class="space-between">
<div class="child">1</div>
<div class="default-flex">
<div class="child">2</div>
<div class="child">3</div>
<div class="child">4</div>
<div class="child">5</div>
</div>
</div>
Or if you were doing the same thing with flex-start and flex-end reversed you just swap the order of the default-flex container and lone child.
I solved a similar case by setting the inner item's style to margin: 0 auto.
Situation: My menu usually contains three buttons, in which case they need to be justify-content: space-between. But when there's only one button, it will now be center aligned instead of to the left.
For those situations where width of the items you do want to flex-end is known, you can set their flex to "0 0 ##px" and set the item you want to flex-start with flex:1
This will cause the pseudo flex-start item to fill the container, just format it to text-align:left or whatever.
To expand on Pavlo's answer https://stackoverflow.com/a/34063808/1069914, you can have multiple child items justify-content: flex-start in their behavior but have the last item justify-content: flex-end
.container {
height: 100px;
border: solid 10px skyblue;
display: flex;
justify-content: flex-end;
}
.container > *:not(:last-child) {
margin-right: 0;
margin-left: 0;
}
/* set the second to last-child */
.container > :nth-last-child(2) {
margin-right: auto;
margin-left: 0;
}
.block {
width: 50px;
background: tomato;
border: 1px solid black;
}
<div class="container">
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block" style="width:150px">I should be at the end of the flex container (i.e. justify-content: flex-end)</div>
</div>

Resources