1

I want to decrease the font size of each element with increasing number in list:

<ul>
 <li>Number 1</li>
 <li>Number 2</li>
 <li>Number 3</li>
</ul>

Should result in something like

  • Number 1
  • Number 2
  • Number 3

where the first element has a font size of 25px, second has 20px, third has 15 px and so on.

Is there a way to do this with CSS only?

4ndro1d
  • 2,926
  • 7
  • 35
  • 65
  • 2
    Are the lists infinitely long? Is there a point at which you stop decreasing font size? – Serlite Sep 06 '16 at 16:33
  • `li {}, li + li {}, li + li +li {}`, or `nth-child` several times. – CBroe Sep 06 '16 at 16:35
  • Well basically I will not have more than 4 elements, but would love to see a solutions which respects an infinite list – 4ndro1d Sep 06 '16 at 16:43
  • 3
    Hm, then in the case of an infinite list, where is the limit for font size? I presume you don't want it decreasing to the point of unreadability... – Serlite Sep 06 '16 at 16:47
  • 1
    In case it wasn't already clear: there is no way to do this infinitely in CSS. Even with a programming language you would need to build in logic to eventually end the decrease at something like 1px or 1%. – skyline3000 Sep 06 '16 at 16:56
  • @4ndro1d my downvoted answer is 1 approach to an infinite list (i made it just as an example for you), but it cannot be done with pure CSS. For pure CSS you will use Jordans approach. – Adam Buchanan Smith Sep 06 '16 at 16:58

5 Answers5

5

You could achieve this effect by add the following CSS to your style sheet:

li:nth-child(1) {
    font-size: 25px;
}

li:nth-child(2) {
    font-size: 20px;
}

li:nth-child(3) {
    font-size: 15px;
}

li:nth-child(4) {
    font-size: 10px;
}

li:nth-child(4) {
    font-size: 5px;
}

As far as I know, there is no automated way of doing this in pure CSS. You would need to use JavaScript (or a JavaScript library like jQuery).

However, as the code sample above shows, the fifth LI element would be a font-size value of zero (which would render as invisible), and any after that would have a negative number for its value (which would be invalid).

Jordan Clark
  • 750
  • 5
  • 18
  • The fourth item is 5px font-size, the fifth item would have 25px font size, this is not good. – skobaljic Sep 06 '16 at 16:57
  • Agreed, the first `li` rule should probably be 5px (or whatever the smallest will be) so all subsequent items get the smallest font-size. – skyline3000 Sep 06 '16 at 17:00
  • 1
    Yes, but any more than 5 list elements would result in a value of zero or lower (which is arguably worse - at least from an accessibility/usability perspective). This is effectively what I am trying to point out in my answer. – Jordan Clark Sep 06 '16 at 17:01
  • Is there anyway to "calculate" the font size from the previous element? – 4ndro1d Sep 06 '16 at 17:07
  • 1
    @JordanClark you missed the point - we're not saying to go lower than 5px - we're saying the base selector rule for `li` which all `li` elements will inherit from should actually be the lowest font-size rather than the highest, and use `li:nth-child(1)` to set the highest. That way, if more list elements are added into the HTML later on, they will be font-size 5px rather than 25px (which would look awkward). – skyline3000 Sep 06 '16 at 17:26
  • @4ndro1d No, there is no previous sibling or parent selector in CSS. The best you could do is target the next sibling. – skyline3000 Sep 06 '16 at 17:27
  • 1
    @JordanClark, a reasonable fallback would be to change your final selector to `li:nth-child(n + 5)`, since the OP never specified what exactly he wanted in the scenario you're concerned with. Even if the font size can't be decreased further, subsequent items should probably still retain the last smallest font size. – Serlite Sep 06 '16 at 17:33
  • @skyline3000: Yes, you are right there. I have updated the code example to show this. In a real-world setting, though, this CSS would probably have a more specific selector, e.g. `#container li:nth-child(...)`. However, in any scenario, each list item would require an individual rule in the style sheet, hence my point and my answer to this question: there is NO automated way or elegant solution to achieve the effect the OP wants in CSS alone. – Jordan Clark Sep 06 '16 at 17:33
2

You don't need Javascript for this solution, you can do it purely in CSS.

CSS

li {
  font-size: 100%;
}

li:nth-child(1) {
  font-size: 90%;
}

li:nth-child(2) {
  font-size: 80%;
}

li:nth-child(3) {
  font-size: 70%;
}

li:nth-child(4) {
  font-size: 60%;
}

While this doesn't go infinitely deep, you mentioned that the max is 4, so this should be a good solution.

If you need to go infinitely deep, I suggest a JS solution, although the times when that is needed are few and far between.

Caleb Anthony
  • 1,105
  • 9
  • 19
  • The code was just for an example, you can add as many `:nth-child` elements as needed. I updated my answer for accuracy though. – Caleb Anthony Sep 06 '16 at 16:58
  • Not good, first set the minimum font-size for all list elements (for example: `li { font-size: 50%;}`), than for first 4. – skobaljic Sep 06 '16 at 16:59
0

Here is an example using JQuery, see example https://jsfiddle.net/kvb5hb6f/3/

This is setting the li font size starting at 25 and incriminating -5 then when the size hits 5 it does not go any smaller.

<ul id="numbers">
  <li>Number 1</li>
  <li>Number 2</li>
  <li>Number 3</li>
  <li>Number 4</li>
  <li>Number 5</li>
  <li>Number 6</li>
  <li>Number 7</li>
  <li>Number 8</li>
  <li>Number 9</li>
</ul>
<script>
  var listItems = $("#numbers li");
  var fontHeight = 25;
  listItems.each(function(idx, li) {
    var product = $(li);
    if (fontHeight >= 5) {
      $(product).css("fontSize", fontHeight + "px");
      fontHeight = fontHeight - 5;
    } else {
      fontHeight = 5;
      $(product).css("fontSize", fontHeight + "px");
    }
  });

</script>
Adam Buchanan Smith
  • 9,422
  • 5
  • 19
  • 39
  • 2
    "Is there a way to do this with CSS only?" Here is how to do it with jquery because it's great and does all the things. – PeeHaa Sep 06 '16 at 16:46
  • @PeeHaa from the OP's comments "Well basically I will not have more than 4 elements, but would love to see a solutions which respects an infinite list" keep up all the good downvoting :) – Adam Buchanan Smith Sep 06 '16 at 16:48
  • He did. In his question. – PeeHaa Sep 06 '16 at 16:53
0

Classes can be used to changed the size, add a class to each li element and the CSS can be created to change the size accordingly.

<ul>
 <li class="one">Number 1</li>
 <li class="two">Number 2</li>
 <li class="three">Number 3</li>
</ul>

This is a start: https://jsfiddle.net/he5gs4z0/2/

Related post: Can you use if/else conditions in CSS?

Community
  • 1
  • 1
JDavila
  • 409
  • 1
  • 7
  • 22
0

You can use the nth-child from css:

`<ul class='ultag'>
 <li>Number 1</li>
 <li>Number 2</li>
 <li>Number 3</li>
</ul>
<style>
 .ultag li:nth-child(1) { font-size: 25px; }
 .ultag li:nth-child(2) { font-size: 20px; }
 .ultag li:nth-child(3) { font-size: 15px; }
 .ultag li:nth-child(4) { font-size: 10px; }
</style>
`
goliath309
  • 11
  • 3