Zatrzymaj zawijanie pływających elementów DIV

84

Chcę mieć wiersz elementów div (komórek), które nie są zawijane, jeśli przeglądarka jest zbyt wąska, aby je dopasować.

Przeszukałem stos i nie mogłem znaleźć działającej odpowiedzi na to, co moim zdaniem powinno być prostym pytaniem CSS.

Komórki mają określoną szerokość. Jednak nie chcę określać szerokości wiersza, szerokość powinna automatycznie odpowiadać szerokości jego komórek potomnych.

Jeśli widoczny obszar jest zbyt wąski, aby pomieścić wiersze, element div powinien być przepełniony paskami przewijania.

Podaj swoją odpowiedź jako działający fragment kodu, ponieważ wypróbowałem wiele rozwiązań, które widziałem gdzie indziej (np. Określ szerokość: 100% i wydaje się, że nie działają).

Szukam tylko rozwiązania HTML / CSS, bez JavaScript.

.row {
  float: left;
  border: 1px solid yellow;
  width: 100%;
  overflow: auto;
}
.cell {
  float: left;
  border: 1px solid red;
  width: 200px;
  height: 100px;
}
<div class="row">
  <div class="cell">a</div>
  <div class="cell">b</div>
  <div class="cell">c</div>
</div>

W tej chwili naprawdę ciężko koduję szerokość wiersza do naprawdę dużej liczby.

Mikołaja
źródło
1
czy jedna z poniższych odpowiedzi zadziałała dla Ciebie? Nie mam żadnego sukcesu z żadnym z nich.
John Fitzpatrick,
Po prostu wypróbowałem wszystkie odpowiedzi i żadna nie zadziałała. Problem polegał na tym, że musiałem wyśrodkować dwa pływające lewe elementy div i zapobiec przesunięciu tego po prawej stronie poniżej w lewo po zmianie rozmiaru okna.
Bashevis,
@Nicholas Myślę, że mój przykład jest dokładnie tym, czego szukasz, dzisiaj natknąłem się na ten sam problem. Menu rozwijane są przepełnione, ale pierwsza warstwa się nie zawija.
Jan

Odpowiedzi:

107

Właściwość CSS display: inline-blockzostała zaprojektowana, aby zaspokoić tę potrzebę. Możesz o tym trochę poczytać tutaj: http://robertnyman.com/2010/02/24/css-display-inline-block-why-it-rocks-and-why-it-sucks/

Poniżej przykład jego zastosowania. Kluczowe elementy to to, że rowelement ma white-space: nowrapi cellelementy mają display: inline-block. Ten przykład powinien działać w większości głównych przeglądarek; tabela kompatybilności jest dostępna tutaj: http://caniuse.com/#feat=inline-block

<html>
<body>
<style>

.row {
    float:left;
    border: 1px solid yellow;
    width: 100%;
    overflow: auto;
    white-space: nowrap;
}

.cell {
    display: inline-block;
    border: 1px solid red;
    width: 200px;
    height: 100px;
}
</style>

<div class="row">
    <div class="cell">a</div>
    <div class="cell">b</div>
    <div class="cell">c</div>
</div>


</body>
</html>
Calvin
źródło
1
Dodaj <!DOCTYPE html>lub <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">na górze kodu HTML, aby IE nie był domyślnie w trybie dziwactw.
Cees Timmerman
4
Uwaga: moje elementy div typu komórkowego zostały skonfigurowane za pomocą float: left, co wymusiło, aby styl obliczony był blokowy, zamiast inline-block. Zajęło nam to trochę czasu, więc pomyślałem, że najlepiej się tym podzielić.
Steve Hibbert
To nie działa z ostatnią komórką float: right, prawda?
Andy
3
To nie jest tak naprawdę przykład tego, jak uchronić pływające elementy div przed zawijaniem - po prostu rozpakowałeś komórki. Mam układ z kilkoma lewymi i prawymi pływakami, więc nie mogę pozbyć się pływaków, aby rozwiązać problem z zawijaniem.
Andy
Haha, w porządku. To pedantyczne rozróżnienie, ale masz rację. Nie rozwiązałem problemu „zatrzymaj elementy div z zawijaniem”, rozwiązałem prawdziwe pytanie pytającego „jak sprawić, by mój układ działał”. Odpowiadając na pierwsze pytanie: jestem pewien, że nie ma sposobu, aby zapobiec zawijaniu się pływających elementów div. Podobnie jak asker, będziesz musiał znaleźć inny sposób zakodowania opisywanego układu.
Calvin
32

Chcesz zdefiniować min-widthwiersz, aby po zmianie rozmiaru przeglądarki nie schodził poniżej tego i zawijał.

