Home > Blockchain >  How to assure the correct text-content rendering into certain list items' ::before pseudo-eleme
How to assure the correct text-content rendering into certain list items' ::before pseudo-eleme

Time:09-28

I want to add an active class to every first element of the submenu (not to all the li's, only the first one from a bunch of li's with same first letter). and add the labels as A, B, C ----- i am achieving this with the css, but the problem is that it keeps adding labels to all, as i want the label to only first element. for example Brittle, britiana, bronze - it will add active class to first B only and same with the others.

how would i go about this?

.groupmenu-drop {
  max-width: 900px;
  margin: auto;
  column-count: 4;
  counter-reset: alphabeticList;
}
@media (max-width: 767px) {
  .groupmenu-drop {
    column-count: 1;
    margin-left: 40px;
  }
}
@media (min-width: 768px) and (max-width: 1024px) {
  .groupmenu-drop {
    column-count: 2;
    margin-left: 50px;
  }
}
.groupmenu-drop > .level1 {
  position: relative;
  padding: 0 0 14px !important;
  counter-increment: alphabeticList;
}
.groupmenu-drop > .level1 {
  padding-bottom: 5px;
}
.groupmenu-drop > .level1 a {
  font: 600 14px/30px 'Open Sans', sans-serif;
  letter-spacing: 0px;
  color: #166665;
}
.groupmenu-drop .level1:before {
  content: counter(alphabeticList, upper-alpha);
  position: absolute;
  top: 3px;
  left: -40px;
  border: 2px solid #166665;
  text-align: center;
  border-radius: 7px;
  font: bold 21px/34px 'Open Sans', sans-serif;
  letter-spacing: 0px;
  color: #095352;
  width: 27px;
  height: 27px;
  line-height: 23px;
}
.groupmenu-drop .level1:first-child:before {
  background-color: #166665;
  color: #fef6eb;
}
<ul >
  <li >
    <a
      
      href="/brands/angelcare.html"
      ><span>Angelcare</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/baby-art.html"
      ><span>Baby Art</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/barbie.html"
      ><span>Barbie</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/bibado.html"
      ><span>Bibado</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/boon.html"
      ><span>Boon</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/braun.html"
      ><span>Braun</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/diono.html"
      ><span>Diono</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/disney.html"
      ><span>Disney</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/dorel.html"
      ><span>Dorel</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/dr-brown-s.html"
      ><span>Dr Brown's</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/dreambaby.html"
      ><span>Dreambaby</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/dreamgenii.html"
      ><span>Dreamgenii</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/dumbo.html"
      ><span>Dumbo</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/earth-friendly-baby.html"
      ><span>Earth Friendly Baby</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/east-coast.html"
      ><span>East Coast</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/fisher-price.html"
      ><span>Fisher-Price</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/fisher-price-little-people.html"
      ><span>Fisher-Price Little People</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/flair.html"
      ><span>Flair</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/gift-wrap-accessories.html"
      ><span>Gift Wrap Accessories</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/halilit.html"
      ><span>Halilit</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/hey-clay.html"
      ><span>Hey Clay</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/hot-wheels.html"
      ><span>Hot Wheels</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/infantino.html"
      ><span>Infantino</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/janod.html"
      ><span>Janod</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/kaloo.html"
      ><span>Kaloo</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/keel-toys.html"
      ><span>Keel Toys</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/lalaboom.html"
      ><span>Lalaboom</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/lamaze.html"
      ><span>Lamaze</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/lansinoh.html"
      ><span>Lansinoh</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/leap-frog.html"
      ><span>Leap Frog</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/lindam.html"
      ><span>Lindam</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/little-bird-told-me.html"
      ><span>Little Bird Told Me</span></a
    >
  </li>
  <li >
    <a  href="/brands/mam.html"
      ><span>MAM</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/mattel.html"
      ><span>Mattel</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/medela.html"
      ><span>Medela</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/mega-bloks.html"
      ><span>Mega Bloks</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/milton.html"
      ><span>Milton</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/munchkin.html"
      ><span>Munchkin</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/my-garden-baby.html"
      ><span>My Garden Baby</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/nuby.html"
      ><span>Nuby</span></a
    >
  </li>
  <li >
    <a  href="/brands/nuk.html"
      ><span>NUK</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/philips-avent.html"
      ><span>Philips Avent</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/plasticine.html"
      ><span>Plasticine</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/playmobil.html"
      ><span>Playmobil</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/ragtales.html"
      ><span>Ragtales</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/safety-first.html"
      ><span>Safety First</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/schleich.html"
      ><span>Schleich</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/summer-infant.html"
      ><span>Summer Infant</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/swaddleme.html"
      ><span>SwaddleMe</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/taf-toys.html"
      ><span>Taf Toys</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/thomas-and-friends.html"
      ><span>Thomas and Friends</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/tiny-love.html"
      ><span>Tiny Love</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/tommee-tippee.html"
      ><span>Tommee Tippee</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/tomy.html"
      ><span>Tomy</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/vicks.html"
      ><span>Vicks</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/vital-baby.html"
      ><span>Vital Baby</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/vtech.html"
      ><span>vTech</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/we-made-me.html"
      ><span>We Made Me</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/widdop-bingham.html"
      ><span>Widdop Bingham</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/winnie-the-pooh.html"
      ><span>Winnie The Pooh</span></a
    >
  </li>
