1

I have this unordered list:

<ul>
<li><i class="fa fa-chevron-down"></i>Item 1</li>
<li><i class="fa fa-chevron-left"></i>Item 2</li>
<li>Item 3</li>
</ul>

How do I keep the word "Item" lined up vertically on the left (not middle)? The First letter of Item should be vertical.

The issue is that sometimes there will be an icon. Sometimes not. And sometimes the icon will vary slightly in size, such as the difference between down and left icons.

This is basically a simple treeview display.

Greg Gum
  • 33,478
  • 39
  • 162
  • 233

3 Answers3

1

Give li a fixed padding-left, position: relative and make the icon position: absolute; to the left should fix your problem.

li {
  padding-left: 40px;
  position: relative;
}

li i {
  left: 0;
  position: absolute;
  top: 0;
}

In addition you can set a width or max-width to the icon:

li i {
  left: 0;
  position: absolute;
  top: 0;
  max-width: 30px;
}
Wim Mertens
  • 1,780
  • 3
  • 20
  • 31
  • Works perfectly. Maybe an explanation of how it work? – Greg Gum Sep 23 '16 at 03:43
  • Because you set position: absolute to the icon it won't push out the text after the icon. And adding padding to the li will give space for an icon to be there (or not). – Wim Mertens Sep 23 '16 at 03:45
  • 1
    Here's some more information about positioning: https://css-tricks.com/absolute-positioning-inside-relative-positioning/ and https://css-tricks.com/absolute-relative-fixed-positioining-how-do-they-differ/ – Wim Mertens Sep 23 '16 at 03:47
0

try this put the text in a span and use the css code below

<ul>
<li><i class="fa fa-chevron-down"></i><span>Item 1</span></li>
<li><i class="fa fa-chevron-left"></i><span>Item 2</span></li>
<li>Item 3</li>
</ul>

and the css

ul li i{vertical-align:middle}
ul li span{vertical-align:middle}

I wish it solve your problem

id3vz
  • 460
  • 4
  • 15
0

You're going to need fixed-width icons to accomplish what you're asking. There's no way of aligning the items unless there is a fixed-width. You can add a fixed-width to font-awesome icons with the class icon-fixed-width since version 3.1.1, and fa-fw since version 4.0. That gives a fixed with of 1.28571429em, which is annoying, but consistent.

Unfortunately CSS has no :parent selector, so you'll probably need to add a class to the <li> tags specifying whether of not they have an icon contained within:

<ul>
    <li class="yes"><i class="fa fa-fw fa-chevron-down"></i>Item 1</li>
    <li class="yes"><i class="fa fa-fw fa-chevron-left"></i>Item 2</li>
    <li>Item 3</li>
</ul>

li:not(.yes) {
    padding-left: 1.28571429em;
}

I've created a fiddle of this here: http://jsfiddle.net/3qwkkg4a/1/

Of course, you could always put the class on the <li> tags that don't contain the icons, or just target the third one with li:nth-of-type(3) for this particular example ;)

Hope this helps! :)

EDIT

These classes can also be added through jQuery, assuming you have access, using:

$('li:has(i)').addClass('yes');

A fiddle showcasing this can be seen here, leaving the HTML untouched:

http://jsfiddle.net/Obsidian_Age/3qwkkg4a/2/

Obsidian Age
  • 41,205
  • 10
  • 48
  • 71
  • I don't think this really answers the question at all. The OP is looking for vertical-alignment – Jacob G Sep 23 '16 at 03:11
  • @JacobGray: The OP asked "How do I keep the word 'Item' lined up vertically?". The first two lines have the word 'Item' displayed to the right of the icon, and his icons take up a variable width. He wants to display all three of the words 'Item' directly below one another. To align the words vertically as such, you need to modify the horizontal offset of the third
  • item. You would also need to ensure that all icons occupy the same widths within themselves :)
  • – Obsidian Age Sep 23 '16 at 03:14
  • @ObsidianAge I tried and this works as shown in your example. However, the items are created in code. So I end up with all of the li elements with the class of 'yes' So they all end up with the extra indent. There could be 3 items, or 30. – Greg Gum Sep 23 '16 at 03:21
  • Unfortunately, that would have to be addressed in the code. There's [multiple](http://stackoverflow.com/questions/2326499/apply-css-styles-to-an-element-depending-on-its-child-elements) [other](http://stackoverflow.com/questions/12206935/is-there-a-css-haschildren-selector) [questions](http://stackoverflow.com/questions/21252551/apply-style-to-parent-if-it-has-child-with-css) about styling elements based on their children, but it's unfortunately not possible in CSS. The best you can do is define a class back-end based on conditional code, I'm afraid. jQuery is also an option, if available. – Obsidian Age Sep 23 '16 at 03:32
  • No problem! Glad to hear that I was on the right track with what you're after. It's a shame that you need to create the items in back-end code, but if you have access to jQuery, you can solve the problem with `$('li:has(i)').addClass('yes');`, which would create the relevant classes on the fly. I've added a new fiddle to my answer showcasing this. Otherwise, I'm afraid your *only* option is to somehow modify the classes in the conditional back-end logic. – Obsidian Age Sep 23 '16 at 03:48