简体   繁体   中英

How to vertically align a list on one item, with HTML/CSS/JavaScript?

I have an HTML document with a very long list, like this:

<ol>
    <li>frog</li>
    <li>fish</li>
    <li>flamingo</li>
    <li>ferret</li>
    <li><div class="marked">fox</div></li>
    ...
</ol>

The list is too long for all items to be visible on the screen. I've marked one item with div class="marked"> and </div> . Is there some way to vertically center the list on that marked item.

  • If the list is too long, it should run off the edge of the visible screen, with no scrollbars created.

Here is an example of how it appears in the browser window:

 __________________
|   2.fish         |
|   3.flamingo     |
|   4.ferret       | <-- This marked item is centered.
|   5.elephant     |
|___6.mouse________| <-- No scrollbars.

How can I vertically align a list on a marketed item?

Here's a solution based on James G.'s code, which avoids the loop by using getBoundingClientRect() :

http://jsfiddle.net/d8d5jjvc/4/

var list = document.getElementById('list'),
    marked= document.getElementById('marked'),
    crm= marked.getBoundingClientRect(),
    height= crm.bottom-crm.top;

list.scrollTop= (crm.top-height)-(list.clientHeight-height)/2;

Ok, I really hope I understood you correctly, because this took WAY longer than I expected.

Working JSfiddle

First you have to find the element you're centering on, the list, the height of the items in the list, and the index of the element you're centering on. (I stole a function from here to do that last bit, as well as changing your class to an id. You can figure that out if it needs to be a class)

function arrayObjectIndexOf(myArray, searchTerm) {
            for(var i = 0, len = myArray.length; i < len; i++) {
                if (myArray[i].firstChild === searchTerm) return i;
            }
            return -1;
        }

var list = document.getElementById('list'),
            listItems = list.children,
            listItemHeight = list.scrollHeight / listItems.length,
            target = elem,
            index = arrayObjectIndexOf(listItems, target);

Then the tricky part was the math. First we get the height of elements above the element we're centering on, then we subtract the height of the container, minus the item we're centering on, over 2. If that makes any sense. You might want to draw it if you don't understand the math, it'll make more sense on paper.

list.scrollTop = (index * listItemHeight) - ((list.clientHeight - listItemHeight) / 2);

You display a list vertically with the display option.

display: inline;

I usually use the inline-block parameter, this is

display: inline-block;

Then, you've to do this on your css.

.marked: { display: inline-block; }

I hope this works for you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM