HTML — Несколько плавающих элементов уровня блока внутри ‹li›

У меня есть сложная проблема, с которой нужно справиться. Вот сценарий:

У меня есть неупорядоченный список, содержащий элементы списка. Они отображаются вертикально, с фоном чередующегося цвета, все из которых имеют одинаковую ширину (ограниченную div фиксированной ширины несколькими родительскими элементами вверх). На некоторых элементах есть индикатор элемента списка (list-style-type: square; list-style-position: inside;), но на большинстве элементов его нет. В этих элементах списка есть три плавающих <div>, все из которых содержат только текст. Один нужно выровнять по левому краю, а два других по правому краю элемента списка. Первый и выровненный по правому краю <div> должен иметь фиксированную ширину, чтобы текст не перетекал на следующую строку или не выходил за границы элемента списка. Два других также должны иметь фиксированную ширину, так как их содержимое практически не изменит размер, за исключением различий в отображении браузера, зависящих от шрифта.

Вот простой текстовый пример:

--------------------------------------
| • <Some Text>        <text2><text3>|
|   <Some more text>...<text2><text3>|
|   <other text>       <text2><text3>|
--------------------------------------

Текст в первом элементе имеет этот CSS: text-overflow: ellipsis; overflow: hidden; white-space: nowrap;, чтобы хорошо ограничить переполнение. Чтобы просмотреть весь контент, у меня есть хорошая черная магия jQuery, чтобы заставить его прокручиваться, что я уже протестировал и доказал вне этого контекста.

Моя текущая проблема заключается в том, что во всех основных браузерах плавание всех элементов приводит к тому, что каждый элемент списка не имеет высоты, за исключением тех, у которых есть индикатор списка (list-style-type). Добавление разделителя clearfix в конец содержимого элемента списка приводит к тому, что содержимое отображается на всю ширину строки ниже индикатора элемента списка:

--------------------------------------
| •                                  |
| <Some Text>        <text2><text3>  |
--------------------------------------

Все было бы очень просто, если бы первому тексту не нужно было задавать фиксированную ширину (мой макет уже так работает), а так и должно быть.

Для вашего удовольствия вот правильный пример HTML, иллюстрирующий именно мою проблему:

<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>
<html xmlns='http://www.w3.org/1999/xhtml' lang='en' xml:lang='en'>
<head>

    <title>HTML List Problem</title>

    <style type="text/css">
        #container { width: 420px; }

        #container ul {
            list-style-type: none;
            margin: 0;
            padding: 0 20px;
            background: green;
        }

        .item { padding: 5px 0 4px 20px; }

        .item-current {
            list-style-type: square;
            list-style-position: inside;
        }

        .item-even { background: yellow; }
        .item-odd { background: orange; }

        .text1 {
            width: 200px;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
            float: left;
        }
        .text2, .text3 {
            float: right;
            width: 30px;
        }


    </style>

</head>

<body>

<div id="container">
    <ul>
        <li class="item item-current item-even">
            <div class="text1 item-current">
                Some Text
            </div>
            <div class="text2">
                text2
            </div>
            <div class="text3">
                text3
            </div>
        </li>
        <li class="item  item-odd">
            <div class="text1">
                Some Text
            </div>
            <div class="text2">
                text2
            </div>
            <div class="text3">
                text3
            </div>
        </li>
        <li class="item item-even">
            <div class="text1">
                Some Text
            </div>
            <div class="text2">
                text2
            </div>
            <div class="text3">
                text3
            </div>
        </li>
        <li class="item  item-odd">
            <div class="text1">
                Some Text
            </div>
            <div class="text2">
                text2
            </div>
            <div class="text3">
                text3
            </div>
        </li>
    </ul>
</div>

</body>
</html>

person Dakota    schedule 22.06.2011    source источник


Ответы (2)


Как насчет этого?

<title>HTML List Problem</title> 

<style type="text/css"> 
    #container { width: 420px; }

    #container ul {
        list-style-type: none;
        margin: 0;
        padding: 0 20px;
        background: green;
    }

    .item {
     padding: 5px 0 4px 20px;
         list-style-type: square;
         color: yellow;
}

    .item-current {
        list-style-type: square;

    }

    .item-even { background: yellow; }
    .item-odd { background: orange; }

    .text1 {
        width: 200px;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        float: left;
    }
    .text2, .text3 {
        float: right;
        width: 30px;
    }


</style> 

    Some Text text2 text3 Some Text text2 text3 Some Text text2 text3 Some Text text2 text3

Все, что я изменил, это:

удалена позиция стиля списка добавлен тип стиля списка: квадрат и цвет фона (чтобы скрыть маркер) Возможно, вам потребуется дополнительная разметка для поддержки альтернативного цвета строки. Это слишком много взлома?

person serialworm    schedule 22.06.2011
comment
Это определенно на грани... точно. Я надеялся, что смогу получить более подробное объяснение того, как удержать li от разрушения, не взрывая их с помощью clearfix. Если я не смогу найти правильное решение, я думаю, я воспользуюсь этим. Однако из-за характера проблемы я думаю, что это связано с тем, как браузер отображает <li> по-разному, когда у него есть маркер элемента списка, чем когда его нет. - person Dakota; 22.06.2011
comment
Проблема в том, что наличие плавающих элементов на всех элементах в <li> приводит к тому, что он не имеет высоты (как и все остальное без clearfix), только добавление clearfix нарушает правильное отображение <li> как элемента списка, поскольку он очищает индикатор элемента когда он находится внутри, в то время как clearfix, когда он находится снаружи, перемещает индикатор элемента вниз к следующему элементу. Ни одно из этих решений не является приемлемым. Почему поплавки не могут занимать место? Почему я не могу выбрать, давать ли моим поплавкам высоту, устанавливая их свойство высоты? ЗАЧЕМ? - person Dakota; 22.06.2011
comment
Что ж, хорошая новость заключается в том, что я решил половину проблемы: теперь я могу заставить браузер принимать высоту плавающих элементов, что предотвращает схлопывание элементов. Это достигается путем добавления overflow: hidden; к объявлению .item. Как только я выясню исправление маркера элемента списка, я также опубликую его и отвечу на свой вопрос. - person Dakota; 22.06.2011
comment
Теперь проблема заключается в том, как установить плавающее значение для маркера элемента списка, чтобы он был вынужден располагаться слева от <li>. Кто-нибудь знает, как получить доступ к этому элементу? - person Dakota; 22.06.2011
comment
Сотрите это, это было width: 100%; на #container ul. Виноват. - person Dakota; 22.06.2011
comment
Я думаю, что элемент li перестает быть блоком, как только он имеет набор list-style-type: none. Я наткнулся на идею установить display: list-item для li. Вы пробовали это? ссылка - person serialworm; 22.06.2011
comment
Хм... Нет. Тем не менее, я смог решить свою проблему. Для этого я использовал фиксированную ширину и высоту. - person Dakota; 23.08.2011

Решением стало использование фиксированной ширины для подэлементов и немного другая структура контента. Некоторые вещи, которые должны работать, просто невозможны в HTML так, как вы думаете. Работать таким обходным путем... Это ужасно.

person Dakota    schedule 23.08.2011