Why do textareas not support flexible growth but contenteditables? - html

Using display: flex solves many problems, however, I can't create some auto-resizing textarea with it, but it works with <div contenteditable="true"></div>. I want to know why it doesn't work with textarea and if there's another way to solve this without using Javascript.
HTML with <div contenteditable="true">:
<div id="flex">
<div id="space"></div>
<div contenteditable="true"></div>
</div>
HTML with <textarea>:
<div id="flex">
<div id="space"></div>
<textarea></textarea>
</div>
CSS for both:
#flex {
display: flex;
height: 90vh;
background-color: #f99;
flex-direction: column;
}
#space {
background-color: #ff9;
flex: 2;
}
textarea,
div[contenteditable="true"] {
min-height: 30px;
max-height: 50vh;
overflow: auto;
resize: none;
}
Demo 1 — Demo 2

Related

Get rid of empty space on the right when word-wrap happens [duplicate]

This question already has answers here:
Make container shrink-to-fit child elements as they wrap
(4 answers)
Closed 1 year ago.
Below is simple example illustrating the problem. I have "Stackoverflow Stackoverflow" string and in first case it is displayed as a single line and in the second case word wrap happens. As you can see in the second case width of the div element is wider than a single "Stackoverflow" word. Is there a way to get rid of this empty space on the right? Resulting element has width 200px as specified per max-width but I want element to have actual width which is enough to fit it into 200px after word wrap.
body {
font-size: 30px;
}
.row {
margin-bottom: 10px;
}
.text-no-wrap {
background: yellowgreen;
white-space: nowrap;
display: inline-block;
}
.text-wrap {
max-width: 200px;
background: tomato;
white-space: normal;
display: inline-block;
}
<div class="row">
<div class="text-no-wrap">Stackoverflow Stackoverflow</div>
</div>
<div class="row">
<div class="text-wrap">Stackoverflow Stackoverflow</div>
</div>
You could try adding width: max-content; to the div's insde the .row
Note that width: max-content; isn't supported in Internet Explorer, but is supported on all other browsers.
Check the support of width: max-content; here.
I've added flex-direction: column; to the .row so the children of those
div's will appear underneath each other.
If you need display: flex; on the .row div, then This is the way to go. If you don't need display: flex; on the .row div, just simply remove it. And only use width: max-content; on the children;
body {
font-size: 30px;
}
.row {
display: flex;
flex-direction: column;
margin-bottom: 10px;
}
.text-no-wrap {
width: max-content;
background: yellowgreen;
}
.text-wrap {
width: max-content;
background: tomato;
}
<div class="row">
<div class="text-no-wrap">Stackoverflow1 Stackoverflow2</div>
</div>
<div class="row">
<div class="text-wrap">Stackoverflow1 Stackoverflow2</div>
<div class="text-wrap">Stackoverflow1 Stackoverflow2</div>
</div>
I believe this one is not a text-wrap issue. If you check the following code you will get multiple spaces in between wrapping text. This one is due to the
max-width: 200px;
specified for
.text-wrap.
body {
font-size: 30px;
}
.row {
display: flex;
margin-bottom: 10px;
}
.text-no-wrap {
background: yellowgreen;
white-space: nowrap;
}
.text-wrap {
max-width: 200px;
background: tomato;
white-space: normal;
}
<html>
<body>
<div class="row">
<div class="text-no-wrap">Stackoverflow Stackoverflow</div>
</div>
<div class="row">
<div class="text-wrap">Stackoverflow Stackoverflow testing text wrapping space issue</div>
</div>
</body>
</html>
Go through the demo you can see that after "testing text" multiple spaces is there.

Moving one HTML element before another while maintaining document flow

