Flex wrapping causes border to have padding - html

I want to display 2 separate strings in-line when the screen is big enough. But when the width gets smaller, I want the 2nd string to move down. I'm currently using flex wrap, but it's adding extra padding to the right when the 2nd string does the wrap. Is there a way to get rid of this padding?
Code: https://jsfiddle.net/Dirst/1ep2tq9y/61/
<div class="entire">
<div class="stringA">First string of text.</div>
<div> Second string of text.</div>
</div>
.entire{
border-style: solid;
display: flex;
flex-wrap: wrap;
width: fit-content;
}
.stringA{
color: green;
padding-right: 5px;
}
I also tried adjusting the width of the containers (e.g., using max-width / min-width / fit-content), but it prevents the inline state from occurring.
I also tried using display inline / inline block, but they cause the borders to split up into two when the screen width becomes small:
https://jsfiddle.net/Dirst/hfexz7od/51/
<div class="entire">
<div class="stringA">First string of text.</div>
<div class="stringB">Second string of text.</div>
</div>
.entire{
/*border: 1px solid black;*/
border-style: solid;
display: inline;
}
.stringA{
display: inline-block;
padding-right: 5px;
/*width: fit-content;*/
}
.stringB{
display: inline-block;
/*width: fit-content;*/
padding-right: 5px;
}
I would like to only have the border wrap around both strings as one rectangle but without the right-padding caused by the wrap.

You should use span instead of div for display: inline-block;
Here is the full of implementation
.entire {
border-style: solid;
display: inline-block;
}
.stringA {
color: green;
padding-right: 5px;
}
<div class="entire">
<span class="stringA">First string of text.</span>
<span> Second string of text.</span>
</div>
You can try it out in this sanbox https://jsfiddle.net/tmj7eab6/

Related

Trying to make div height based on max content with flexbox and css font-size is ruining flex: auto

I have a flex container with multiple flex items, 2 of which I need to flex grow based on the text so all divs space out the same way.
I was able to accomplish this like this:
<div class="outer product-grid">
<div class="inner product-component">
<a class="image"><img class="product-image" /></a>
<a class="upper-text title">
Short Upper Text
</a>
<div class="lower-text author">
Short Lower Text
</div>
<h5 class="price"> <span>price</span> </h5>
</div>
<div class="inner">
<a class="image"><img class="product-image" /></a>
<a class="upper-text">
Long Upper Text - Long Upper Text
</a>
<div class="lower-text">
Long Lower Text - Long Lower Text
</div>
<h5 class="price"> price </h5>
</div>
<div class="inner">
<a class="image"><img class="product-image" /></a>
<a class="upper-text">
Even Longer Upper Text - Even Longer Upper Text
</a>
<div class="lower-text">
Even Longer Lower Text - Even Longer Lower Text
</div>
<h5 class="price"> price </h5>
</div>
</div>
SCSS
.outer {
display: flex;
flex: wrap;
.inner {
border: 5px solid yellow;
display: flex;
text-align: center;
margin-right: 1em;
margin-bottom: 1.5em;
width: 200px;
flex-direction: column;
font-size: 1.00em;
a.image{
border: 5px solid orange;
img {
width: em(160px);
height: em(210px);
}
}
a.upper-text {
border: 5px solid red;
flex: auto;
margin: 0.2em auto;
line-height: normal;
}
.lower-text {
border: 5px solid green;
flex: auto;
}
}
}
My upper-text and lower-text need to be different sizes. When I put a font-size into either of those classes, I lose the whole flex grow.
You can try on my codepen https://codepen.io/mxdavis/pen/KxxmKE by inserting font-size: 20px; to between line 24 and 25 (in the a.upper-text class) and you will see the red border no longer ends at the same point like it does when the font is not adjusted. https://codepen.io/mxdavis/pen/dqqzMy
I need the even sized boxes, and the adjusted font size. Flex seems to be the easiest route since upper-text and lower-text cannot be predicted.
Any advice is greatly appreciated.
Thanks!
Update: I realize now if I play with the text sizes and don't make upper and lower texts equal even my first code snippet doesn't work, which is probably why a font increase is throwing it off. Is there a way to accomplish this or should I just set a fixed height and then click to reveal more? https://codepen.io/mxdavis/pen/KxxedE
I was able to accomplish this (for the most part) using flex and grid together.
I still have to guestimate a max template row for unpredictable text but at least I can guarantee the starting points with this.
https://codepen.io/mxdavis/pen/KxxedE
Here's the new css with the .inner now using display: grid instead of flex.
.outer {
display: flex;
flex-flow: row wrap;
.inner {
border: 5px solid yellow;
display: grid;
grid-template-rows: 210px minmax(max-content, 3fr) minmax(max-content, 2fr) 30px;
grid-row-gap: 5px;
text-align: center;
margin-right: 1em;
margin-bottom: 1.5em;
width: 150px;
font-size: 1.00em;
a.image{
border: 5px solid orange;
img {
width: em(160px);
height: em(210px);
}
}
a.upper-text {
border: 5px solid red;
line-height: normal;
}
.lower-text {
border: 5px solid green;
}
.price {
border: 5px solid blue;
margin: 0;
}
}
}
I still would be interested to see how to rely ONLY on the most content for that row, without using tables.

