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" >
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.
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.
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.
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>🙂</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>🙂</span>
<img src="https://upload.wikimedia.org/wikipedia/commons/0/02/Red_Circle(small).svg" >
</div>
<div placeholder="Tell me something..." contentEditable="true"></div>