Fluid width single line textarea - javascript

I'm trying to create a div with a fluid-width textarea inside it. The width of the div should be at least 3em, at most 12em, and otherwise the exact same width as the textarea. I've got this working. See fiddle.
When the textarea fills up the div, it creates a line break rather than overflowing to the left, which is the effect I'm going for. Any ideas how to achieve this?
Edit: This code is based on A List Apart's article on Expanding Text Areas.
html
<div><pre><span></span><br></pre>
<textarea autofocus placeholder='Note'></textarea>
</div>
css
div {
border: 1px solid grey;
position: relative;
display: inline-block;
/* overflow: hidden; */
height: 1.3rem;
min-width: 3rem;
max-width: 12rem;
}
textarea {
border: 1px solid blue;
resize: none;
background: rgba(0,0,255,.5);
padding: 0;
width: 100%;
}
textarea, pre {
position: absolute;
top: 0;
right: 0;
height: 100%;
margin: 0;
/* visibility: hidden; */
}
pre {
border: 1px solid pink;
position: relative;
max-width: 100%;
}
* {
font: 1rem arial;
}
js
var textarea = document.querySelector('textarea');
var span = document.querySelector('span');
textarea.addEventListener('input', function() {
span.textContent = textarea.value;
});

In your CSS use:
white-space: nowrap;
overflow: hidden;
Edit this is deprecated:
Can you set wrap="off" as an attribute on the textarea?
edit: to say overflow: hidden; (per comment below) original: overflow: auto;

Related

How to make insertion into contentEditable paragraph bound by its size?

I need an editable one line paragraph such that the text inserted into it must not overflow its size.
I'm currently using CSS to try to hide the overflow and also to avoid multiple lines (by not displaying the paragraph's children).
However, ideally I need the text inserted into the paragraph to be "cut" as soon as it would overflow.
This is my code so far (also in JSFiddle):
div
{
width: 50vw;
height: 50vh;
margin: 10px auto;
background-color: gray;
}
p
{
position: absolute;
left: 50%;
transform: translateX(-50%);
width: 25%;
background-color: brown;
text-align: center;
white-space: nowrap;
overflow-x: hidden;
}
/* Avoiding multiple lines */
p *
{
display: none;
}
<div>
<p contentEditable="true">
Edit me! Unfortunally I can be overflowed... :(
</p>
</div>
You can use word-break: keep-all; property in this case
div {
width: 50vw;
height: 50vh;
margin: 10px auto;
background-color: gray;
}
p {
position: absolute;
left: 50%;
transform: translateX(-50%);
width: 25%;
background-color: brown;
text-align: center;
word-break: keep-all;
white-space: normal;
}
p * {
display: none;
}
<div>
<p contentEditable="true">
Edit me! Unfortunally I can be overflowed... :(
</p>
</div>

Wrong focus position in ContentEditable Div with placeholder in IE

I have a content Editable Div with a place holder.
See this fiddle.
[contenteditable=true]:empty:before {
content: attr(placeholder);
}
#myDiv {
border: 1px dashed #AAA;
width: 290px;
padding: 5px;
text-align: center;
}
<div id="myDiv" contenteditable="true" placeholder="Enter text here..."></div>
The problem is:
When we open this fiddle in Chrome and click on div we get cursor focus in div at center. see pic. below:
But when we do same thing in IE we get focus at last of place holder. see below pic.
I want to focus cursor at center in IE too.
I'm not sure exactly why this happens, but you could apply position: absolute; to your pseudoelement and a few additional rules to size the div. This works for me in IE11.
fiddle
Example:
[contenteditable=true] {
position: relative;
}
[contenteditable=true]:empty:before {
content: attr(placeholder);
position: absolute;
left: 0;
right: 0;
top: 4px;
margin: auto;
}
#myDiv {
border: 1px dashed #AAA;
width: 290px;
padding: 5px;
text-align: center;
height: 16px;
}
<div id="myDiv" contenteditable="true" placeholder="Enter text here..."></div>