How to make one of vertically aligned children shrink to width set by other children?

Question
There is an inline container with 2 vertically stacked children. Pictured below:
The top green child should shrink it's width to the width of the bottom orange child, wrapping the text inside itself. The desired layout pictured below:
Question: How can it be done with CSS alone?
Other cases
Orange container wider than the green one (picture below). Green stays at it's natural maximum width. Note that even if the solution woulds stretch the green box to 100%, implementing the target solution would be easy by adding an extra container for the green box and then centering the green box inside it.
Orange box wider than the maxium possible width of the parent (picture below). Orange should start wrapping.
Notes
The content of the children is dynamic - the solution needs to work with children of variable width.
The parent is inline - it's width is not 100%, but rather the width of it's widest child.
Browser support is of no importance. Solutions can use even CSS Grid.
Code
Fiddle
http://jsfiddle.net/twfky2cr/24/
HTML
<div class="container">
<div class="fitChild">
Some long text that I would like to wrap to fit the container size
set by the orange box
</div>
<div class="fullWidthChild">
This one should set the container size
</div>
</div>
CSS
.container {
display: inline-flex;
flex-direction: column;
flex-wrap: nowrap;
align-items: center;
background-color: black;
}
.container,
.fitChild,
.fullWidthChild {
padding: 10px;
}
.fitChild {
color: white;
background-color: green;;
}
.fullWidthChild {
margin-top: 10px;
background-color: orange;
}
I have a partial solution for You.
http://jsfiddle.net/twfky2cr/166/
I'm using display: table and width:1px for cells.
<div class="table">
<div class="row">
<span class="cell wrap">
Some long text that I would like to wrap to fit the container size
</span>
</div>
<div class="row">
<span class="cell nowrap">
This one should set the container size
</span>
</div>
</div>
.table {
background-color: Black;
display: table;
padding: 1rem;
}
.row {
display: table-row;
}
.cell {
padding: 1rem;
display: table-cell;
width: 1px;
}
.wrap {
color: white;
background-color: Green;
white-space: wrap;
}
.nowrap {
background-color: Orange;
white-space: nowrap;
}
Checkout this fiddle here http://jsfiddle.net/kjr9aghp/
$(document).ready(function() {
$('.fitChild').width($('.fullWidthChild').width());
});
.container {
display: inline-flex;
flex-direction: column;
flex-wrap: nowrap;
align-items: center;
background-color: black;
}
.container,
.fitChild,
.fullWidthChild {
padding: 10px;
width: 100% !important;
}
.mainwrapper{
max-width:50%;
}
.fitChild {
color: white;
background-color: green;;
}
.fullWidthChild {
margin-top: 10px;
background-color: orange;
}
<div class="container">
<div class="mainwrapper">
<div class="fitChild">
Some long text that I would like to wrap to fit
the container size set by the orange box
</div>
<div class="fullWidthChild">
This one should set the container size
</div>
</div>
</div>

Flexbox not expanding with content

I am trying to build a basic messenger view on a mobile screen. So there is a header at the top, a scrollable list of messages in the middle, and a bar at the bottom with a textarea and button to send a new message.
I am using an autosize plugin to makes the textarea expand as a user types their message. The problem is that as it changes the height property, it will start to overflow the height of the container that it is in, instead of that container expanding to take up more room.
A working sample is here: https://codepen.io/jwynveen/pen/RJdWLB?editors=1100#0
#container {
width: 412px;
height: 660px;
border: solid 2px black;
display: flex;
flex-direction: column;
}
#container h1 {
border-bottom: solid 1px gray;
margin-bottom: 0;
padding: 1rem;
}
#container #message-list {
flex-grow: 1;
flex-shrink: 1;
overflow-y: scroll;
}
#container #message-list .message {
margin: 1rem;
padding: 1rem;
border: solid 1px gray;
}
#container #message-input-bar {
display: block;
}
#container #message-input {
padding: 1rem;
display: flex;
border-top: solid 2px red;
}
#container #message-input textarea {
flex-grow: 1;
}
<html>
<div id="container">
<h1>My Header</h1>
<div id="message-list">
<div class="message">This is a dummy message.</div>
<div class="message">This is a dummy message.</div>
</div>
<div id="message-input">
<textarea style="height: 100px"></textarea>
<button id="send">Send</button>
</div>
</div>
</html>
If there are no messages in the center area, the textarea makes its container expand as expected. But once the center area has enough to scroll, the textarea starts to overflow.
Found a fix based on the suggestion by #vaishali-kapadia. I wrapped the #message-input with another div so that the added div is display:block and the existing one maintains the flexbox layout.
Changed from:
<div id="message-input">
<textarea style="height: 100px"></textarea>
<button id="send">Send</button>
</div>
To:
<div id="message-input-bar">
<div id="message-input">
<textarea style="height: 100px"></textarea>
<button id="send">Send</button>
</div>
</div>
With the added CSS (though not necessary since the div is display:block by default):
#message-input-bar {
display:block;
}
Solution 1
You have applied manual height to container. so it stops there after reaching that particular height.
Instead apply height: auto; so that container can expand as per the content
See this codepen -
https://codepen.io/vaishalik3/pen/QxoyMd?editors=1100#0
Solution 2 -
In case you want scrollbar as it is.
Apply display: block; instead of flex to #message-input
width: 100%; or as per your need to textarea
See this codepen - https://codepen.io/vaishalik3/pen/ERMPLd?editors=1100#0
Solution 3
Apply display: grid; to .container
display: flex; to #message-input
See this codepen - https://codepen.io/vaishalik3/pen/RJdqzq?editors=1100#0
Hope this helps :)
Remove
style="height: 100px"
from your textarea and provide height:100% to CSS.
https://codepen.io/anon/pen/ZRPQBX?editors=1100#0