farooq
źródło
1
To działałoby nawet z pływakami. Myślę, że to prawdziwa odpowiedź.
Danon
2
Zgadzam się z @Danon - to działa, podczas gdy inline-block wprowadził problemy z wyrównaniem w pionie.
dlchambers
1
Zależy od Twoich potrzeb. Zapobiega to zawijaniu pływających elementów div podczas zmiany rozmiaru strony, ale pytający stwierdził: „Nie chcę określać szerokości wiersza, szerokość powinna automatycznie odpowiadać szerokości komórek potomnych”. Ręczne określanie szerokości wymaga trochę zduplikowanej pracy, ponieważ musisz obliczyć całkowitą szerokość wiersza. Co gorsza, jeśli twoje komórki mają zmienną szerokość (powiedzmy, ponieważ mają rozmiar odpowiadający wierszowi tekstu w nich), obliczenie sumy może być niepraktyczne lub niemożliwe.
Calvin
-1; Jest to sprzeczne z tym, co OP wyraźnie określił w swoim pytaniu, a mianowicie NIE musi określać szerokości. +1 do komentarza Calvina powyżej.
Teodor Sandu,
4

Po przeczytaniu odpowiedzi Johna odkryłem, że wydaje się, że działają u nas następujące rzeczy (nie wymagały określenia szerokości):

<style>
.row {
    float:left;
    border: 1px solid yellow;
    overflow: visible;
    white-space: nowrap;
}

.cell {
    display: inline-block;
    border: 1px solid red;
    height: 100px;
}
</style>

<div class="row">
    <div class="cell">hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello </div>
    <div class="cell">hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello </div>
    <div class="cell">hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello </div>
</div>
Kevin LeBlanc
źródło
To rozwiązało problem, który miałem z przeciąganymi elementami div na iPhonie. Gdy elementy DIV miały więcej niż jedno słowo i zostały przeciągnięte na krawędź ekranu, element DIV był zawijany, tak że w każdym wierszu znajdowało się słowo. W każdym razie overflow: visible; white-space: nowrap;załatwił mi sprawę. Dzięki!
TryHarder
4
Zadziałało, ponieważ uwolnił komórki. Niezbyt dobre rozwiązanie, które powstrzymałoby zawijanie pływających elementów div
Andy
1

Jedynym sposobem, w jaki udało mi się to zrobić, jest użycie overflow: visible;i width: 20000px;na elemencie nadrzędnym. Nie ma sposobu na zrobienie tego z poziomem CSS 1, o którym jestem świadomy i nie chciałem myśleć, że będę musiał iść na całość z poziomem CSS 3. Poniższy przykład ma 18 menu, które wykraczają poza mój wyświetlacz LCD o rozdzielczości 1920x1200 , jeśli ekran jest większy, po prostu skopiuj elementy menu pierwszego poziomu lub po prostu zmień rozmiar przeglądarki. Alternatywnie, przy nieco niższych poziomach zgodności przeglądarki, możesz użyć zapytań o media CSS3.