Html Canvas Overlay that don't disable content under

I want to put the canvas defined by the red border over the div (black border) that is currently under it. It should have the same size as the div. I also want to be able to click on buttons and select text that is under the canvas.
I have been trying to do this for 2 days now and can't figure it out...
<canvas id="canvas">
</canvas>
<div class="jumbotron">
<div class="container-fluid" id="canvas-container">
</div>
</div>
current css (I know it's a mess, but I have been trying a lot of things)
html {
position: relative;
min-height: 100%;
}
body {
/* Margin bottom by footer height */
margin-bottom: 60px;
margin-top: 50px; /* Required margin for .navbar-fixed-top. Remove if using .navbar-static-top. Change if height of navigation changes. */
}
.footer {
position: absolute;
bottom: 0;
width: 100%;
/* Set the fixed height of the footer here */
height: 60px;
background-color: #f5f5f5;
}
/* Custom page CSS
-------------------------------------------------- */
/* Not required for template or sticky footer method. */
body > .container {
padding: 60px 15px 0;
}
.container .text-muted {
margin: 20px 0;
}
.footer > .container {
padding-right: 15px;
padding-left: 15px;
}
code {
font-size: 80%;
}
.jumbotron
{
text-align: center;
}
#canvas-container
{
padding: 0;
//position: absolute;
border: 1px solid black;
}
.jumbotron
{
padding: 0;
#position: absolute;
}
canvas {
border: 1px solid red;
}
You need to specify:
canvas {
pointer-events:none;
}
Here is a js fiddle where you can test clicking on the area where the black box is under the red box:
https://jsfiddle.net/1n1bp7m9/1/

How can I make dynamically created divs flush with eachother?

I have a function that creates a grid of divs that are generated and sent to a container div when the document loads (or when the user resets it). Everything seems to be about the way that I like it, except that there is a gap between each "row" of divs. I'd like it to be a perfect grid, with each square flush with each other. I've tried modifying borders, outlines, padding and the like with no success. I'm convinced there has to be a way to make this work that is less complicated than I am making it out to be. jsfiddle example: https://jsfiddle.net/psyonix/1g9p59bx/84/
var d = ("<div class='square'></div>");
function createGrid(numSquares) {
var area = $('#g_area');
var n = 0;
var squareSize = (area.innerWidth() / numSquares);
for (var i = 0, len = (numSquares * numSquares); i < len; i++) {
area.append(d);
}
$('.square')
.height(squareSize)
.width(squareSize)
#g_area {
background-color: #C8C8C8;
position: relative;
width: 580px;
height: 600px;
border-radius: 5px;
margin: 0 auto;
overflow: hidden;
}
.square {
display: inline-block;
position: relative;
background-color: #C8C8C8;
outline-color: #000000;
outline-width: 1px;
outline-style: solid;
}
You just need to either remove a outline-width from .square or give it some 2px or 3px value.
.square {
display: inline-block;
position: relative;
background-color: #C8C8C8;
outline-color: #000000;
outline-width: 3px; //or 2px or just remove it as I have done in my DEMO
outline-style: solid;
}
DEMO HERE
You are using inline-block on the square elements, so the square elements will act like the words inside a paragraph, and will be laid out as in lines of a sentence. These lines will have line-height just as in normal sentences, so one way is to reset the line-height of the parent holding these square words.
#g_area {
background-color: #C8C8C8;
position: relative;
width: 580px;
height: 600px;
border-radius: 5px;
margin: 0 auto;
overflow: hidden;
line-height: 0px;
}
This way you can JAM the lines as you are not exactly looking for lines as in normal sentences.
Another way is to avoid using the inline-block and using block and float to attain the same. Block display doesn't have the issue of line-height or white-spaces between elements.
.square {
display: inline-block;
position: relative;
background-color: #C8C8C8;
outline-color: #bc0000;
outline-width: 1px;
outline-style: solid;
display:block;
float:left;
}

