I have a line of numbers as icons <i>1</i><i>2</i><i>3</i><i>4</i>
and I'm trying to make a prigramm that would dynamically put specific emojis over each of them. So that the number is behind it's emoji.
So far I've only managed to cross the numbers out on demand. I was thinking, maybe there is a possibility to use emojis as a kind of a line-through-style in CSS?
UPD: So I I have <i id="six">6</i>
in HTML and #six::before {content: '🔥'; position: absolute;}
in CSS, and it's working, although it's displayed askew, and z-index
attribute doesnt change anything.
There are a bunch of factors playing a role on why the content gets rendered with an offset relative to the container. The easiest approach to solve that is using an offset on the left property so that it gets aligned correctly.
I tried to make a demo extrapolating your initial conditions.
I used the ::before
pseudoelement to render the emoji content when a given class gets applied to the element. Anyway to make sure that the parent <i>
element gets aligned with the pseudoelement, I styled it with fixed height and width and set the font size in the root element so that everything gets styled properly when using rem.
So this is the style for the .box element:
.box{
position: relative;
width: 1rem;
height: 1rem;
line-height: 1rem;
display: inline-block;
text-align: center;
}
position:relative
is needed so that the pseudoelement will be positioned absolute relative to its parent; the size is fixed and the display: inline-block
will make sure that the parent element will still be inline in terms of layout but will also take its width into consideration.
The demo has 3 buttons:
<i>
elements (as red) and ::before elements (as blue)I used top: 20%
and I have to admit it was arbitrary. Anyway I'm quite sure it should scale well across font sizes.
One note aside, since the <i>
element sets the formatting to italic, I changed it inside the pseudoelement (font-style: normal;
) so that the emoji doesn't get stretched (like the flame you showed in your example).
To better show how this layout scales with font size I also added a range slider that will change the font size of the root element in real time.
changeFontSize();
function toggleClassToBoxes(classname){
document.querySelectorAll('.container > .box')
.forEach(box => { box.classList.toggle(classname); });
}
function toggleClassToBoxesByNumber(classnamePrefix){
document.querySelectorAll('.container > .box')
.forEach(box => {
const i = parseInt(box.textContent);
const classname = `${classnamePrefix}-${i}`;
box.classList.toggle(classname);
});
}
function changeFontSize(range){
if(!range)
range = document.querySelector('.fontsize input');
const value = `${range.value}px`;
document.querySelector(':root').style.fontSize = value;
document.querySelector('.fontsize label').textContent = `font-size: ${value};`;
}
:root{
font-size: 80px;
}
.box{
position: relative;
width: 1rem;
height: 1rem;
line-height: 1rem;
display: inline-block;
text-align: center;
}
.box.outline{
outline: solid red 6px;
}
.emoji::before {
position: absolute;
font-style: normal;
left: 0;
right: 0;
}
.emoji.outline::before {
outline: solid blue 3px;
}
.emoji.offset::before {
left: -20%;
/*
This was overstating for the sake of evaluating any option
padding: 0;
margin: 0;
width: 1rem;
height: 1rem;
line-height: 1rem;
padding: 0;
margin: 0;
box-sizing: border-box;
*/
}
.emoji-1::before{
content: "😆";
}
.emoji-2::before{
content: "😁";
}
.emoji-3::before{
content: "🤣";
}
.emoji-4::before{
content: "😂";
}
.fontsize{
display: flex;
gap: 20px;
}
.fontsize input{
width: 50%;
}
button, input{
cursor: pointer;
padding: .5em 1em;
}
label{
font-size: 24px;
}
<div class="container">
<i class="box">1</i>
<i class="box">2</i>
<i class="box">3</i>
<i class="box">4</i>
</div>
<div>
<div class="buttonstripe">
<button
onclick="toggleClassToBoxes('emoji');toggleClassToBoxesByNumber('emoji');"
>Toggle Emojis</button>
<button onclick="toggleClassToBoxes('outline');">Toggle Outlines</button>
<button onclick="toggleClassToBoxes('offset');">Toggle Offset</button>
</div>
<div class="fontsize">
<input type="range" oninput="changeFontSize(this)" min="0" max="100" value="80">
<label>font-size</label>
<div>
</div>