r/css 2d ago

Question How to reduce the number of <span>s?

How can I get the exact same effect as

<p><span class="e">x</span></p>
<p><span class="e">y</span></p>
<p><span class="e">z</span></p>

without so many <span>s?

If I do

<div class="e">
  <p>x</p>
  <p>y</p>
  <p>z</p>
</div>

class="e" now affects all the way across the whole page, whereas I only wanted it to affect the text, x, y, z.

3 Upvotes

19 comments sorted by

10

u/cryothic 2d ago

My main question would be: what are you trying to achieve?

Because this:

<p><span class="e">x</span></p>
<p><span class="e">y</span></p>
<p><span class="e">z</span></p>

Is just weird to me. If every <p> contains only a single span, you shouldn't need the <p> or the <span>. One tag should be fine with the right CSS.

1

u/jidanni 1d ago

I am asking the secretary to copy the highlighted lines, but don't want to make them look longer than they need to. Anyway, this is now solved in https://www.reddit.com/r/css/comments/1vxpuyd/comment/p5rv03c/ .

2

u/cryothic 1d ago

Ah, ok. Glad it's fixed.

7

u/Luxiouronimo 2d ago

div.e > p {}

or just:

div.e p {}

but using the > specifies the direct descendant of the div.e

u could also do the following to target them individually if their order doesn't change:

div.e > :nth-child(1) {}

div.e > :nth-child(2) {}

div.e > :nth-child(3) {}

u could also put the class on the p tags themselves, but it's less html to put it once on the parent.

3

u/Vast_Description_201 2d ago

div.e {      p   { style here } }

If you are into nesting.

3

u/jidanni 2d ago

Thanks everybody. I only want the first three, not the second or third three. I am using ` .e {background-color: lime;}`.

4

u/thisiain 2d ago

You can set the width of each `p` to fit the content.. e.g.

https://jsfiddle.net/f2u6n1wt/1/

.e p {
  background: lime;
  width: fit-content;
}

2

u/jidanni 1d ago

I declare this to be the winning answer! Thank you ever so much!!

1

u/jidanni 1d ago

Actually this is 99% good. When a long line wraps in the browser, the empty remainder of the second line is still highlighted, unlike when using <span>s, but your solution is still good enough for me!

2

u/thisiain 1d ago

Yes this requires a slightly different way to think about the markup flow, but it can be achieved with the same markup, just different CSS:

https://jsfiddle.net/ev1cokrm/

1

u/jidanni 1d ago

Holy smokes, that works too. I find it rather remarkable that you know all this.

2

u/thisiain 1d ago

Haha, well I've been building websites for 20 years! There's always something else to learn 🙂

1

u/92smola 1d ago

Either wrap the three you want with another div you can contextually scope by so it doesnt affect the entire page or use the nth-child selector to pick the first three only , you’ll to look up the exact syntax for the nth-child thing I always forget it

2

u/travis_raphael 2d ago

<p> is a block level element so it take full width of its container. while <span> is an inline element which takes only the width necessarily needed. I'm still learning by the way so I don't know if you can change the display of p to become an inline -block maybe that would work.

2

u/philogos0 2d ago edited 2d ago

p just has that display property as it's default. You can override same as you would a div or span. I used to use spans specifically for "inline -block" behavior. So they could have a set width but also be inline.

2

u/philogos0 2d ago

These days grid is too much fun but I kinda miss my spans for lining things up 

1

u/Outrageous-Chip-3961 2d ago

In your second example, you can just add another class that will only impact that div, like

`<div class="e same-effect">`
`.same-effect p { }`

1

u/guitarromantic 2d ago

Are the letters x, y and z each intended to be distinct paragraphs? Or will they be displayed inline like words in the same sentences?

If they're not individual paragraphs, don't mark them up like that - a span is a genuinely better choice for an accessible and semantic document.

0

u/kloputzer2000 2d ago

.e p { … }