I am trying to create tab module such as this:
https://codepen.io/oknoblich/pen/tfjFl
However I am having difficulty since I can not change the HTML layout:
<div class="container">
<div class="tab-header">Tab1</div>
<div class="tab-content teal">Content1</div>
</div>
<div class="container current">
<div class="tab-header">Tab2</div>
<div class="tab-content teal">Content2</div>
</div>
The problems are that absolute positioning removes the content from the document flow, while other methods prevents the content from being the full width of the page.
I created two codepen's that illustrates the difficulties:
https://codepen.io/dwigt/pen/pOQpLd (absolute positioning removes content from document flow)
https://codepen.io/dwigt/pen/YOREOJ (flexbox layout does not take up full page-width)
Is there anyway I can replicate the tab functionality using this HTML layout and no javascript?
You can use display: contents (which is unfortunately not too well supported) combined with flexbox layout with wrap, set on the .wrapper element. This way, tab-headers and tab-contents will be treated equally, as if they were at the same level with one another - the .container elements are "transparent" to the layout engine. As a result, they will all be laid out with flexbox logic applied. Finally, to have the three tab headers display first, we set the order of the tab contents to some high value (here 100), and since we have flex wrap enabled, the content is then pushed downwards to a new line, below the headers. See example below:
.wrapper {
max-width: 300px;
display: flex;
flex-wrap: wrap;
height: 100%;
}
.container {
height: 50px;
display: contents;
}
.container .tab-header {
width: 100px;
max-width: 100%;
max-height: 100%;
flex: 1 0 33.33%;
}
.container .tab-content {
display: none;
height: 200px;
order: 100;
}
.container.current .tab-content {
display: block;
width: 300px;
left: 0;
}
.footer {
height: 500px;
width: 300px;
display: block;
}
.red {
background: red;
}
.teal {
background: teal;
}
<div class="wrapper">
<div class="container">
<div class="tab-header">Tab1</div>
<div class="tab-content teal">Content1</div>
</div>
<div class="container current">
<div class="tab-header">Tab2</div>
<div class="tab-content teal">Content2</div>
</div>
<div class="container">
<div class="tab-header">Tab3</div>
<div class="tab-content teal">Content3</div>
</div>
</div>
<div class="footer red">Footer Text</div>
This isn't quite perfect because the first tab is a bit wider, but give this a shot and see if this doesn't get your closer to your goal. It allows your tabs to be 100% and also allows you to add more tabs that space evenly from edge to edge of your container.
Let me know how it works out :D
Add display: table-cell and width: 100% to your css selector label
label {
display: table-cell;
width: 100%;
margin: 0 0 -1px;
padding: 15px 25px;
font-weight: 600;
text-align: center;
color: #bbb;
border: 1px solid transparent;
}

IE 11: Image doesn't scale down correctly within flexbox

I'm trying to use flexbox to place two images in a column. In this case, the width of the div container is smaller than the width of the image. In Chrome the image perfectly fits into the div container, but it doesn't in IE, and I don't know why.
div.outer {
width: 400px;
display: flex;
flex-direction: column;
justify-content: space-around;
}
div.inner {
width: 100%;
border: 1px solid red;
}
img {
width: 100%;
height: auto;
}
<div class="outer">
<div class="inner">
<img src="http://placehold.it/480x360">
</div>
<div class="inner">
<img src="http://placehold.it/480x360">
</div>
</div>
https://jsfiddle.net/Yifei/16cpckqk/
This is what I've got in IE 11:
IE11 seems to have some trouble with the initial value of the flex-shrink property. If you set it to zero (it is initially set to 1), it should work:
div.outer {
width: 400px;
display: flex;
flex-direction: column;
justify-content: space-around;
}
div.inner {
flex-shrink: 0;
width: 100%;
border: 1px solid red;
}
img {
width: 100%;
height: auto;
}
<div class="outer">
<div class="inner">
<img src="http://placehold.it/480x360">
</div>
<div class="inner">
<img src="http://placehold.it/480x360">
</div>
</div>
The accepted solution destroyed my sticky footers in ie. So I solved this disturbing issue with the following non satisfying "only for ie JS"... . The px value instead the "height:auto" did the trick for me.
if(fuBrowser =='ie'){
var img = $("#teaser img");
img.each(function() {
$( this ).css({height: $( this ).height()});
});
}