</ul>

Output i am getting: https://paste.pics/be37c962a84545356f416db149368a92

i want to achieve like the screen shot below: https://paste.pics/ff36dd98eb6fcf126004b581ac466f93

CodePudding user response:

The approach is straightforward.

  • One queries a node list of all of a navigation/link-list's direct children ... document.querySelectorAll('.groupmenu-drop > li').

  • Following up one creates an Array.from this node list and mapss it into an array of mutated list-item elements which each gets assigned its text-content's first letter-character as value of an own data-first-char-attribute.

  • Then one reduces all items into an array of list-item elements which each start with a different letter than their directly preceding list-item.

  • Finally forEach collected new first-character list-item one adds a related class-name like new-first-char.

  • In the same time one would slightly change some selector rules

    • The ::before pseudo-element rendering would be covered by a changed rule like ...

      .groupmenu-drop .level1.new-first-char::before {
         content: attr(data-first-char);
      }
      

      ... which targets every list-item that features a new-first-char class-name , and where the latter's content gets rendered by the value of this very element's data-first-char attribute.

    • The active/selected state of such pseudo-elements then just needs to be targeted by ...

      .groupmenu-drop .level1.new-first-char.selected::before {
         background-color: #166665;
         color: #fef6eb;
      }
      

One has to at least touch the list elements where the pseudo-element rendering takes place because one can not rely anymore on the OP's original content rendering via the counter css-function. This is due to the OP's design of a single flat/non-nested list which by the OP's original counter-functionality forces the continuous alphabetical pseudo-element enumeration for each list item.

Therefore it is best to target the pseudo-element rendering by just a class-name like new-first-char where the pseudo-element's content gets rendered from this very element's data-first-char attribute-value.

function init() {

  const newFirstCharacterItems = Array
    .from(
      document
        .querySelectorAll('.groupmenu-drop > li')
    )
    .map(elmNode => {

      const textContent = elmNode
        .querySelector('a > span')
        ?.textContent ?? '';

      let char = textContent
        .trim()
        // https://www.regular-expressions.info/unicode.html#category
        .match(/\p{L}/u) // first letter character.
        ?.[0] ?? '';

      char = char
        .toUpperCase();

      elmNode
        .dataset
        .firstChar = char;

      return elmNode;
    })
    .reduce(({ currentCharacter = '', result }, elmNode) => {

      const char = elmNode
        .dataset
        .firstChar;

      if (char !== '' && char !== currentCharacter) {

        currentCharacter = char;
        result
          .push(elmNode);
      }
      return { currentCharacter, result };

    }, { result: [] }).result;

    newFirstCharacterItems
      .forEach(elmNode =>
        elmNode
          .classList
          .add('new-first-char')
      );
}