center vertical line between divs

I have a div named welcome-inputs and within other two left and right
The div named left needs to be on the left side welcome-inputs and the div named right right side of welcome-inputs.
left and right have width = 100px
Need for a line that is at the MIDDLE of the two, signaling the separation.
view the code: http://jsfiddle.net/gn1asdmh/3/
The red line must be in the middle of the images (the images represent left and right)
jsFiddle demo
Add a span element between .left and .right
<span class="middleLine"></span>
CSS:
.welcome-inputs {
float: none;
margin: 0 auto;
width: 80%;
background:white;
height:100px;
text-align:center; /* ADD THIS */
}
.welcomeforms {
color: #6B6B6B;
margin: 0 auto;
width: 100px !important;
}
.left {
float: left;
/*border-right: 3px solid red; REMOVE THIS */
}
.right {
float: right;
}
body {
background:blue;
}
span.middleLine{
display:inline-block;
border-right: 2px solid red;
margin-left:-1px; /* cause the border is 2px */
height:100%;
}
JSFiddle
The other way to resolve it.
.left {
position:absolute;
top: 0;
left: 0;
}
.right {
position:absolute;
top: 0;
right: 0;
}
If you add position: relative to .welcome-inputs, you can use an ::after or ::before pseudo-element on .left or .right like this:
.left::after {
border-right: 3px solid red;
content: "";
height: 100px;
position: absolute;
top: 0;
left: calc((100% - 3px) / 2); // or use '50%' for better compatibility, but less exactness
}
and get rid of the border-right on .left
JSFiddle Here
Just use generated content on the parent element. There is no reason in the given example to use structural markup for this.
Updated fiddle, http://jsfiddle.net/gn1asdmh/26/
.welcome-inputs {
float: none;
margin: 0 auto;
width: 80%;
background:white;
height:100px;
position: relative;
}
.welcome-inputs::before {
content: '';
display: block;
position: absolute;
outline: 1px solid red;
left: 50%;
width: 0;
height: 100px;
}
.welcomeforms {
color: #6B6B6B;
margin: 0 auto;
width: 100px !important;
}
.left {
float: left;
}
.right {
float: right;
}
body {
background:blue;
}
The cleanest way to do it would be to use an HTML table. This will keep it responsive. Try something like the below code.
.welcome-inputs {
width: 100%;
}
#leftInput,
#rightInput {
width: 100px;
}
#separatorInput {
text-align: center;
}
#dividingLine {
display: inline-block;
height: 100%;
width: 5px;
background: red;
}
<table class="welcome-inputs">
<tr>
<td id="leftInput">
<img width="100%" src="http://news.bbcimg.co.uk/media/images/71832000/jpg/_71832498_71825880.jpg" />
</td>
<td id="separatorInput"><div id="dividingLine"</td>
<td id="rightInput">
<img width="100%" src="http://news.bbcimg.co.uk/media/images/71832000/jpg/_71832498_71825880.jpg" />
</td>
</tr>
</table>
Even better: no need to use any empty/dummy elements. We rely on using pseudo-elements instead. In this case I will use ::before:
.welcome-inputs {
float: none;
margin: 0 auto;
width: 80%;
background:white;
height:100px;
position: relative; /* new property added to original one */
}
.welcome-inputs::before {
content: '';
position: absolute;
top: 0;
bottom: 0;
width: 3px;
background-color: red;
left: 50%;
transform: translateX(-50%);
}
Just remember to declare position: relative on the parent element. See fiddle here: http://jsfiddle.net/teddyrised/gn1asdmh/28/
p/s: You might want to use vendor prefixes for transform, to maximise cross-browser compatibility.
to add some idea to these answers , you may think as well of :box-sizing, calc() for instance , or even a simple background image/repeat/sizing

Categories

Resources