Style two inline children under in one div so that the left children takes max width

I have one div holding on two inline children.
Something like..
<div>
<span> stuff </span>
<span> more stuff with variable length </span>
<div>
I want to make my second child to take whatever width it needs, and then the first child to be 100% - second child width. So that the two children are inline.
Is there a css/less only solution to this?
This might be doable using flex properties, but here is how I have gotten it working using float. Note that I changed the spans to divs - it might be possible to do this by setting spans to display: block, but I just feel this is cleaner. Also, an important aspect of this is the order of the divs; the float comes first, so that the "rest" section can base its content on what remains for it.
.outer {
width: 100%;
height: 300px;
}
.outer > div {
height: 100%;
}
.fill {
display: inline-block;
float: right;
background-color: green;
}
.rest {
overflow: hidden;
background-color: red;
}
<div class="outer">
<div class="fill">This will use up as much space as it needs to</div>
<div class="rest">Fill content</div>
</div>
Flexbox can do that:
div {
border: 1px solid grey;
display: flex;
margin-bottom: 10px;
}
span {
padding: 0 1em;
}
span:first-child {
flex: 1;
background: lightblue;
}
<div>
<span> stuff </span>
<span> more stuff with variable length </span>
</div>
<div>
<span> stuff </span>
<span> lots and lots of more stuff with variable length </span>
</div>
Try this https://jsfiddle.net/2Lzo9vfc/123/
HTML
<div>
<span class="span-1"> stuff </span>
<span class="span-2"> more stuff with variable length </span>
<div>
CSS
div {
display: table;
}
span {
border: 1px solid black;
padding: 5px;
display: table-cell;
}
.span-1 {
width: 100%;
}
.span-2 {
white-space: nowrap;
}

An inline-block div with "white-space: normal" exceeds the width of a parent with "white-space: nowrap"

I'm trying to position a few elements in a row, so that they all fit in the width of the container. To prevent them from word-wrapping I added "white-space: nowrap" to the parent, and added "white-space: normal" to the children to allow them to wrap the text (as desired).
The problem is that with this configuration the right most child sometimes exceeds the width of the parent.
HTML:
<div id="container">
<div class="child">
child 1
</div>
<div class="child">
child 2 text that might be long enough to wrap, but still exceed the parent
</div>
</div>
CSS:
#container {
white-space: nowrap;
width: 200px;
background: yellow;
border: 1px solid brown;
padding: 5px;
}
.child {
display: inline-block;
border: 2px solid red;
vertical-align: top;
white-space: normal;
}
http://jsfiddle.net/7e5TU/1/ (change the length of the text if the problem doesn't appear straight away).
I know that I can solve it with a table, and probably with a float on the left child, and "overflow: hidden" on the right, but I see no reason why this should not work.
Could anyone provide some insights? I'd mostly love to understand what in the box model causes this behavior. Thanks!
I agree with #hashem That's the expected behavior. By using white-space: nowrap; for the parent, you've collapsed the whitespaces between inline(-block) elements. white-space treats the children, not the element itself.
Well if you still need a fix you can add width to second child to make it fit inside container.
fiddle
e.g.
.child2
{
width: 70%;
}
If you are willing to use flexbox (https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Flexible_boxes) you could do it like this:
http://jsfiddle.net/7e5TU/6/
HTML
<div id="container">
<div class="child1">
child 1
</div><div class="child2">
child 2 text that might be long enough to wrap,
but still exceed the parent
</div>
</div>
CSS
#container {
width: 200px;
background: yellow;
border: 1px solid brown;
padding: 5px;
display: flex;
flex-direction: row
}
.child1, .child2 {
display: block;
border: 1px solid red;
vertical-align: top;
}
.child1 {
min-width: 50px;
}
You can do this with CSS display:table. This way no sizing details are needed.
It ensures the elements stay in a row and the text will wrap perfectly to the width of the parent container.
HTML
<div class='container'>
<div class='field'>
<div class='data'>
child 1
</div>
</div>
<div class='field'>
<div class='data'>
child 2 text that might be long enough to wrap, but still exceed the parent
</div>
</div>
</div>
CSS
.container {
display: inline-table;
border-spacing: 4px;
background: yellow; border: 1px solid brown;
padding: 5px;
}
.field {
display: table-cell;
}
.data {
border: 2px solid red;
padding: 3px;
}