Home > Mobile >  Center an image in a contenteditable div
Center an image in a contenteditable div

Time:10-04

Please before tagging the question as duplicated, I tell you, I've been searching a lot and can't find a clear answer, so it may be worth it to try to get a clear one for the year we are living, 2022.

I have this contenteditable div:

  <div  placeholder="Tell me something..." contentEditable="true"></div>

I've been able to center the text and regular emojis setting the line-height in css but when I enter an image I am using as a custom emoji it does not get centered.

<img src="img/emojis/red-circle.png" >

enter image description here

I am adding the image to the input field with event.target after I click it from another box:

inputField.innerHTML  =
      "<div class='emo'>"   event.target.outerHTML   "</div>";

But the Divs get removed by innerHTML, so it blocks me from adding display:flex; align-items: center;

And if I set display:flex; align-items: center; directly on the contenteditable I get horizontal scrolling which I do not want.

Then if I set the css to be display:flex; align-items: center; flex-direction: column; on the contenteditable the image-emojis display one on each line every time, not side by side.

enter image description here

Please help.

EDIT:

Following the first answer advice I tested flex-wrap:wrap; on the contenteditable which also produces horizontal scrolling on long words with no spaces and flex-wrap:nowrap; does the same.

enter image description here

EDIT-2:

As suggested adding break-word:break-all; works partially but now I notice another problem with display: flex; It prevents the ENTER key from adding additional lines even thought <div> <br> </div> are added to the Html, any idea?

EDIT-3

Finally not using flex box, but just line-height to align text and emojis and as per Lukas below:

 .input-field img {
  vertical-align: middle;
}

...aligned the image.

enter image description here

const emojiBox = document.querySelector(".emoji-box");
const inputField = document.querySelector(".input-field");

emojiBox.addEventListener("click", (e) => {
  let emoji = null;
  let isImage = null;
  let emojiImage = null;
  let removeBR = null;
  
  if (e.target != e.currentTarget) {    
    removeBR = inputField.querySelector("br");
    if (removeBR) {
      removeBR.outerHTML = "";
    }

    if (
      e.target.tagName.toLowerCase() === "img" &&
      e.target.classList.value.toLowerCase() === "emoji"
    )
      isImage = true;

    if (isImage) {
      emojiImage = e.target;
    } else {
      emoji = e.target;
    }
  }


  if (emoji) {
    inputField.innerHTML  = emoji.outerHTML;
  } else if (emojiImage) {
    inputField.innerHTML  = emojiImage.outerHTML;
  }
  cursorAtTheEnd();
});

function cursorAtTheEnd() {
  let sel = window.getSelection();
  sel.selectAllChildren(inputField);
  sel.collapseToEnd();
  inputField.focus();
}
html {
  
  font-size: 62.5%;
 
}

.image-emoji { 
  max-width: 1.8rem;
  max-height: 1.8rem;
  border-radius: 100%;
  padding: 0;
  margin: 0 0.15rem 0;  
}


.input-field {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  word-break: break-all;
   font-size:1.6rem;
  min-height: 3rem;
  max-height: 20rem;
  width: 40rem; 
  margin: 0.5rem;
  padding: 1rem 6rem 1rem 4rem;
  border: 2px solid #e6e6e6;
  border-radius: 0.5rem;
  outline: none;
  overflow-y: auto;

  
}


[contenteditable="true"]:empty:before {  
  content: attr(placeholder);
  pointer-events: none;
  display: block; /* For Firefox */
}


.emoji-box {
  display: flex;
  align-items: center;  
  font-size:1.6rem;
  background: white;
  border: 0.2rem solid #eee;
  border-radius: 0.5rem;
  height: 3rem;
  width: 40rem;  
  padding: 1rem 6rem 1rem 4rem;
  margin: 0.5rem;
  color: #183153;
  cursor: pointer;
  overflow-y: auto;
  
}
<div >
<span>&#128578;</span>
<img src="https://upload.wikimedia.org/wikipedia/commons/0/02/Red_Circle(small).svg" >
</div>

<div  placeholder="Tell me something..." contentEditable="true"></div>

CodePudding user response:

try this

const emojiBox = document.querySelector(".emoji-box");
const inputField = document.querySelector(".input-field");

let lastKeyEnter = false;

function removeBR() {
    let removeBR = inputField.querySelector("br:last-of-type");

    if (
        removeBR &&
        removeBR.previousElementSibling &&
        removeBR.previousElementSibling.tagName === "BR"
    ) {
        removeBR.remove();
    }
}

inputField.onkeydown = (e) => {
    if (e.keyCode === 13) {
        lastKeyEnter = true;
    } else if (lastKeyEnter) {
        lastKeyEnter = false;
    }
};

emojiBox.addEventListener("click", (e) => {
    let emoji = null;
    let isImage = null;
    let emojiImage = null;

    if (e.target != e.currentTarget) {
        if (
            e.target.tagName.toLowerCase() === "img" &&
            e.target.classList.value.toLowerCase() === "emoji"
        )
            isImage = true;

        if (isImage) {
            emojiImage = e.target;
        } else {
            emoji = e.target;
        }
    }

    let lastChild = inputField.lastChild;

    if (
        lastChild &&
        lastChild.previousSibling &&
        lastChild.previousSibling.tagName === undefined
    ) {
        lastChild.tagName === "BR" ? lastChild.remove() : "";
    }

    if (emoji && emoji.tagName === "SPAN") {
        lastKeyEnter ? removeBR() : "";
        lastKeyEnter = false;
        inputField.innerHTML  = emoji.innerHTML;
    } else if (emoji && emoji.tagName === "IMG") {
        lastKeyEnter ? removeBR() : "";
        lastKeyEnter = false;
        inputField.innerHTML  = emoji.outerHTML;
    } else if (emojiImage) {
        lastKeyEnter ? removeBR() : "";
        lastKeyEnter = false;
        inputField.innerHTML  = emojiImage.outerHTML;
    }
    cursorAtTheEnd();
});

function cursorAtTheEnd() {
    let sel = window.getSelection();
    sel.selectAllChildren(inputField);
    sel.collapseToEnd();
    inputField.focus();
}
html {
  
  font-size: 62.5%;
 
}

.image-emoji { 
  max-width: 1.8rem;
  max-height: 1.8rem;
  border-radius: 100%;
  padding: 0;
  margin: 0 0.15rem 0;  
}


.input-field {
  word-break: break-all;
   font-size:1.6rem;
  min-height: 3rem;
  max-height: 20rem;
  width: 40rem; 
  margin: 0.5rem;
  padding: 1rem 6rem 1rem 4rem;
  border: 2px solid #e6e6e6;
  border-radius: 0.5rem;
  outline: none;
  overflow-y: auto;
  display: inline-block;
  line-height: 2rem;
  
}

.input-field img {
  vertical-align: text-bottom;
}


[contenteditable="true"]:empty:before {  
  content: attr(placeholder);
  pointer-events: none;
  display: block; /* For Firefox */
}


.emoji-box {
  display: flex;
  align-items: center;  
  font-size:1.6rem;
  background: white;
  border: 0.2rem solid #eee;
  border-radius: 0.5rem;
  height: 3rem;
  width: 40rem;  
  padding: 1rem 6rem 1rem 4rem;
  margin: 0.5rem;
  color: #183153;
  cursor: pointer;
  overflow-y: auto;
  
}
<div >
    <span>&#128578;</span>
    <img src="https://upload.wikimedia.org/wikipedia/commons/0/02/Red_Circle(small).svg" >
</div>

<div  placeholder="Tell me something..." contentEditable="true"></div>

  • Related