init();
body { margin: 0; zoom: .7; }

.groupmenu-drop {
  max-width: 900px;
  margin: auto;
  column-count: 4;
  counter-reset: alphabeticList;

  /* additional fix */
  list-style: none;
}
@media (max-width: 767px) {
  .groupmenu-drop {
    column-count: 1;
    margin-left: 40px;
  }
}
@media (min-width: 768px) and (max-width: 1024px) {
  .groupmenu-drop {
    column-count: 2;
    margin-left: 50px;
  }
}
.groupmenu-drop > .level1 {
  position: relative;
  padding: 0 0 14px !important;
  counter-increment: alphabeticList;
}
.groupmenu-drop > .level1 {
  padding-bottom: 5px;
}
.groupmenu-drop > .level1 a {
  font: 600 14px/30px 'Open Sans', sans-serif;
  letter-spacing: 0px;
  color: #166665;
}

/* slightly changed selector */
.groupmenu-drop .level1.new-first-char::before {
  /*content: counter(alphabeticList, upper-alpha);*/

  /* changed content rendering */
  content: attr(data-first-char);

  position: absolute;
  top: 3px;
  left: -40px;
  border: 2px solid #166665;
  text-align: center;
  border-radius: 7px;
  font: bold 21px/34px 'Open Sans', sans-serif;
  letter-spacing: 0px;
  color: #095352;
  width: 27px;
  height: 27px;
  line-height: 23px;
}
/* slightly changed selector */
.groupmenu-drop .level1.new-first-char.selected::before {
  background-color: #166665;
  color: #fef6eb;
}
<ul >
  <li >
    <a
      
      href="/brands/angelcare.html"
      ><span>Angelcare</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/baby-art.html"
      ><span>Baby Art</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/barbie.html"
      ><span>Barbie</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/bibado.html"
      ><span>Bibado</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/boon.html"
      ><span>Boon</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/braun.html"
      ><span>Braun</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/diono.html"
      ><span>Diono</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/disney.html"
      ><span>Disney</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/dorel.html"
      ><span>Dorel</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/dr-brown-s.html"
      ><span>Dr Brown's</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/dreambaby.html"
      ><span>Dreambaby</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/dreamgenii.html"
      ><span>Dreamgenii</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/dumbo.html"
      ><span>Dumbo</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/earth-friendly-baby.html"
      ><span>Earth Friendly Baby</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/east-coast.html"
      ><span>East Coast</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/fisher-price.html"
      ><span>Fisher-Price</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/fisher-price-little-people.html"
      ><span>Fisher-Price Little People</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/flair.html"
      ><span>Flair</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/gift-wrap-accessories.html"
      ><span>Gift Wrap Accessories</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/halilit.html"
      ><span>Halilit</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/hey-clay.html"
      ><span>Hey Clay</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/hot-wheels.html"
      ><span>Hot Wheels</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/infantino.html"
      ><span>Infantino</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/janod.html"
      ><span>Janod</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/kaloo.html"
      ><span>Kaloo</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/keel-toys.html"
      ><span>Keel Toys</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/lalaboom.html"
      ><span>Lalaboom</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/lamaze.html"
      ><span>Lamaze</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/lansinoh.html"
      ><span>Lansinoh</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/leap-frog.html"
      ><span>Leap Frog</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/lindam.html"
      ><span>Lindam</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/little-bird-told-me.html"
      ><span>Little Bird Told Me</span></a
    >
  </li>
  <li >
    <a  href="/brands/mam.html"
      ><span>MAM</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/mattel.html"
      ><span>Mattel</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/medela.html"
      ><span>Medela</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/mega-bloks.html"
      ><span>Mega Bloks</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/milton.html"
      ><span>Milton</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/munchkin.html"
      ><span>Munchkin</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/my-garden-baby.html"
      ><span>My Garden Baby</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/nuby.html"
      ><span>Nuby</span></a
    >
  </li>
  <li >
    <a  href="/brands/nuk.html"
      ><span>NUK</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/philips-avent.html"
      ><span>Philips Avent</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/plasticine.html"
      ><span>Plasticine</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/playmobil.html"
      ><span>Playmobil</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/ragtales.html"
      ><span>Ragtales</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/safety-first.html"
      ><span>Safety First</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/schleich.html"
      ><span>Schleich</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/summer-infant.html"
      ><span>Summer Infant</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/swaddleme.html"
      ><span>SwaddleMe</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/taf-toys.html"
      ><span>Taf Toys</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/thomas-and-friends.html"
      ><span>Thomas and Friends</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/tiny-love.html"
      ><span>Tiny Love</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/tommee-tippee.html"
      ><span>Tommee Tippee</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/tomy.html"
      ><span>Tomy</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/vicks.html"
      ><span>Vicks</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/vital-baby.html"
      ><span>Vital Baby</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/vtech.html"
      ><span>vTech</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/we-made-me.html"
      ><span>We Made Me</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/widdop-bingham.html"
      ><span>Widdop Bingham</span></a
    >
  </li>
  <li >
    <a
      
      href="/brands/winnie-the-pooh.html"
      ><span>Winnie The Pooh</span></a
    >
  </li>
