Изучаем принцип работы псевдокласса :not() на примере задачи «Выделение активной строки таблицы на чистом CSS»

    Несколько дней назад мой друг попросил помочь с решением задачи, которая была на его собеседовании. Интервьюер дал ему следующий фрагмент кода:


    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>
    
    Поддержать автора
    Поделиться публикацией

    Комментарии 28

      +4

      Строки — это фигня детсадовская, вот бы столбец выделить как-нибудь

        0
        Ну с псевдоэлементами можно поиграться:
        css-tricks.com/simple-css-row-column-highlighting
          +1
          А есть ли решения без
          overflow: hidden;
          
          и хаков типа
            top: -5000px;
            height: 10000px;
          
          ?
            0
            Да, «display:grid» называются)
          0
          Ну помимо какого-нибудь селектора типа contains… На css grid можно превратить строки в столбцы наверняка.
          +2
          Это что за «задачи» такие?))
          .content img:first-child{
            margin-top:0;
          }
          .content img:last-child{
            margin-bottom:0;
          }
            +1
            С тем что сейчас встречаются «фронтенд» разрабы не умеющие верстать, не удивительно появление таких задачек
            p.s. Можно вообще без псевдоклассов
            .content img + p ,
            .content p + img {
            margin-top: 35px;
            }
              +1
              И все же лучше с псевдоклассами, так как Ваш пример не будет коректно работать, к примеру:
              <main class="content">
                <p>Some text</p>
                <img src="picture.jpg" alt="some alt">
                <div>Some text</div>
              </main>
              
                0
                или поменять селектор на:
                .content img + * ,
                .content * + img 
                  +2
                  Такой подход тоже имеет недостатки перед псевдоклассом, так как что если один из наших элементов, который стоит после изображения, должен иметь отступ сверху больше 35 пикселей? Из-за чего нужно помнить ставить приоритеты, или импортанты, лишняя память которую нужно держать в голове :)
                  Ну и к тому же лучше не забывать «хорошую» производительность селектора "*".
                –2

                Для меня вёрстка всегда была, есть и будет темной стороной фронтенда. Не умею я мыслить как верстальщик. И не стесняюсь в этом признаться Но одно дело технично реализовывать то, что все умеют и совсем другое создавать что-то новое. Я по-прежнему не вижу гур, работающих с SVG или решающих нетривиальные для обычного кодера вещи от кого можно было бы получать компетентные знания близкие к канонически верным. Без оверхеда.

                  0
                  Работать с SVG не так уж и сложно, по сути это обычный XML, со своими особеносвтями и векторной графикой, ничего сложного там нету, проблема возникает лишь при больших SVG, но опять же, разобраться не состовлет проблем.
                    –1

                    Вы попробуйте сравнить drag and drop для элементов входящих в группу SVG и для вложенных dom элементов и найдите отличия. Покажите мне пожалуйста хотя бы одно каноническое решение.

                      +1
                      D&D в SVG, месье, снимаю перед вами шляпу, я думал что видел все в этой жизни верстальщика :)
                      Но ради интереса хочу спросить, какие то есть подводные камни? Просто даже не хочу пробовать.
                0
                Можно с использованием not написать так, что не потребуется сбрасывать отступы
                +9

                какие-то извращения c :not.
                Пишем проще и не ломаем людям голову


                table:hover tr {
                    opacity: .24;
                }
                
                table:hover tr:hover {
                    opacity: 1;
                }
                  –1
                  В вашем способе создаются 3 правила: для основной стилизации tr, для стилизации tr при наведении на таблицу, стилизация tr при наведении на таблицу и строку. В моем 2 правила: основная стилизация вместе с opacity: 0.24 и стилизация при наведении на таблицу и строку.
                    +1
                    Одно правило всегда лучше двух.
                    Просто представьте, что нам нужно менять не только прозрачность но и цвет текста, и фон и ещё что-то. Правила начинают расти, дублироваться. А потом поменяв в одном месте, забудем поменять в другом, что частично решается препроцессорами или переменными, но это и называется извращения, когда можно обойтись простым правилом — «примени это ко всем строкам таблицы под курсором, кроме собственно той под которой курсор».

                    Так же :not очень полезен для более частых случаев типа «примени ко всем строкам, кроме первой» и тп.
                    +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;
                    }
                    
                      0
                      Manyaka, для списков, параграфов я тоже использую. А вот ваш пример кода я бы переписал так:

                      ul li:nth-child(n+2) {
                        margin-top: 1em;
                      }
                      


                      Селектор проще в моем случае. Как думаете? Еще, если интересно, могу прислать в личные сообщения пару ссылку на мой инстаграм профайл, где я делюсь советами.
                        0
                        Я думаю, что, что такое «n+2» надо ещё посчитать, а слово «last-child» более понятное, и кроме того, я придерживаюсь соглашения, когда марджины идут слева-направо (margin-right), сверху-вниз (margin-bottom), что соответствует русскому письму, кроме последних элементов, у которых этих марджинов нет, благодаря :not. Поэтому использование margin-top неприемлемо, в данном случае. Но ваш пример интересный.
                          0
                          Да что же вы такое городите?))
                          А как же семантика? Надо же вначале общие стили прописать, а потом всякую специфику. А вы это всё в одну цепочку селекторов пихаете. Last-child не подцепит прописанный отступ, зато может подцепить дефолтный. Или мы юзаем какой-нибудь normalize.css? Тогда в чём профит от такой сокращенной, но не очевидной записи?
                            0
                            «марджины идут слева-направо (margin-right), сверху-вниз (margin-bottom)» Можете подсказать, где прочитать про это соглашение?
                              0
                              Ну это видимо сокращенная запись «margin:» (начиная с «margin-top» и по часовой) установленная W3C в качества стандарта. Только наоборот и в зеркальном отражении.
                                0
                                Например, тут на хабре: Организация отступов в верстке (margin/padding). Такая организация — не идея автора той статьи. Вот, некоторые англоязычные источники, в которых есть размышления на эту тему: Single-direction margin declarations, margin-bottom or margin-top. Вот статья в поддержку margin-top: CSS: margin top vs bottom
                                  0
                                  Да это же дичь какая-то))
                                  Вот и выросло поколение верстальщиков, которые если и слышали о «схлопывании отступов», то по крайней мере не имеют представления как это используется.
                                    0
                                    Как вообще можно называться верстальщиком, не зная о схлопывании отступов? Это ведь основа верстания.
                                    0
                                    Manyaka Спасибо!

                          Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                          Самое читаемое