2016-07-06 7 views
8

Я создал отзывчивый макет для приложения с использованием Flexbox. Макет требует сворачиваемого меню слева, блока с заголовком и телом посередине и переключаемой панели справки справа (для этого есть больше, но это основная структура).white-space: nowrap breaks flexbox layout

Левое меню имеет два состояния: ширину 180 пикселей или 80 пикселей в ширину. Панель справки либо скрыта, либо занимает 180 пикселей. Средний ящик занимает остальную часть пространства. Flexbox работает как шарм.

Проблема возникает, когда я делаю прокрутку div, используя white-space: nowrap. У меня есть куча предметов, которые нужно отображать в горизонтальном скроллере, поэтому у меня есть список div с элементами, установленными на overflow:auto и white-space: nowrap.

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


Следующая скрипку иллюстрирует этот вопрос:

http://jsfiddle.net/PieBie/6y291fud/

Вы можете переключать справки-панели, нажав тумблер помощь в строке меню. Создайте резервную копию, нажав Перечислите пробелы в списке, это переключит свойство CSS white-space: no-wrap. Если панель справки открыта, вы можете видеть, что ее выталкивают за пределы.

Нижний список - это то, чего я хочу достичь, но я хочу, чтобы он был полной шириной его родителя.

Я могу воссоздать проблему в Chrome, Firefox, Opera, Vivaldi и Edge. Internet Explorer 11 играет хорошо (° _ °). Я бы предпочел чистое решение CSS (SCSS также вариант), но в случае необходимости я могу использовать JS.


$('#nav-toggle').on('click',function(){ 
 
\t $(this).parent().toggleClass('collapsed'); 
 
}); 
 
$('#help-toggle').on('click',function(){ 
 
\t $('#help-pane').toggleClass('visible'); 
 
}); 
 
$('#list-toggle').on('click',function(){ 
 
\t $('#list').toggleClass('nowrap'); 
 
});
body,html{width:100%;height:100%;overflow:hidden;} 
 

 
#body{ 
 
    display:flex; 
 
    flex-flow:row nowrap; 
 
    position:absolute; 
 
    top:0; 
 
    left:0; 
 
    margin:0; 
 
    padding:0; 
 
    width:100%; 
 
    height:100%; 
 
    background-color:#abc; 
 
    overflow:hidden; 
 
} 
 

 
#shell{ 
 
    flex: 1 1 auto; 
 
    display:flex; 
 
    flex-flow:row nowrap; 
 
    position:relative; 
 
    width:100%; 
 
    min-height:100%; 
 
} 
 

 
    #left{ 
 
    flex: 0 0 180px; 
 
    min-height:100%; 
 
    min-width: 0; 
 
    background:lightblue; 
 
    } 
 
    #left.collapsed{ 
 
    flex: 0 0 80px; 
 
    } 
 
    
 
    #mid{ 
 
    flex: 1 1 auto; 
 
    min-height:100%; 
 
    min-width: 0; 
 
    display:flex; 
 
    flex-flow:column nowrap; 
 
    align-items:stretch; 
 
    align-content:stretch; 
 
    position:relative; 
 
    width:100%; 
 
    min-height:100vh; 
 
    min-width: 0; 
 
    background:purple; 
 
    } 
 
     #mid-top{ 
 
     flex: 0 0 auto; 
 
     min-height:100px; 
 
     background:green; 
 
     } 
 
     #mid-bottom{ 
 
     min-height:calc(100% - 100px); 
 
     flex: 1 1 auto; 
 
     background:lightgreen; 
 
     } 
 
     #list{ 
 
     overflow: auto; 
 
     width: 100%; 
 
     max-width: 100%; 
 
     } 
 
     #list.nowrap{ 
 
     white-space: nowrap; 
 
     } 
 
     #secondlist{ 
 
     overflow: auto; 
 
     max-width: 250px; 
 
     white-space: nowrap; 
 
     } 
 
     .list-item{ 
 
     display: inline-block; 
 
     width: 50px; 
 
     height: 50px; 
 
     margin: 2px; 
 
     background: purple; 
 
     } 
 
     .list-item.odd{ 
 
     background: violet; 
 
     } 
 
     
 