</ul>

CodePudding user response:

Suppose the HTML list is in the alphabet order. I will retrieve the list using the query selector method first. Then loop and compare the text inside, if the characters are different then add an active class to the element.

<div >
    <div >
        <div >
            <a  href="#"><span>Albama</span></a>
        </div>
        <div >
            <a  href="#"><span>Brittle</span></a>
        </div>
        <div >
            <a  href="#"><span>Beat</span></a>
        </div>
    </div>
</div>

<script>
    let elements = document.querySelectorAll('.mainbrain-item > .menu-link > span');

    let firstLeter = '';
    for (const element of elements) {
        if(firstLeter !== element.text[0].toLowerCase()){

            // select the parent element which is the div with mainbraind-item class
            element.parentElement.parentElement.classList.add('active');
            firstLeter = element.text[0].toLowerCase();
        }
    }
</script>

Updated based on the structure OP provided. I added the .active selector in the css code

     <style>
        /* ..... */

        .groupmenu-drop .level1.active:before {
            content: counter(alphabeticList, upper-alpha);
            position: absolute;
            top: 3px;
            left: -40px;
            border: 2px solid #166665;
            text-align: center;
            border-radius: 7px;
            font: bold 21px/34px 'Open Sans', sans-serif;
            letter-spacing: 0px;
            color: #095352;
            width: 27px;
            height: 27px;
            line-height: 23px;
        }

        /* ... */
    </style>


    <ul >
        <li >
            <a  href="/brands/angelcare.html"><span>Angelcare</span></a>
        </li>
        <li >
            <a  href="/brands/baby-art.html"><span>Baby Art</span></a>
        </li>
        <li >
            <a  href="/brands/barbie.html"><span>Barbie</span></a>
        </li>
    </ul>


    <script>
        document.addEventListener("DOMContentLoaded", function () {
            // code...
            let elements = document.querySelectorAll('.groupmenu-drop > .item > .menu-link > span');

            let firstLeter = '';
            for (const element of elements) {
                if (firstLeter !== element.textContent[0].toLowerCase()) {
                    let level1El = element.parentElement.parentElement;
                    level1El.classList.add('active');
                    firstLeter = element.textContent[0].toLowerCase();
                }
            }
        });
    </script>
  • Related