HTML + CSS: Numbered list with numbers inside of c

2019-01-08 09:01发布

问题:

I'm trying to create an ordered list in CSS + HTML that looks like this:

I can't for the life of me figure out how to do this. I've tried using list-image but then the numerals don't appear. I tried setting a background, but it won't appear behind the number if list-style-position is set to outside. I tried setting it with a background and list-style-position: inside, then putting the text inside the li in a div to align it, but no combination of floats, margins, etc worked without wrapping around the numeral.

This seems like something I've seen on plenty of web sites, but at the moment I can't seem to find a working example, nor is Googling for this giving me any results.

So, can anyone help me with this? How would you create the above using HTML+CSS, ideally without using JS, and definitely without using just images. This text needs to be selectable and copy/pasteable.

Because a commenter asked, here's the markup I have right now:

<ol>
  <li><span>List item one.</span></li>
  <li><span>List item two.</span></li>
  <li><span>List item three.</span></li>
</ol>

None of the CSS I've tried has even come close to working, so I'm not sure the value of sharing what I have currently. Here's one version that failed...

ol { display: block; list-style: decimal outside url('/images/lists/yellow-circle-18px.png'); }
ol li { width: 176px; margin-right: 20px; float: left; }
ol li span { display: block; }

回答1:

The horizontal layout aspect of the question can be achieved using CSS float and/or display:inline-block;. These are well documented for this, as list elements are often used for creating drop-down menus using this technique, so I won't discuss it further here.

The circled number aspect is a bit more tricky.

It can't be achieved using standard list styles, unless you're prepared to use graphics, and hard-code the image name each one. This is quite an old-school approach, and I suspect it's not what you're looking for.

One idea that popped into my head would be to use a font that has its numbers in circles, such as this one, and then simply style the <ol> element to use that font, and the <li> element to use your regular font. The down-side of this is that you'd have to keep your list below 10 items, and the user's browser would need to download a whole font just for that. Also, you would need to pick one that matched the other fonts on your site. Probably not an ideal solution, but it would work.

A more practical solution would be to abandon the list style entirely (still use the same HTML markup, but set list-style:none;). The numbers would then be inserted using CSS's little-used :before and count() features.

In your case, it would be along the following lines:

ol ul:before {
    content: counter(mylist);
}

This will give you the same numbered sequence. You would then need to add further styles to the selector above to give it a circle background, some colours, and a bit of margin. You would also need to style the <li> element somehow so that its entire text was indented from the number rather than wrapping below the number. I expect this could be done with display:inline-block; or similar.

It might need a bit of experimentation, and I haven't given the complete answer, but the technique would definitely work.

See quirksmode.org for a writeup and examples, along with a browser compatibility chart.

And the browser compatibility chart gives a clue as to the one major down-side of this technique: It won't work in IE7 or earlier. It does work in IE8 though, and in all other browsers, so if you can live with IE7 users not seeing it (and there aren't that many of them these days), then it should be fine.



回答2:

I'm using ideas that @Spudley has in his answer, and I'm using ideas from a previous answer I wrote:

  • How to use CSS to surround a number with a circle?

See: http://jsfiddle.net/j2gK8/

IE8 does not support border-radius, and workarounds like CSS3 PIE do not work with :before. And, older browsers like IE7 do not support counter.

If you want to make it work in older browsers, you'll have to resort to writing the numbers yourself. I also exchanged the fancy rounded corners for a normal image (which could have rounded corners, but doesn't in my example):

See: http://jsfiddle.net/XuHNF/

So, there's the fancy approach that won't work in IE7+IE8, which probably rules it out. And then there's the ugly, but compatible method.

Of course, there's always another problem. If you have differing amounts of text, then this happens.

You're then looking at this problem:

  • CSS Floating Divs At Variable Heights
  • https://stackoverflow.com/search?q=user%3A405015+masonry


回答3:

If anyone is still reading this, I encountered the same issue and found a tutorial that was extremely helpful.

Styling ordered list numbers

ol {
    counter-reset:li; /* Initiate a counter */
    margin-left:0; /* Remove the default left margin */
    padding-left:0; /* Remove the default left padding */
}
ol > li {
    position:relative; /* Create a positioning context */
    margin:0 0 6px 2em; /* Give each list item a left margin to make room for the numbers */
    padding:4px 8px; /* Add some spacing around the content */
    list-style:none; /* Disable the normal item numbering */
    border-top:2px solid #666;
    background:#f6f6f6;
}
ol > li:before {
    content:counter(li); /* Use the counter as content */
    counter-increment:li; /* Increment the counter by 1 */
    /* Position and style the number */
    position:absolute;
    top:-2px;
    left:-2em;
    -moz-box-sizing:border-box;
    -webkit-box-sizing:border-box;
    box-sizing:border-box;
    width:2em;
    /* Some space between the number and the content in browsers that support
       generated content but not positioning it (Camino 2 is one example) */
    margin-right:8px;
    padding:4px;
    border-top:2px solid #666;
    color:#fff;
    background:#666;
    font-weight:bold;
    font-family:"Helvetica Neue", Arial, sans-serif;
    text-align:center;
}
li ol,
li ul {margin-top:6px;}
ol ol li:last-child {margin-bottom:0;}


