Смущен приоритетом CSS

У меня есть два набора правил CSS, применимых к ячейке таблицы. Я думал, что один набор правил будет иметь приоритет над другим, но приходится выбирать что-то из каждого. правила противоречат друг другу.

HTML генерируется JavaScript

const toDoArray = {
  test: true,
}

var toDoElements = "<table style=\"width: 100%;\">";

for (var k in toDoArray) { // Loop through the object
  var trS = "";
  if (toDoArray[k]) {
    trS = `class = "taskChecked"`
  }
  toDoElements +=
    `<tr ${trS} id = "${k}-tr">
      <td onclick = "checkOffToDo('${k}')" id = "${k}-td" border=none > ${k}</td>
      <td onclick = "removeToDo('${k}')" class = "toDoDeleteButton">&times;</td>     
    </tr>`
}

toDoElements += "</table>";

document.getElementById("toDoList").innerHTML = toDoElements;
#toDoList { width: 200px; font-size: 3rem; }

.taskChecked {
  text-decoration: line-through;
  text-decoration-color: violet;
  color: purple;
  background: orange;
}

.toDoDeleteButton {
  border: none;
  width: 8%;
  height: auto;
  text-decoration: none !important;
  text-decoration-color: aqua;
  color: yellow;
  background-color: blue;
}
<div id = "toDoList"></div>

Я нашел ответ StackOverflow, описывающий приоритет (https://stackoverflow.com/a/25105841), но, похоже, он не соответствует этому. Если бы это соответствовало всему одному или всему другому, я думал, что смогу заставить это работать правильно, но теперь я просто в замешательстве.

Моя главная цель — не дать этому закончиться. Остальные цвета и прочее — это я тестирую варианты, пытаясь выяснить, что происходит и почему это не работает.

Это в Хроме.

Каких именно применяемых правил вы не ожидаете?

Pointy 09.04.2024 03:00

Некоторые свойства CSS наследуются дочерними элементами. Итак, text-decoration из элемента tr влияет на элемент td.

qrsngky 09.04.2024 03:10

@qrsngky, это правда, но у ребенка есть свои правила. Возможно, это одна из действительно странных особенностей работы стилей таблиц.

Pointy 09.04.2024 03:11

@Pointy - нет, речь идет о том, как текстовое оформление распространяется и накапливается.

Alohci 09.04.2024 03:24

Я могу воспроизвести то же самое с помощью div > div: ребенок не может «отменить» текстовое оформление родителя. Однако использование display:inline-block на ребенке каким-то образом делает его «отменяемым». Однако это не вариант для ячейки таблицы.

qrsngky 09.04.2024 03:26

@Alohci да, я уверен, что это так, но то, как инспектор DOM показывает стили, довольно подозрительно, поскольку <td> (только с текстовым узлом) имеет явный стиль text-decoration, и браузер показывает его как активный, но это явно не работает.

Pointy 09.04.2024 03:26

Любой, кто действительно это понимает, должен добавить ответ получше, чем мой :) e: о, это прямо в документации MDN; Я думаю, что ключевым термином здесь является «текст», как и текстовые узлы в DOM. Поэтому, как только родительский элемент начинает рисовать что-то поверх текста, дочерние элементы не могут остановить это. Однако они могут добавить больше украшений. Очевидно, это не то, что я сделал много.

Pointy 09.04.2024 03:27

См. эту страницу MDN

Pointy 09.04.2024 03:31

Я вижу: «Текстовые украшения рисуются через текстовые элементы-потомки. Это означает, что если элемент определяет текстовое оформление, то дочерний элемент не может удалить украшение». Итак, может ли кто-нибудь объяснить поведение встроенного блока?

qrsngky 09.04.2024 03:33

@qrsngky — Атомарные встроенные блоки, такие как inline-block (также inline-flex, inline-grid и т. д.), являются лишь исключением. Текстовое оформление просто определено так, чтобы не распространяться на них.

Alohci 09.04.2024 03:39

Я вижу, что проблема с встроенным блоком уже задавалась здесь . Это относилось к более старым характеристикам, но я нашел объяснение в новой ссылке

qrsngky 09.04.2024 03:48

Точная формулировка скопирована с Drafts.csswg.org/css-text-decor-3/#line-decoration для справки: Note that text decorations are not propagated to any out-of-flow descendants, nor to the contents of atomic inline-level descendants such as inline blocks and inline tables.

qrsngky 09.04.2024 04:04
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
4
12
121
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

В вашем классе «taskDef» есть text-decoration: line-through. Это <tr>, вся строка таблицы. Это применимо к обоим элементам <td> в таблице: слову и «X».

Теперь я не могу сказать, почему стиль ячейки не переопределяет стиль строки. Стиль явно есть (ну, без зачеркивания). Я не могу сказать ничего определенного, но если бы я делал это, я бы не делал элемент <td> «кнопкой»; вместо этого поместите в ячейку настоящий <button> и стилизуйте ее отдельно. Вероятно, потребуются некоторые другие изменения в размере шрифта и т. д.

Это странно.

редактировать: комментаторы объяснили, что речь идет конкретно о правилах text-decoration и о том, как они работают с текстовыми узлами-потомками.