Dynamic width of table div

I need to have a div construct with a table-display, while the first cell should be as wide as the content fit to it without linebreak. The second cell should take the rest of the width,
html
<div class="table full-width">
<div class="table-cell">Cell 1 without br</div>
<div class="table-cell">Cell 2 just the rest width</div>
</div>
css
.full-width {
width: 100%;
}
.table {
display: table;
}
.table-cell {
display: table-cell;
}
I would highly recommend not explicitly styling <div>s as table elements. Use the default HTML elements for that, or perhaps use more fluid formatting styles, such as float.
However, I suggest you use the more modern CSS3 flex-box, with its children style flex-grow. It gives you a lot more flexibility in situations like these.
div.container {
display: flex;
background-color: lightgrey;
padding: 20px;
justify-content: space-between;
}
div.shrink, div.grow {
padding: 20px;
margin: 0 10px;
background-color: grey;
flex-basis: auto;
}
div.shrink {
flex-shrink: 1;
}
div.grow {
flex-grow: 1;
}
<div class="container">
<div class="shrink">
This will shrink!
</div>
<div class="grow">
This will grow!
</div>
</div>
You can try this:
HTML
<div class="table full-width">
<div class="table-cell">Cell 1 without br</div>
<div class="table-cell cell-wide">Cell 2 just the rest width</div>
</div>
CSS
.full-width {
width: 100%;
}
.table {
display: table;
}
.table-cell {
display: table-cell;
white-space: pre;
}
.cell-wide {
width: 100%
}
Fiddle

Flex box column row issue in Internet Explorer

In having an issue in Internet explorer where it does not render flex box elements correctly in conjunction to rows.
Columns seem to work fine in both browsers but...
IE 11 seems to be shrinking the rows for no reason? meaning I can fix it by applying flex: 1 0 auto(prevent shrinking) to rows and flex:1 to columns but is not constant code.
Is there a fix to it in IE or am I doing something wrong as Chrome renders it correctly this is my current fix and seems like a hack to me.
Chrome
IE:
<html>
<body>
<style>
div.form {
display: block;
width: 500px;
height: 500px;
overflow-y: scroll;
}
div.container-row {
display: flex;
flex-direction: column;
background-color: white;
}
div.container-col {
display: flex;
flex-direction: row;
background-color: white;
}
div.field {
display: inline-flex;
flex: 1;
background-color: purple;
padding: 10px;
box-sizing: border-box;
}
div.value {
display: inline-flex;
flex: 1;
background-color: pink;
}
input[type=text] {
width: 100%;
padding: 10px;
}
</style>
<div class="form">
<div class="container-row">
<div class="field">hiiiiiiiidddsssssssdddddddd</div>
<div class="value">
<input type="text" />
</div>
</div>
<div class="container-row">
<div class="field">hiiiiiiiidddsssssssdddddddd</div>
<div class="value">
<input type="text" />
</div>
</div>
<div class="container-col">
<div class="field">hiiiiiiiidddsssssssdddddddd</div>
<div class="value">
<input type="text" />
</div>
</div>
<div class="container-col">
<div class="field">hiiiiiiiidddsssssssdddddddd</div>
<div class="value">
<input type="text" />
</div>
</div>
</div>
</body>
</html>
Fiddle: https://jsfiddle.net/e2jwc371/3/
Cheers for the help ;)
When using flex: 1;, you're not only setting flex-grow and flex-shrink. You're also setting flex-basis (relative sizing between the elements) to 0%. That's probably what's confusing IE.
Change the flex properties to use auto-sizing (flex: 1 auto;), and it works correctly in IE too:
...
div.field {
display: inline-flex;
flex: 1 auto;
background-color: purple;
padding: 10px;
box-sizing: border-box;
}
div.value {
display: inline-flex;
flex: 1 auto;
background-color: pink;
}
...
Updated JSFiddle: https://jsfiddle.net/e2jwc371/4/