1

I have an unordered list whose li elements each contain a button as a child within them.

In Javascript I toggle adding a 'done' style (which crosses off the text) on the li elements when they are clicked like so

function crossOffList(e){
    if (e.target.nodeName === "LI"){
        e.target.classList.toggle("done");
    }
}

The following is the li style:

li {
  margin: 10px 0px;
  **display: flex;**
  justify-content: space-between;
  align-items: center;
  align-self: center;
}

The issue is that when I add display: flex; to the li style, the button also becomes crossed off after the li item is clicked, like so:

Crossed off button

This is how the buttons are created and added to the li elements

function addDeleteButton(element){
    element.innerHTML += " ";
    var button = document.createElement("button");
    button.appendChild(document.createTextNode("Delete"));
    button.addEventListener("click", function(e) {
        ul.removeChild(element);
    })
    
    //button.classList.add("delete-button");

    element.appendChild(button);
}

// initialise all starting list elements
for (var i of document.getElementsByTagName("li")){
    addDeleteButton(i);
    i.addEventListener("click", crossOffList);
}

This behaviour of the button also becoming crossed off does not occur if the display is not set to flex. What is causing this behaviour and is there any way to use flex while having the button not be crossed off after click?

Cirrus86
  • 336
  • 4
  • 13
  • 3
    Click on `<>` in question editor and add enough html and css to demonstrate the issue here in page. If you add strikethrough to the parent it affects it's children. If only want text strike-through use a span for the text and more specific rule to only target the span `.done span{}` for example – charlietfl Sep 20 '20 at 02:51
  • Having tried several ways of overruling the line-through on the button it appears that when flex is set it insists on picking up the LI element done class - as well as anything else you add like text-decoration: underline; even if !important is set. So far the only way I have managed to get round this is putting the text into a span element as @charlietfl suggested. – A Haworth Sep 20 '20 at 08:54
  • I found this in MDN documentation 'Text decorations draw across descendant elements. This means that it is not possible to disable on a descendant a text decoration that is specified on one of its ancestors.' [link]https://developer.mozilla.org/en-US/docs/Web/CSS/text-decoration so now the question seems to be the other way round: why does it not strike through the button when flex is not present? – A Haworth Sep 20 '20 at 09:01

1 Answers1

1

CSS text-decoration does not get inherited in the same way as other properties, it gets propagated. It cannot be overwritten (but it can be added to) by setting another value in a child element. There is some discussion of this at Override text-decoration on child element However, MDN documentation states that this propagation does not apply when the child element is floating or absolute.

I have not been able to show any improvement using float but there is some improvement if we position the button absolutely when, and only when, the parent LI element has display:flex

For example putting class flex on each LI element if you want them flexed and removing it if not and changing the CSS to:

li {
  position: relative;
  margin: 10px 0px;
  justify-content: space-between;
  align-items: center;
  align-self: center;
  background-color:cyan;
}
li.flex {/* add .flex class to each li if you want them flexed*/
  display: flex;
  }
li.done {
  text-decoration: line-through;
}
.flex button {
  position:absolute;
  right:0;
}

Some work will be needed to make sure the desired layout is achieved but at least this method does not strike out the button text in both flex and non-flex cases.

A Haworth
  • 30,908
  • 4
  • 11
  • 14