Oto pełna przykładowa demonstracja kopiowania / wklejania ...

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>XHTML5 Menu Demonstration</title>
<style type="text/css">
* {border: 0; box-sizing: content-box; color: #f0f; font-size: 10px; margin: 0; padding: 0; transition-property: background-color, background-image, border, box-shadow, color, float, opacity, text-align, text-shadow; transition-duration: 0.5s; white-space: nowrap;}
a:link {color: #79b; text-decoration: none;}
a:visited {color: #579;}
a:focus, a:hover {color: #fff; text-decoration: underline;}
body {background-color: #444; overflow-x: hidden;}
body > header {background-color: #000; height: 64px; left: 0; position: absolute; right: 0; z-index: 2;}
body > header > nav {height: 32px; margin-left: 16px;}
body > header > nav a {font-size: 24px;}
main {border-color: transparent; border-style: solid; border-width: 64px 0 0; bottom: 0px; left: 0; overflow-x: hidden !important; overflow-y: auto; position: absolute; right: 0; top: 0; z-index: 1;}
main > * > * {background-color: #000;}
main > section {float: left; margin-top: 16px; width: 100%;}
nav[id='menu'] {overflow: visible; width: 20000px;}
nav[id='menu'] > ul {height: 32px;}
nav[id='menu'] > ul > li {float: left; width: 140px;}
nav[id='menu'] > ul > li > ul {background-color: rgba(0, 0, 0, 0.8); display: none; margin-left: -50px; width: 240px;}
nav[id='menu'] a {display: block; height: 32px; line-height: 32px; text-align: center; white-space: nowrap;}
nav[id='menu'] > ul {float: left; list-style:none;}
nav[id='menu'] ul li:hover ul {display: block;}
p, p *, span, span * {color: #fff;}
p {font-size: 20px; margin: 0 14px 0 14px; padding-bottom: 14px; text-indent: 1.5em;}
.hidden {display: none;}
.width_100 {width: 100%;}
</style>
</head>

<body>

<main>
<section style="height: 2000px;"><p>Hover the first menu at the top-left.</p></section>
</main>

<header>
<nav id="location"><a href="">Example</a><span> - </span><a href="">Blog</a><span> - </span><a href="">Browser Market Share</a></nav>
<nav id="menu">
<ul>
<li><a href="" tabindex="2">Menu 1 - Hover</a>
<ul>
<li><a href="" tabindex="2">Menu 1 B</a></li>
<li><a href="" tabindex="2">Menu 1 B</a></li>
<li><a href="" tabindex="2">Menu 1 B</a></li>
<li><a href="" tabindex="2">Menu 1 B</a></li>
<li><a href="" tabindex="2">Menu 1 B</a></li>
<li><a href="" tabindex="2">Menu 1 B</a></li>
<li><a href="" tabindex="2">Menu 1 B</a></li>
<li><a href="" tabindex="2">Menu 1 B</a></li>
</ul>
</li>
<li><a href="" tabindex="2">Menu 2</a></li>
<li><a href="" tabindex="2">Menu 3</a></li>
<li><a href="" tabindex="2">Menu 4</a></li>
<li><a href="" tabindex="2">Menu 5</a></li>
<li><a href="" tabindex="2">Menu 6</a></li>
<li><a href="" tabindex="2">Menu 7</a></li>
<li><a href="" tabindex="2">Menu 8</a></li>
<li><a href="" tabindex="2">Menu 9</a></li>
<li><a href="" tabindex="2">Menu 10</a></li>
<li><a href="" tabindex="2">Menu 11</a></li>
<li><a href="" tabindex="2">Menu 12</a></li>
<li><a href="" tabindex="2">Menu 13</a></li>
<li><a href="" tabindex="2">Menu 14</a></li>
<li><a href="" tabindex="2">Menu 15</a></li>
<li><a href="" tabindex="2">Menu 16</a></li>
<li><a href="" tabindex="2">Menu 17</a></li>
<li><a href="" tabindex="2">Menu 18</a></li>
</ul>
</nav>
</header>

</body>
</html>
Jan
źródło
Kiedy używam upvoted odpowiedź i wymienić width:100%z width:1000pxnim pracuje dla mnie
Nick.McDermaid
@ Nick.McDermaid Nie bez powodu użyłem 20 tys. Pikseli, gdy wychodzą ekrany 4K, wiesz, że w końcu będzie 8K i tak dalej, więc najlepiej pracować z niesamowicie wysoką liczbą, aby działała przez te dodatkowe lata, dopóki ekrany nie będą wyższe - rozwiązanie niż samo życie. ;-)
John
Zrozumiano ... Po prostu cieszę się, że przestałem się owijać. CSS - to doprowadza mnie do szału nawet przy użyciu narzędzi F12. Nie wiem, jak ktokolwiek zrobiłby cokolwiek bez nich.
Nick.McDermaid
1
Na przyszłość: użycie dużej szerokości / wysokości jest wysoce nieefektywne, ponieważ przeglądarka nadal przechowuje w pamięci niepotrzebne duże pudełko. Ustaw kontener na, white-space: nowrap;a dzieci na, display: inline-block;jak już powiedziano w innych odpowiedziach (lub cofnij się do display: table;i display: table-cell;).
gyo
main > * > * {background-color: #000;}O_o
theflowersoftime
0

Dla mnie (używając bootstrap) jedyną rzeczą, która działała, było ustawienie display:absolute;z-index:1na ostatniej komórce.

Spikolynn
źródło
1
display:absolutenie jest poprawnym
kodem
-1

Miałem nieco podobny problem, w którym ograniczony obszar składał się z obrazu w postaci pływającej: lewy blok i niepływający blok tekstu. Obszar ma płynną szerokość. Zgodnie z projektem tekst byłby zawinięty wzdłuż prawej strony obrazu. Problem polegał na tym, że tekst zaczynał się od znacznika <h2>, którego pierwszym słowem było maleńkie słowo „From”. Gdy zmieniłem rozmiar okna na mniejszą szerokość, tekst niepływający pozostawiałby dla pewnego zakresu szerokości tylko słowo „Od” na górze obszaru zawijania, reszta tekstu byłaby ściśnięta poniżej elementu zmiennoprzecinkowego blok. Moim rozwiązaniem było powiększenie pierwszego słowa tagu poprzez zastąpienie spacji występującej po nim tym kodem, <span style = "opacity: 0;"> x </span>. Efektem było utworzenie pierwszego słowa zamiast „From”, „FromxNextWord”, gdzie „x” jako niewidoczny wyglądał jak spacja. Teraz moje pierwsze słowo było na tyle duże, że nie zostało porzucone przez resztę bloku tekstu.

Jim
źródło