回答4:

I think I found out a solution for that. Your HTML code would be

<ol>
   <li>First item</li>
   <li>Second item</li>
</ol>

If you apply the following styles, it gets quite like a circle:

ol {margin-left:0; padding-left:0; counter-reset:item}
ol>li {margin-left:0; padding-left:0; counter-increment:item; list-style:none inside;margin-bottom:10px}
ol>li:before {
content:"(" counter(item) ")";
padding:3px 5px;
margin-right:0.5em;
background:#ccc;
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px; 
}

I would then play around with paddings and radius in order to make it appear as a circle



回答5:

EDIT: I changed up the code so try and match what you have

I tried to do this with a carousel that I was making with an image and link inside of each list item like this:

   <ol id = "list">
     <li class = "listItems">
       <!-- Image -->
       <img src = "YourImage" class = "listNumber"></div>
       <!-- Text -->
       <div class = "listInfo">Info goes here</div>
     </li> 
   </ol>

and so on for each item. To get them to appear horizontally my css looked like this:

#list
{
    list-style: none;
    width: 5000px;  /* Total width of list IMPORTANT*/
}
    /* Image gallery list item*/
    #list li
    {
        float :left;    /* Arranges the items in a horizontal list IMPORTANT */
    }

That made all images line up horizontally. To edit each item inside the list you will need to place them in divs and then edit the css from there. Once you have them all floating the same way the css inside the divs shouldn't give you problem. You can just style them by class like this:

.listNumber
{
  postion: absolute;
  left: (#)px;
  top: (#)px;
}

I also remember that i needed to makes sure the list was at least the width of each item in it before I could float them all left. If it wasn't, then they would sit on the bottom.



回答6:

I find that browsers position list-style-image at various places and one has only the "outside" & "inside" position control.

I recommend the following:

http://jsfiddle.net/vEZHU/

NOTE: You can also use float to lay them out or what I did. Also, this asumes you know of sprites.

Hope this makes sense.



回答7:

I would use flexbox and add 'divs' to the 'li' containing the number.

    <div class="container">
<ul class="info-list">
  <li><div>1.</div> CPellentesque eget nunc sit amet urna ullamcorper fermentum et eu leo. Nunc vel nibh tempor, pharetra lectus congue, luctus orci.
  </li>
  <li><div>2.</div>CPellentesque eget nunc sit amet urna ullamcorper fermentum et eu leo. Nunc vel nibh tempor, pharetra lectus congue, luctus orci.
  </li>
  <li><div>3.</div>CPellentesque eget nunc sit amet urna ullamcorper fermentum et eu leo. Nunc vel nibh tempor, pharetra lectus congue, luctus orci.
  </li>
</ul>
<ul class="info-list">
  <li><div>4.</div> CPellentesque eget nunc sit amet urna ullamcorper fermentum et eu leo. Nunc vel nibh tempor, pharetra lectus congue, luctus orci.
  </li>
  <li><div>5.</div>CPellentesque eget nunc sit amet urna ullamcorper fermentum et eu leo. Nunc vel nibh tempor, pharetra lectus congue, luctus orci.
  </li>
  <li><div>6.</div>CPellentesque eget nunc sit amet urna ullamcorper fermentum et eu leo. Nunc vel nibh tempor, pharetra lectus congue, luctus orci.
  </li>
</ul>
</div>

CSS:

.container {
  display: flex;
}
.info-list li {
  list-style: none;
  display: flex;
}
.info-list li > div {
  display: inline-block;
  border: 2px solid #ccc;
  border-radius: 100%;
  width: 25px;
  height: 25px;
  display: flex;
  align-items: center;
  justify-content: space-around;
  margin-right: 10px;
}

On codepen: https://codepen.io/mkempinsky/pen/OBNXGO



回答8:

content:counter(li) with increment doesn't work in my less so I found some wokraround:)

li {
position: relative;
line-height: 2.5em;
list-style-type: none;
&:before{
  content: '';
  position: absolute;
  left: -29px;
  top: 7px;
  display: block;
  background: @btn-bg-secondary;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  color: @bg-color-primary;
  padding-left: 7px;
  line-height: 1.5em;
}
&:nth-child(1):before{
  content: '1';
}
&:nth-child(2):before{
  content: '2';
}
&:nth-child(3):before{
  content: '3';
}
&:nth-child(4):before{
  content: '4';
}
&:nth-child(5):before{
  content: '5';
}
&:nth-child(6):before{
  content: '6';
}
&:nth-child(7):before{
  content: '7';
}
&:nth-child(8):before{
  content: '8';
}
}

http://jsfiddle.net/du6ezxj7/