#help-pane{ 
 
    display:none; 
 
    flex: 0 0 0px; 
 
    background:red; 
 
} 
 
#help-pane.visible{ 
 
    display:inherit; 
 
    flex:0 0 180px; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div id="body"> 
 
<div id="shell"> 
 
     <div id="left"> 
 
      <div id="nav"> 
 
      - menu - 
 
      </div> 
 
      <div id="help-toggle"> 
 
      help toggle 
 
      </div> 
 
      <div id="nav-toggle"> 
 
      nav toggle 
 
      </div> 
 
      <div id="list-toggle"> 
 
      list whitespace toggle 
 
      </div> 
 
     </div> 
 
     <div id="mid"> 
 
      <div id="mid-top"> 
 
       - mid top - 
 
      </div> 
 
      <div id="mid-bottom"> 
 
       - mid bottom- <br><br> 
 
       <div id="list"> 
 
       <div class="list-item odd">&nbsp;</div> 
 
       <div class="list-item">&nbsp;</div> 
 
       <div class="list-item odd">&nbsp;</div> 
 
       <div class="list-item">&nbsp;</div> 
 
       <div class="list-item odd">&nbsp;</div> 
 
       <div class="list-item">&nbsp;</div> 
 
       <div class="list-item odd">&nbsp;</div> 
 
       <div class="list-item">&nbsp;</div> 
 
       <div class="list-item odd">&nbsp;</div> 
 
       <div class="list-item">&nbsp;</div> 
 
       <div class="list-item odd">&nbsp;</div> 
 
       </div> 
 
       <hr> 
 
       <div id="secondlist"> 
 
       <div class="list-item odd">&nbsp;</div> 
 
       <div class="list-item">&nbsp;</div> 
 
       <div class="list-item odd">&nbsp;</div> 
 
       <div class="list-item">&nbsp;</div> 
 
       <div class="list-item odd">&nbsp;</div> 
 
       <div class="list-item">&nbsp;</div> 
 
       <div class="list-item odd">&nbsp;</div> 
 
       <div class="list-item">&nbsp;</div> 
 
       <div class="list-item odd">&nbsp;</div> 
 
       <div class="list-item">&nbsp;</div> 
 
       <div class="list-item odd">&nbsp;</div> 
 
       </div> 
 
      </div> 
 
     </div> 
 
</div> 
 
<div id="help-pane" class="visible"> 
 
    - help-pane - 
 
</div> 
 
</div>

+1

Похоже, вы сталкиваясь настройки минимального размера * по умолчанию для гибких элементов *. Элемент flex не может по умолчанию быть меньше размера его содержимого. Это простое решение. http://stackoverflow.com/a/36247448/3597276 –

ответ

14

Это вызвано default flex-box behaviour, что предотвращает сгибать урн стать меньше, чем его содержимое.

Решение этой проблемы задает min-width: 0 (или min-height: 0 для столбцов) для всех родительских гибких ящиков. В данном конкретном случае (и в fiddle):

#shell{ 
    flex: 1 1 auto; 
    display:flex; 
    flex-flow:row nowrap; 
    position:relative; 
    width:100%; 
    min-height:100%; 
    min-width: 0; /* this one right here does it!*/ 
} 

$('#nav-toggle').on('click',function(){ 
 
\t $(this).parent().toggleClass('collapsed'); 
 
}); 
 
$('#help-toggle').on('click',function(){ 
 
\t $('#help-pane').toggleClass('visible'); 
 
}); 
 
