Как сохранить div от обертывания, когда выравниваемый к нему div может меняться по ширине?

У меня простая настройка. A div, который содержит заголовок и titleOptions.

Название иногда длинное, и я хотел бы, чтобы он имел ellipsis вместо того, чтобы показывать полный заголовок. Справа от названия находится titleOptions. Они могут различаться. Иногда удаляют, редактируют и перемещают, иногда несколько таких, иногда нет. (Поэтому ширина заголовка не может быть исправлена, так как titleOptions меняются).

Как я ВСЕГДА имею одну строку для заголовка и titleOptions. Я не хочу, чтобы это было когда-либо завершено, или нажмите кнопку titleOptions ниже.

Я предпочитаю ширину titleOptions быть текучей, поскольку это позволит более длинному названию иметь больше недвижимости.

Вот скрипка для лучшего объяснения: http://jsfiddle.net/K8s3Z/1

Ответ 1

Вы можете использовать flexbox.

.titleBar {
    width:980px;
    overflow:hidden;
    border: 1px solid #EEE;
    margin-bottom:2em;
    display: -webkit-flex;
}
.title {
    border: 1px solid #DDD;
    white-space:nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    -webkit-flex: 1;
}

.titleOptions {
    white-space:nowrap;
    border: 1px solid #DDD;
}

fiddle (у которого также есть другие синтаксис и префиксы и т.д.).


С JS, если flexbox недоступен

function getByClassName(collection, className) {
    var i = collection.length;
    var regexp = new RegExp('\\b' + className + '\\b');
    var returnSet = [];
    while ( i-- ) {
        if ( collection[i].className.match(regexp)  ) {
            returnSet.push(collection[i]);
        }
    }
    return returnSet;
}
if ( ! Modernizr.flexbox && ! Modernizr.flexboxlegacy ) {
    var bars = document.querySelectorAll('.titleBar');
    for (var i = 0, l = bars.length; i < l; ++i) {
        var bar = bars[i];
        var divs = bar.getElementsByTagName('*');
        var optWidth = getByClassName(divs, 'titleOptions')[0].offsetWidth;
        getByClassName(divs, 'title')[0].style.width = bar.offsetWidth - optWidth + 'px';
    }
}

В скрипте есть пользовательские функции для проверки на flexbox (на основе Modernizr), если вы не хотите использовать Modernizr (по какой-то причине). Просто назначьте ответы на локальный объект Modernizr в скрипте. Кроме того, нет jQuery, если у вас есть отвращение к этому. Оба легко заменить здесь, если вы их используете.

Ответ 2

Чтобы показать эллипсис, вы можете использовать css text-overflow. Хотя AFAIK, вам нужно дать контейнеру ширину, чтобы он знал, где произойдет переполнение.

Это свойство CSS не приводит к возникновению переполнения; для этого, и чтобы применить переполнение текста, автор должен применить некоторые дополнительные свойства к элементу, например, установить переполнение в скрытое.

Вы можете запустить некоторый код javascript после загрузки DOM, чтобы динамически установить ширину .title на основе ширины .titleOptions.

Вот статический пример того, что вы пытаетесь сделать:

.title {
    float:left;
    border: 1px solid #DDD;
    white-space:nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    width: 76%;
}

Попробуйте использовать js для динамической установки ширины.

Изменить: Вот пример того, как вы можете установить ширину динамически, используя javascript (и немного jQuery). Используя css для .title, я выше (минус width: 76%;), я добавил это js:

function getChildByClassName(ele, className) {
    for(var i = 0; i < ele.childNodes.length; i++) {
        if($(ele.childNodes[i]).hasClass(className)) {
            return ele.childNodes[i];
        }
    }
}

var titleBars = document.getElementsByClassName('titleBar');
var w = 0;
var spacer = 10;

for(var i = 0; i < titleBars.length; i++) {
    w = titleBars[i].clientWidth;
    w = w - getChildByClassName(titleBars[i], 'titleOptions').clientWidth - spacer;
    $(titleBars[i]).children('.title').eq(0).css('width', w + 'px');
}

http://jsfiddle.net/K8s3Z/8/

Ответ 3

Вот опция, использующая position ing ( только CSS и все браузеры, поддерживаемые, минус тень окна) и даже имеет приятное сочетание текста.

Fiddle

.titleBar {
    width:980px;
    overflow:hidden;
    border: 1px solid #EEE;
    margin-bottom:2em;
    position: relative;
}

.title {
    float:left;
    border: 1px solid #DDD;

    overflow:hidden;
    white-space:nowrap;
}

.titleOptions {
    border: 1px solid #DDD;
    position: absolute;
    right: 0;
    top: 0;
    background-color: #fff;

    /* optional... make it blend in instead of ellipsis */
    -moz-box-shadow:    2px 0 25px 50px #fff;
    -webkit-box-shadow: 2px 0 25px 50px #fff;
    box-shadow:         2px 0 25px 50px #fff;     
}

Снимок экрана смешивания... если вы его не поймали.

Ответ 4

Если вы разместите контейнер опций на том же уровне, что и текст, и поместите его, текст должен автоматически обернуться вокруг контейнера. С помощью нескольких настроек вы можете отображать только одну строку и скрывать остальные.

Попробуйте этот html:

<div class="titleBar">
    <div class="title"><div class="titleOptions">OPTIONS | CLICK ME</div> THIS IS MY TITLE </div>
</div>

И css:

.titleBar {
    border: 1px solid #EEE;
    margin-bottom:2em;
}

.title {
    overflow:hidden;
    white-space:nowrap;
    text-overflow: ellipsis;
}

.titleOptions {
    float:right;
    white-space:nowrap;
    border: 1px solid #DDD;
}

В качестве резервной копии для IE вы можете удалить свойство переполнения текста в .title и использовать это вместо

/*IE Fallback*/
.titleOptions {
    background-color:white;
    position:relative;
    z-index:10;
}
.titleOptions:before {
  content: "\2026 ";
  padding-right: 5px;
}

Ответ 5

просто создайте контейнер div width auto