2

In short, i want a textbox bottom to top that keeps the width and height that i defined. Keeping the cursor bottom left works when adding style position:relative, which makes the div automatically grow when text is added. When using position:absolute, the cursor changes to top-left.

How to reproduce the problem:

Open the jsfiddle and write bottom right more text into the textbox until it overflows. The goal is to keep the size of the div but at the same time keep the caret bottom left

I am forced to go with a div "contenteditable=true" in order to create a nice textbox. The div is created by a server "swellrt" and i can add attributes and styles but i can not change that the text is going into this one div.

The big picture of this it is about a collaborative text editor where the server takes care about the div where all text for all users is going and taking the edits from the users from the same div, posting and getting all changes using a live webrtc channel. On client side i can only change the style and attirbutes of the div which is controlled by the server.

enter image description here

The caret or cursor shall basically start and (as long as not moved by the user) stay at the bottom of the document.

I was able to do this with below example, but using position:relative, the div will grow in height on overflow (when we enter a lot of text). But when changing the position to absolute, the caret will start top left again.

https://jsfiddle.net/pa0owso5/20/

<html>
<style>
.canvas {

    background-color:   #fff;
    box-shadow:         0 4px 14px -4px #919191;
    border:             1px solid #e0e0e0;
    height: 200px;
    width:  400px;
    margin: 20px;
    padding-left: 20px;
    padding-top: 20px;
    padding-bottom: 20px;
    padding-right: 20px;
    word-wrap:break-word; 
    vertical-align: bottom;
    display: table-cell;
    word-wrap:break-word; 
    overflow: scroll; 

    vertical-align: bottom;
    display: table-cell;

    position:relative;
}

</style>

<div contenteditable=true class="canvas">
text should start bottom left
</div>
</html>

Key css elements i use currently are:

vertical-align: bottom;
display: table-cell;
word-wrap:break-word; 
position:relative;
Harry
  • 1,233
  • 10
  • 24

3 Answers3

1

remove display: table-cell; Then you can have overflow-y. Your div will also be of fixed height as you please. And if you want your text to start from bottom, just put a child div giving it all the attributes and transformY to -100%

Prajval M
  • 2,298
  • 11
  • 32
  • thanks for the quick reply but i cannot add another element, the text comes from a server "swellrt" and goes into this one div. Any idea how to deal with that without changing the server code? – Harry Mar 17 '18 at 21:30
  • If you are using Vue and axios to get data you could model it with your div. Without any frontend framework it is difficult to do. – Prajval M Mar 17 '18 at 21:32
  • Thanks, i can add whatever framework i like, i'll give it a shot. Also i changed my question to add the not yet mentioned requirements for the div. – Harry Mar 17 '18 at 21:35
  • uff i just had a look to vue and axios, those don't help because it would require to rewrite the client part of the swellrt server. I guess it would be easier to rewrite the client part to add another div as you suggest than changing the webrtc based live connection... – Harry Mar 17 '18 at 21:47
  • which javascript framework are you using for front end – Prajval M Mar 17 '18 at 21:48
  • currently i just play with plain html and css, thats how swellrt seems to want me to work with it. I could add whatever i like... typically i use jquery and dhtmlx – Harry Mar 17 '18 at 21:50
  • you can use jquery .get() and .text() methods – Prajval M Mar 17 '18 at 21:54
  • not sure if i understood correctly, but just copying and pasting the text into my own div does not work because users might be concurrently working in the server div. Pasting new text into their editor would cause to overwrite their concurrent work – Harry Mar 17 '18 at 23:11
1

If I am understanding correctly you want the caret to start at the bottom? There is an answer here: Set keyboard caret position in html textbox which may answer what you're looking for. It uses javascript to set the caret position in an element. You could determine the length of text and just set the caret to the end. Here is the code:

function setCaretPosition(elemId, caretPos) {
    var elem = document.getElementById(elemId);

    if(elem != null) {
        if(elem.createTextRange) {
            var range = elem.createTextRange();
            range.move('character', caretPos);
            range.select();
        }
        else {
            if(elem.selectionStart) {
                elem.focus();
                elem.setSelectionRange(caretPos, caretPos);
            }
            else
                elem.focus();
        }
    }
}
David Torrey
  • 1,335
  • 3
  • 20
  • 43
  • That is a great thing but unfortunately would not work because a user might concurrently alter the text in the textbox. Using this solution, i would remove the caret from the users control. – Harry Mar 30 '18 at 22:58
  • you just want it to start at the bottom, right? You could do it on load or if there are specific conditions met, you wouldn't necessarily need to keep it permanently there – David Torrey Mar 30 '18 at 23:52
  • 1
    Well it is more like it should be a bottom to top textbox natively as there are multiple parties involved inserting text and reading the text (collaborative), just placing the cursor bottom left would only help for empty textboxes. Thanks a lot for investing your brains anyway! – Harry Apr 01 '18 at 11:43
1

With use of position:relative your caret is able to know where the "bottom" of your canvas is. If you use position:absolute on your canvas class, this means that you are "master of this canvas", but of course also that you have to set all values on your own. This, subsequently, means that your caret does not know automatically where bottom is. Anyhow, you can add an additional "caret" class and give this class the information it needs to position itself.

Try following in CSS:

    .canvas {

    background-color:   #fff;
    box-shadow:         0 4px 14px -4px #919191;
    border:             1px solid #e0e0e0;
    height: 300px;
    width:  500px;
    margin: 20px;
    padding-left: 20px;
    padding-top: 20px;
    padding-bottom: 20px;
    padding-right: 20px;
    word-wrap:break-word; 
    vertical-align: bottom;
    display: table-cell;
    word-wrap:break-word; 
    overflow: scroll; 

    vertical-align: bottom;
    display: table-cell;

    position:absolute;
}
.caret {
  margin-top: 250px;
  position: relative;
}

And in your HTML:

<div contenteditable=true class="canvas">
  <div contenteditable=true class="caret">
  testtext
  </div>
</div>

Cheers!

Yelnya
  • 104
  • 2