$('#list-toggle').on('click',function(){ 
 
\t $('#list').toggleClass('nowrap'); 
 
});
body,html{width:100%;height:100%;overflow:hidden;} 
 

 
#body{ 
 
    display:flex; 
 
    flex-flow:row nowrap; 
 
    position:absolute; 
 
    top:0; 
 
    left:0; 
 
    margin:0; 
 
    padding:0; 
 
    width:100%; 
 
    height:100%; 
 
    background-color:#abc; 
 
    overflow:hidden; 
 
} 
 

 
#shell{ 
 
    flex: 1 1 auto; 
 
    display:flex; 
 
    flex-flow:row nowrap; 
 
    position:relative; 
 
    width:100%; 
 
    min-height:100%; 
 
    min-width: 0; 
 
} 
 

 
    #left{ 
 
    flex: 0 0 180px; 
 
    min-height:100%; 
 
    min-width: 0; 
 
    background:lightblue; 
 
    } 
 
    #left.collapsed{ 
 
    flex: 0 0 80px; 
 
    } 
 
    
 
    #mid{ 
 
    flex: 1 1 auto; 
 
    min-height:100%; 
 
    min-width: 0; 
 
    display:flex; 
 
    flex-flow:column nowrap; 
 
    align-items:stretch; 
 
    align-content:stretch; 
 
    position:relative; 
 
    width:100%; 
 
    min-height:100vh; 
 
    min-width: 0; 
 
    background:purple; 
 
    } 
 
     #mid-top{ 
 
     flex: 0 0 auto; 
 
     min-height:100px; 
 
     background:green; 
 
     } 
 
     #mid-bottom{ 
 
     min-height:calc(100% - 100px); 
 
     flex: 1 1 auto; 
 
     background:lightgreen; 
 
     } 
 
     #list{ 
 
     overflow: auto; 
 
     width: 100%; 
 
     max-width: 100%; 
 
     } 
 
     #list.nowrap{ 
 
     white-space: nowrap; 
 
     } 
 
     #secondlist{ 
 
     overflow: auto; 
 
     max-width: 250px; 
 
     white-space: nowrap; 
 
     } 
 
     .list-item{ 
 
     display: inline-block; 
 
     width: 50px; 
 
     height: 50px; 
 
     margin: 2px; 
 
     background: purple; 
 
     } 
 
     .list-item.odd{ 
 
     background: violet; 
 
     } 
 
     
 
#help-pane{ 
 
    display:none; 
 
    flex: 0 0 0px; 
 
    background:red; 
 
} 
 
#help-pane.visible{ 
 
    display:inherit; 
 
    flex:0 0 180px; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div id="body"> 
 
<div id="shell"> 
 
     <div id="left"> 
 
      <div id="nav"> 
 
      - menu - 
 
      </div> 
 
      <div id="help-toggle"> 
 
      help toggle 
 
      </div> 
 
      <div id="nav-toggle"> 
 
      nav toggle 
 
      </div> 
 
      <div id="list-toggle"> 
 
      list whitespace toggle 
 
      </div> 
 
     </div> 
 
     <div id="mid"> 
 
      <div id="mid-top"> 
 
       - mid top - 
 
      </div> 
 
      <div id="mid-bottom"> 
 
       - mid bottom- <br><br> 
 
       <div id="list"> 
 
       <div class="list-item odd">&nbsp;</div> 
 
       <div class="list-item">&nbsp;</div> 
 
       <div class="list-item odd">&nbsp;</div> 
 
       <div class="list-item">&nbsp;</div> 
 
       <div class="list-item odd">&nbsp;</div> 
 
       <div class="list-item">&nbsp;</div> 
 
       <div class="list-item odd">&nbsp;</div> 
 
       <div class="list-item">&nbsp;</div> 
 
       <div class="list-item odd">&nbsp;</div> 
 
       <div class="list-item">&nbsp;</div> 
 
       <div class="list-item odd">&nbsp;</div> 
 
       </div> 
 
       <hr> 
 
       <div id="secondlist"> 
 
       <div class="list-item odd">&nbsp;</div> 
 
       <div class="list-item">&nbsp;</div> 
 
       <div class="list-item odd">&nbsp;</div> 
 
       <div class="list-item">&nbsp;</div> 
 
       <div class="list-item odd">&nbsp;</div> 
 
       <div class="list-item">&nbsp;</div> 
 
       <div class="list-item odd">&nbsp;</div> 
 
       <div class="list-item">&nbsp;</div> 
 
       <div class="list-item odd">&nbsp;</div> 
 
       <div class="list-item">&nbsp;</div> 
 
       <div class="list-item odd">&nbsp;</div> 
 
       </div> 
 
      </div> 
 
     </div> 
 
</div> 
 
<div id="help-pane" class="visible"> 
 
    - help-pane - 
 
</div> 
 
</div>