Самое главное, что text-decoration не может быть унаследовано, в тестовой демонстрации ниже есть две строки, независимые друг от друга, и в вашем случае родительское text-decoration находится поверх дочернего.

<style>
  div {
    text-decoration: line-through
  }
  span {
    text-decoration: underline;
  }
</style>
<div>
  <span>text-decoration</span>
</div>

«Не может быть унаследовано» — неправильная концепция. Например, в <style> div { text-decoration: line-through } span { display: inline-block; text-decoration: inherit; } </style> <div> <span>text-decoration</span> </div> через промежуток проходит линия, хотя без text-decoration: inherit; этого бы не произошло.

Alohci 09.04.2024 04:09

@Alohci, строка, которую вы смотрели, получена не из диапазона, а из div, даже если содержимое находится в диапазоне, а не в div.

moon 09.04.2024 04:21

Если вы попробуете это <div style = "text-decoration: line-through"><span style = "margin:10px;display:block;text-decoration:none">abc</‌​span><span>cde</span‌​></div>, то увидите, что это не одна строка от родителя, а две строки, по одной для каждого дочернего элемента. Если вы измените «block» на «inline-block», то линия будет только у одного дочернего элемента.

qrsngky 09.04.2024 05:44

@qrsngky, да, вы правы, так вы имеете в виду, что «встроенный блок» влияет на «оформление текста»?

moon 09.04.2024 08:20

По сути, «встроенный блок» предотвращает распространение текстового оформления на дочерние элементы. Но если вы также используете «text-decoration: inherit», тогда text-decoration может повлиять на детей.

qrsngky 10.04.2024 16:31
Ответ принят как подходящий

Цитата из ссылки MDN:

Текстовые украшения рисуются по дочерним текстовым элементам. Это означает, что если элемент определяет текстовое оформление, то дочерний элемент не может удалить это оформление.

Таким образом, даже несмотря на то, что ваш элемент <td> указывает text-decoration: none, на текст внутри <td> по-прежнему влияет text-decoration элемента <tr>.

Однако согласно этой спецификации:

Обратите внимание, что текстовые украшения не распространяются ни на каких-либо потомков вне потока, ни на содержимое атомарных потомков строчного уровня, таких как строчные блоки и строчные таблицы.

Поэтому обходной путь — добавить элемент inline-block. Например, мы можем использовать элемент span и оформить его как встроенный блок. А поскольку в пролете нет ничего особенного, размеры остальных элементов остались прежними.

const toDoArray = {
  test: true,
}

var toDoElements = "<table style=\"width: 100%;\">";

for (var k in toDoArray) { // Loop through the object
  var trS = "";
  if (toDoArray[k]) {
    trS = `class = "taskChecked"`
  }
  toDoElements +=
    `<tr ${trS} id = "${k}-tr">
      <td onclick = "checkOffToDo('${k}')" id = "${k}-td" border=none > ${k}</td>
      <td onclick = "removeToDo('${k}')" class = "toDoDeleteButton"><span>&times;</span></td>     
    </tr>`
}

toDoElements += "</table>";

document.getElementById("toDoList").innerHTML = toDoElements;
#toDoList { width: 200px; font-size: 3rem; }

.taskChecked {
  text-decoration: line-through;
  text-decoration-color: violet;
  color: purple;
  background: orange;
}

.toDoDeleteButton {
  border: none;
  width: 8%;
  height: auto;
  text-decoration-color: aqua;
  color: yellow;
  background-color: blue;
}

.toDoDeleteButton > span{
  display: inline-block;
}
<div id = "toDoList"></div>

Я обнаружил, что вам даже не нужен .toDoDeleteButton > span {text-decoration: none;}.
Украшение текста не распространяется на диапазон, если вы не укажете text-decoration: inherit как для td, так и для диапазона.

Другой способ решить эту проблему — добавить дополнительный класс.

Чтобы объяснить список приоритетов, qrsngky уже сказал, что «дочерний элемент не может удалить украшение родительского».

Я просто хочу добавить к его ответу второе решение, которое лучше сработало в моем случае:

const toDoArray = {
  test: true,
}

var toDoElements = "<table style=\"width: 100%;\">";

for (var k in toDoArray) { // Loop through the object
  var trS = "";
  if (toDoArray[k]) {
    trS = `class = "taskChecked"`
  }
  toDoElements +=
    `<tr ${trS} id = "${k}-tr">
      <td class = "task" onclick = "checkOffToDo('${k}')" id = "${k}-td" border=none > ${k}</td>
      <td onclick = "removeToDo('${k}')" class = "toDoDeleteButton">&times;</td>     
    </tr>`
}

toDoElements += "</table>";

document.getElementById("toDoList").innerHTML = toDoElements;
#toDoList { width: 200px; font-size: 3rem; }

.taskChecked .task{
   text-decoration: line-through;
 }

.taskChecked {
  text-decoration-color: violet;
  color: purple;
  background: orange;
}

.toDoDeleteButton {
  border: none;
  width: 8%;
  height: auto;
  text-decoration-color: aqua;
  color: yellow;
  background-color: blue;
}
<div id = "toDoList"></div>

Другие вопросы по теме