Shabrina Fitri
Shabrina Fitri

Reputation: 13

Different content for each "::before" pseudo-element

How can we give different content to each ::before pseudo-element? My code looks like this:

.timeline h1::before {
  position: absolute;
  font-size: inherit;
  left: 0;
}

.timeline h1:first-of-type:before {
  content: '01';
  color: #E82F3A;
}

.timeline h1:nth-of-type(2):before {
  content: '02';
  color: #E82F3A;
}

.timeline h1:last-of-type:before {
  content: '03';
  color: #E82F3A;
}

.timeline h1 {
  position: relative;
  color: #404C60;
  padding-left: 35px;
  font-size: 1.8rem;
}
<div class="timeline">
  <div>
    <h1>Heading</h1>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
      in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    </p>
  </div>
  <div>
    <h1>Heading</h1>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
      in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    </p>
  </div>
  <div>
    <h1>Heading</h1>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
      in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    </p>
  </div>
</div>

I want the first <h1>'s ::before pseudo-element to have content '01', the second's to have content '02', and the last's to have content '03'. But when I try the code, all the <h1>'s ::before content is '03'. What's wrong?

Upvotes: 1

Views: 103

Answers (3)

AuxTaco
AuxTaco

Reputation: 5181

The :first-of-type, :nth-of-type, and :last-of-type pseudo-classes refer to the first/nth/last elements among siblings. Since your <h1>s are each wrapped in their own <div>s, they match both :first-of-type and :last-of-type, and the rule defined later wins.

Instead of dealing with all that, you can use CSS counters.

.timeline {
  counter-reset: my-counter;
}

.timeline h1::before {
  content: counter(my-counter, decimal-leading-zero);
  counter-increment: my-counter;
}

/* the rest is your original code */
.timeline h1::before {
  position: absolute;
  font-size: inherit;
  left: 0;
  color: #E82F3A;
}

.timeline h1 {
  position: relative;
  color: #404C60;
  padding-left: 35px;
  font-size: 1.8rem;
}
<div class="timeline">
  <div>
    <h1>Heading</h1>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
      in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    </p>
  </div>
  <div>
    <h1>Heading</h1>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
      in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    </p>
  </div>
  <div>
    <h1>Heading</h1>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
      in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    </p>
  </div>
</div>

Breaking it down:

.timeline {
  counter-reset: my-counter;
}

We're creating a new counter called my-counter. It needs to be initialized before we can use it. counter-reset handles that. Every .timeline has a my-counter counter that starts at 0. We'll be incrementing it in the h1::before pseudo-element, so the numbers that actually display start at 1.

.timeline h1::before {
  content: counter(my-counter, decimal-leading-zero);
  counter-increment: my-counter;
}

Here we set the content of the h1::before pseudo-element to the value of our my-counter counter and apply the decmial-leading-zero list style to it with counter. counter-increment increases the value of my-counter by 1 before it is displayed.

Upvotes: 1

connexo
connexo

Reputation: 56803

Each h1 in your example is first-of-type since the counting resets on every new parent div, so you need to work with div:nth-of-type h1::before.

div h1::before {
  position: absolute;
  font-size: inherit;
  left: 0;
}

div:nth-of-type(1) h1::before {
  content: '01';
  color: #E82F3A;
}

div:nth-of-type(2) h1::before {
  content: '02';
  color: #E82F3A;
}

div:nth-of-type(3) h1::before {
  content: '03';
  color: #E82F3A;
}

div h1 {
  position: relative;
  color: #404C60;
  padding-left: 35px;
  font-size: 1.8rem;
}
<div>
  <h1>Heading</h1>
  <p>
    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
    in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
  </p>
</div>
<div>
  <h1>Heading</h1>
  <p>
    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
    in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
  </p>
</div>
<div>
  <h1>Heading</h1>
  <p>
    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
    in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
  </p>
</div>

If your really want numbers, you can use a CSS counter:

body {
  counter-reset: section;
}

div h1::before {
  counter-increment: section;
  position: absolute;
  font-size: inherit;
  left: 0;
  content: "0"counter(section);
  color: #E82F3A;
}

div:nth-of-type(10) h1::before,
div:nth-of-type(10) ~ div h1::before {
  content: counter(section);
}

div h1 {
  position: relative;
  color: #404C60;
  padding-left: 35px;
  font-size: 1.8rem;
}
<div>
  <h1>Heading</h1>
  <p>
    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
    in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
  </p>
</div>
<div>
  <h1>Heading</h1>
  <p>
    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
    in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
  </p>
</div>
<div>
  <h1>Heading</h1>
  <p>
    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
    in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
  </p>
</div>

Upvotes: 1

Lajos Arpad
Lajos Arpad

Reputation: 76968

You will need the nth-child selector. Since your divs are siblings, you could create a CSS rule which would include that and their child. Assuming that the parent of the divs has an id of foobar, an example might be something like this:

#foobar :nth-child(3) h1::before {
    /*your rule*/
}

Upvotes: 1

Related Questions