Несколько дней назад мой друг попросил помочь с решением задачи, которая была на его собеседовании. Интервьюер дал ему следующий фрагмент кода:
tbody:hover tr {
opacity: 0.24;
}
Также добавил: “Сейчас, при наведении на таблицу, все строки становятся блеклыми. А требуется сделать так, чтобы строка, на которую навели, оставалась активной”.
Решение
В текущем решении при наведении на элемент tbody:hover сразу все элементы tr меняют свою непрозрачность на 0.24.
tbody:hover tr {
opacity: 0.24;
}
Мне же нужно изменить селектор так, чтобы непрозрачность применялась ко всем элементам tr кроме того, на который навели.
Для такой реализации потребуется использовать псевдоклассы hover и not. С помощью hover браузер определит, что на строку навели, а при помощи not он поймет, что к ней не надо применять стили.
tbody:hover tr:not(:hover) {
opacity: 0.24;
}
Домашняя задача
Для закрепления я подготовил домашнюю задачу, в которой требуется исправить ошибку при выводе изображения в тексте. Я подготовил следующую разметку и стили:
<main class="content">
<p>Some text</p>
<img src="picture.jpg" alt="some alt">
<p>Some text</p>
</main>
.content img {
margin-top: 35px;
margin-bottom: 35px;
}
Ошибка заключается в том, что если изображение будет первым элементом, у него по прежнему остается отступ сверху, а нужно сделать так, чтобы его не было.
<main class="content">
<img src="picture.jpg" alt="some alt">
<p>Some text</p>
<p>Some text</p>
</main>
Соответственно, если изображение является последнем элементом, то требуется убрать отступ снизу.
<main class="content">
<p>Some text</p>
<p>Some text</p>
<img src="picture.jpg" alt="some alt">
</main>
Комментарии (23)
Spaceoddity
28.05.2019 10:13Это что за «задачи» такие?))
.content img:first-child{ margin-top:0; } .content img:last-child{ margin-bottom:0; }
Kesha_kh
28.05.2019 10:37С тем что сейчас встречаются «фронтенд» разрабы не умеющие верстать, не удивительно появление таких задачек
p.s. Можно вообще без псевдоклассов
.content img + p , .content p + img { margin-top: 35px; }
WanSpi
28.05.2019 13:41+1И все же лучше с псевдоклассами, так как Ваш пример не будет коректно работать, к примеру:
<main class="content"> <p>Some text</p> <img src="picture.jpg" alt="some alt"> <div>Some text</div> </main>
Kesha_kh
28.05.2019 13:59или поменять селектор на:
.content img + * , .content * + img
WanSpi
28.05.2019 14:05Такой подход тоже имеет недостатки перед псевдоклассом, так как что если один из наших элементов, который стоит после изображения, должен иметь отступ сверху больше 35 пикселей? Из-за чего нужно помнить ставить приоритеты, или импортанты, лишняя память которую нужно держать в голове :)
Ну и к тому же лучше не забывать «хорошую» производительность селектора "*".
melnik909 Автор
28.05.2019 17:05Можно с использованием not написать так, что не потребуется сбрасывать отступы
tsukasa_mixer
28.05.2019 13:38+2какие-то извращения c :not.
Пишем проще и не ломаем людям голову
table:hover tr { opacity: .24; } table:hover tr:hover { opacity: 1; }
melnik909 Автор
28.05.2019 17:13-1В вашем способе создаются 3 правила: для основной стилизации tr, для стилизации tr при наведении на таблицу, стилизация tr при наведении на таблицу и строку. В моем 2 правила: основная стилизация вместе с opacity: 0.24 и стилизация при наведении на таблицу и строку.
MiXei4
29.05.2019 08:09Одно правило всегда лучше двух.
Просто представьте, что нам нужно менять не только прозрачность но и цвет текста, и фон и ещё что-то. Правила начинают расти, дублироваться. А потом поменяв в одном месте, забудем поменять в другом, что частично решается препроцессорами или переменными, но это и называется извращения, когда можно обойтись простым правилом — «примени это ко всем строкам таблицы под курсором, кроме собственно той под которой курсор».
Так же :not очень полезен для более частых случаев типа «примени ко всем строкам, кроме первой» и тп.
Manyaka
29.05.2019 20:50+1.content img:not(:first-child) { margin-top: 35px; } .content img:not(:last-child) { margin-bottom: 35px; }
Мне еще нравится через :not убирать margin-bottom в списках или у параграфов:
ul li:not(:last-child) { margin-bottom: 1em; }
melnik909 Автор
29.05.2019 20:55Manyaka, для списков, параграфов я тоже использую. А вот ваш пример кода я бы переписал так:
ul li:nth-child(n+2) { margin-top: 1em; }
Селектор проще в моем случае. Как думаете? Еще, если интересно, могу прислать в личные сообщения пару ссылку на мой инстаграм профайл, где я делюсь советами.Manyaka
29.05.2019 22:08Я думаю, что, что такое «n+2» надо ещё посчитать, а слово «last-child» более понятное, и кроме того, я придерживаюсь соглашения, когда марджины идут слева-направо (margin-right), сверху-вниз (margin-bottom), что соответствует русскому письму, кроме последних элементов, у которых этих марджинов нет, благодаря :not. Поэтому использование margin-top неприемлемо, в данном случае. Но ваш пример интересный.
Spaceoddity
29.05.2019 22:50Да что же вы такое городите?))
А как же семантика? Надо же вначале общие стили прописать, а потом всякую специфику. А вы это всё в одну цепочку селекторов пихаете. Last-child не подцепит прописанный отступ, зато может подцепить дефолтный. Или мы юзаем какой-нибудь normalize.css? Тогда в чём профит от такой сокращенной, но не очевидной записи?
melnik909 Автор
29.05.2019 22:59«марджины идут слева-направо (margin-right), сверху-вниз (margin-bottom)» Можете подсказать, где прочитать про это соглашение?
Spaceoddity
30.05.2019 03:44Ну это видимо сокращенная запись «margin:» (начиная с «margin-top» и по часовой) установленная W3C в качества стандарта. Только наоборот и в зеркальном отражении.
Manyaka
30.05.2019 05:50Например, тут на хабре: Организация отступов в верстке (margin/padding). Такая организация — не идея автора той статьи. Вот, некоторые англоязычные источники, в которых есть размышления на эту тему: Single-direction margin declarations, margin-bottom or margin-top. Вот статья в поддержку margin-top: CSS: margin top vs bottom
Spaceoddity
30.05.2019 07:32Да это же дичь какая-то))
Вот и выросло поколение верстальщиков, которые если и слышали о «схлопывании отступов», то по крайней мере не имеют представления как это используется.
andreymal
Строки — это фигня детсадовская, вот бы столбец выделить как-нибудь
Spaceoddity
Ну с псевдоэлементами можно поиграться:
css-tricks.com/simple-css-row-column-highlighting
zag2art
А есть ли решения без
и хаков типа?
Spaceoddity
Да, «display:grid» называются)
Keyten
Ну помимо какого-нибудь селектора типа contains… На css grid можно превратить строки в столбцы наверняка.