I have a basic list going on, with the HTML structure like this:
<ul class="list">
{...}
<li class="item">Ellipse</li>
{...}
Then I use some JS to add button
s to delete items, so the end structure is like this:
<ul class="list">
{...}
<li class="item">Ellipse <button>Delete item</button></li>
{...}
I also have a function to strike through the list elements on click by toggling a CSS class:
let ul = document.querySelector('.list');
{...}
function markAsDone (event) {
let target = event.target;
target.classList.toggle('done');
}
{...}
ul.addEventListener('click', markAsDone);
This works as expected (e.g. the list item is struck through). However, if I change the list items' display property to flex in CSS:
.item {
display: flex;
justify-content: space-between;
max-width: 300px ;
}
And then click on the item, the text of the button also is struck through, unlike before! Since I've started writing this, I no longer know which behaviour feels more 'wrong' to me, lol.
The full code is on Codepen here. Try clicking the items in the list, then uncomment the CSS style for .item
to see what I mean.
My uneducated guess would be that the answer to this is in the way the flex containers treat the items in them. However, my understanding of it is very limited, so I've come to you for an answer.
The flex CSS shorthand property sets how a flex item will grow or shrink to fit the space available in its flex container.
To use CSS onClick, you'll essentially need to create a pseudo class. You'll use CSS selectors and the checkbox hack to produce something like an OnClick function. And you can get away with this if you just want to use only CSS to make some minor changes, like border width or border radius.
The display CSS property sets whether an element is treated as a block or inline element and the layout used for its children, such as flow layout, grid or flex. Formally, the display property sets an element's inner and outer display types.
Simply wrap your text with span
will resolve your issue. check below snippet.
i am not sure but you apply done
class to parent element
which strike through both element.
let button = document.querySelector('.smash');
let input = document.querySelector('.userinput');
let ul = document.querySelector('.list');
let listItems = document.querySelectorAll('.list > li');
function inputLengthValue() {
let result = input.value.length;
return result;
}
function createListElem() {
let li = document.createElement('li');
li.appendChild(document.createTextNode(input.value));
li.classList.add('item');
ul.appendChild(li);
input.value = "";
let delButton = document.createElement('button');
delButton.appendChild(document.createTextNode('Delete item'));
li.appendChild(delButton);
delButton.addEventListener('click', removeItem)
}
function addListItemOnclick() {
if (inputLengthValue() != 0) {
createListElem();
}
}
function addListItemOnEnterPress(event) {
if (inputLengthValue() != 0 && event.keyCode === 13) {
createListElem();
}
}
function createDeleteButtons() {
for (let i = 0; i < listItems.length; i++) {
let delButton = document.createElement('button');
delButton.appendChild(document.createTextNode('Delete item'));
listItems[i].appendChild(delButton);
delButton.addEventListener('click', removeItem);
}
}
function markAsDone(event) {
let target = event.target;
target.classList.toggle('done');
}
function removeItem(event) {
let target = event.target;
target.parentNode.remove();
}
button.addEventListener('click', addListItemOnclick);
input.addEventListener('keydown', addListItemOnEnterPress);
ul.addEventListener('click', markAsDone);
createDeleteButtons(); // create delete btn for default items
.done {
text-decoration: line-through;
}
.item {
display: flex;
justify-content: space-between;
max-width: 300px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h1 class="title">Some list</h1>
<input type="text" placeholder="enter your text" class="userinput">
<button class="smash">Add item</button>
<ul class="list">
<li class="item"><span>Romboid</span></li>
<li class="item"><span>Square</span></li>
<li class="item"><span>Circle</span></li>
<li class="item"><span>Ellipse</span></li>
<li class="item"><span>Rectangle</span></li>
<li class="item"><span>Oval</span></li>
</ul>
To answering "WHY" let's have a look at the specification.
The 'text-decoration' property on descendant elements cannot have any effect on the decoration of the ancestor.
Your code is fine. This behavior is consistent with spec, text-decoration
affect all children (with some exceptions). There is only one thing you can do about it: just try to avoid the text-decoration
on the parent element, if you doт't want this text-decoration
to be applied to the children.
Note that text decorations are not propagated to floating and absolutely positioned descendants, nor to the contents of atomic inline-level descendants such as inline blocks and inline tables.
Buttons are display: inline-block;
by default, that's why they look fine unless the parent container takes control over it, such as flex or grid.
Here is an example:
.item {
font-size: 20px;
padding: 10px;
border: 1px solid green;
text-decoration: line-through;
text-decoration-color: red;
}
.item-flex { display: flex; }
.item-inline-flex { display: inline-flex; }
.item-grid { display: grid; }
.item-inline-grid { display: inline-grid; }
.item-table { display: table; }
.item-inline-table { display: inline-table; }
.item-inline { display: inline; }
.item-inline-block { display: inline-block; }
.item span, .item button {
margin-left: 10px;
text-decoration: overline underline;
text-decoration-color: blue;
}
<div class="item">
display:
<span>block</span>
<button>button</button>
</div>
<div class="item item-flex">
display:
<span>flex</span>
<button>button</button>
</div>
<div class="item item-grid">
display: <span>grid</span>
<button>button</button>
</div>
<div class="item item-table">
display:
<span>table</span>
<button>button</button>
</div>
<div class="item item-inline">
display:
<span>inline</span>
<button>button</button>
</div>
<div class="item item-inline-block">
display:
<span>inline-block</span>
<button>button</button>
</div>
<div class="item item-inline-flex">
display:
<span>inline-flex</span>
<button>button</button>
</div>
<div class="item item-inline-grid">
display:
<span>inline-grid</span>
<button>button</button>
</div>
<div class="item item-inline-table">
display:
<span>inline-table</span>
<button>button</button>
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With