Div szerokość 100% minus stała liczba pikseli

316

Jak mogę uzyskać następującą strukturę bez użycia tabel lub JavaScript? Białe obramowania reprezentują krawędzie div i nie mają związku z pytaniem.

Struktura 1

Rozmiar obszaru pośrodku będzie się różnić, ale będzie miał dokładne wartości pikseli, a cała struktura powinna być skalowana zgodnie z tymi wartościami. Aby to uprościć, potrzebuję sposobu ustawienia szerokości „100% - n px” na górne środkowe i dolne środkowe divy.

Doceniłbym czyste rozwiązanie dla różnych przeglądarek, ale w przypadku, gdy nie jest to możliwe, hacki CSS się sprawdzą.

Oto bonus. Kolejna struktura, z którą się zmagam, i ostatecznie używam tabel lub JavaScript. Jest nieco inny, ale wprowadza nowe problemy. Używam go głównie w systemie okienkowym opartym na jQuery, ale chciałbym zachować układ poza skryptem i kontrolować tylko jeden element (środkowy).

Struktura 2

Usunięto_kont
źródło
W przypadku drugiego elementu mówisz, że chcesz naprawić wysokość bardzo środkowego elementu, ale pozostałe elementy w pobliżu powinny być dynamiczne
Casebash

Odpowiedzi:

78

Możesz użyć zagnieżdżonych elementów i wypełnienia, aby uzyskać lewą i prawą krawędź paska narzędzi. Domyślna szerokość divelementu to auto, co oznacza, że ​​wykorzystuje on dostępną szerokość. Następnie możesz dodać dopełnienie do elementu, który nadal będzie utrzymywał dostępną szerokość.

Oto przykład, którego można użyć do umieszczania obrazów jako zaokrąglonych narożników po lewej i prawej stronie oraz obrazu środkowego, który powtarza się między nimi.

HTML:

<div class="Header">
   <div>
      <div>This is the dynamic center area</div>
   </div>
</div>

CSS:

.Header {
   background: url(left.gif) no-repeat;
   padding-left: 30px;
}
.Header div {
   background: url(right.gif) top right no-repeat;
   padding-right: 30px;
}
.Header div div {
   background: url(center.gif) repeat-x;
   padding: 0;
   height: 30px;
}
Guffa
źródło
Dziękuję za to. Musiałem go trochę ulepszyć w zależności od mojej sytuacji. Pierwszy zagnieżdżony div potrzebował marginesu po prawej stronie zamiast dopełnienia, a środkowy div również potrzebował tego samego prawego marginesu.
Max.
3
Świetne rozwiązanie. tylko mała rzecz -> to działa, ponieważ ".Header div div" przesłania ".Header div" . Powinien to być „.Header> div” i „.Header> div> div” . Rzeczywiście, „.Header div” oznacza każde dziecko div lub dziecko sub-div, podczas gdy „.Header> div” oznacza tylko bezpośrednie dzieci .Header
Charles HETIER
@CharlesHETIER: Tak, to również działa i jest łatwiejsze w użyciu, ponieważ nie musisz przekraczać wszystkich ustawień mniej szczegółowej reguły. Odpowiedź została napisana, gdy wsparcie >operatora wciąż nie było wystarczająco dobre, aby było niezawodne.
Guffa
1
Jest to nieaktualne, patrz odpowiedź poniżej na temat funkcji calc na css.
María Arias de Reyna Domínguez
2
@delawen: Musisz poczekać chwilę, zanim stanie się nieaktualny. Brak jest obsługi calcw IE 8 lub bieżących wersjach Anroid Browser lub Opera. caniuse.com/#search=calc
Guffa
760

Nowy sposób, na który właśnie natknąłem się: csscalc() :

.calculated-width {
    width: -webkit-calc(100% - 100px);
    width:    -moz-calc(100% - 100px);
    width:         calc(100% - 100px);
}​

Źródło: szerokość css 100% minus 100px

rom_j
źródło
86
Najlepsza odpowiedź w IMHO 2013. Przyjęta odpowiedź jest nieaktualna.
Danubian Sailor
7
Najwyższy czas, żeby ktoś się na to natknął. Skończyłem z hackami, skoro to wiem. +1 @lechlukasz
preahkumpii
47
Po 10 latach zmagań CSS ta odpowiedź zasługuje na +20000! Nadal nie mogę uwierzyć
własnym
8
Wszystko, co mogę na to powiedzieć, to ... youtube.com/
Jazz
5
Bardziej kompatybilny? -> $ ('# yourEl'). css ('width', '100%'). css ('width', '- = 100px'); (jQuery)
sboy031 18.09.13
7

Podczas gdy odpowiedź Guffa działa w wielu sytuacjach, w niektórych przypadkach możesz nie chcieć, aby lewy i / lub prawy kawałek paddingu był rodzicem środkowego diva. W takich przypadkach możesz użyć kontekstu formatowania bloków na środku i przesunąć div padding lewy i prawy. Oto kod

HTML:

<div class="container">
    <div class="left"></div>
    <div class="right"></div>
    <div class="center"></div>
</div>

CSS:

.container {
    width: 100px;
    height: 20px;
}

.left, .right {
    width: 20px;
    height: 100%;
    float: left;
    background: black;   
}

.right {
    float: right;
}

.center {
    overflow: auto;
    height: 100%;
    background: blue;
}

Wydaje mi się, że ta hierarchia elementów jest bardziej naturalna w porównaniu do zagnieżdżonych div div i lepiej reprezentuje to, co jest na stronie. Z tego powodu granice, wypełnienie i margines można normalnie zastosować do wszystkich elementów (tj .: ta „naturalność” wykracza poza styl i ma konsekwencje).

Zauważ, że działa to tylko dla div i innych elementów, które mają wspólną właściwość „domyślnie wypełniają 100% szerokości”. Dane wejściowe, tabele i ewentualnie inne będą wymagać zawinięcia ich w div kontenera i dodanie trochę więcej css, aby przywrócić tę jakość. Jeśli masz pecha, aby znaleźć się w takiej sytuacji, skontaktuj się ze mną, a ja wykopię css.

jsfiddle tutaj: jsfiddle.net/RgdeQ

Cieszyć się!

Unislash
źródło
6

Możesz skorzystać z układu Flexbox . Musisz ustawić flex: 1element, który musi mieć odpowiednio dynamiczną szerokość lub wysokość flex-direction: row and column.

Szerokość dynamiczna:

HTML

<div class="container">
  <div class="fixed-width">
    1
  </div>
  <div class="flexible-width">
    2
  </div>
  <div class="fixed-width">
    3
  </div>
</div>

CSS

.container {
  display: flex;
}
.fixed-width {
  width: 200px; /* Fixed width or flex-basis: 200px */
}
.flexible-width {
  flex: 1; /* Stretch to occupy remaining width i.e. flex-grow: 1 and flex-shrink: 1*/
}

Wynik:


Wysokość dynamiczna:

HTML

<div class="container">
  <div class="fixed-height">
    1
  </div>
  <div class="flexible-height">
    2
  </div>
  <div class="fixed-height">
    3
  </div>
</div>

CSS

.container {
  display: flex;
}
.fixed-height {
  height: 200px; /* Fixed height or flex-basis: 200px */
}
.flexible-height {
  flex: 1; /* Stretch to occupy remaining height i.e. flex-grow: 1 and flex-shrink: 1*/
}

Wynik:

Manoj Kumar
źródło
3

Typowym sposobem na to jest, jak opisano w zagnieżdżonych elementach Guffa. To trochę smutne, gdy trzeba dodać dodatkowe znaczniki, aby uzyskać potrzebne haki, ale w praktyce jest to div otoki lub nikogo nie skrzywdzi.

Jeśli musisz to zrobić bez dodatkowych elementów (np. Gdy nie masz kontroli nad znacznikami strony), możesz użyć rozmiaru pudełka , który ma całkiem przyzwoitą, ale niepełną lub prostą obsługę przeglądarki. Prawdopodobnie więcej zabawy niż poleganie na skryptach.

Bobin
źródło
3

Może jestem głupi, ale czy to nie jest oczywiste rozwiązanie?

<div class="parent">
    <div class="fixed">
    <div class="stretchToFit">
</div>

.parent{ display: table; width 100%; }
.fixed { display: table-cell; width: 150px; }
.stretchToFit{ display: table-cell; vertical-align: top}

Innym sposobem, który wymyśliłem w chromie, jest jeszcze prostszy, ale człowieku, to hack!

.fixed{ 
   float: left
}
.stretchToFit{
   display: table-cell;
   width: 1%;
}

To samo powinno wypełnić resztę wiersza poziomo, tak jak robią to komórki tabeli. Występują jednak dziwne problemy z przekraczaniem 100% jego elementu nadrzędnego, ale ustawienie szerokości na wartość procentową naprawia to.

Jack Franzen
źródło
2

Możemy to bardzo łatwo osiągnąć za pomocą Flex-Box.

Jeśli mamy trzy elementy, takie jak Header, MiddleContainer i Footer. I chcemy nadać pewną stałą wysokość nagłówkom i stopkom. wtedy możemy napisać w ten sposób:

W przypadku React / RN (domyślnie są to „display” jako flex i „flexDirection” jako kolumna), w web css będziemy musieli określić kontener kontenera lub kontener zawierający je jako display: „flex”, flex-direction: „column” jak poniżej:

    container-containing-these-elements: {
     display: flex,
     flex-direction: column
    }
    header: {
     height: 40,
    },
    middle-container: {
     flex: 1, // this will take the rest of the space available.
    },
    footer: {
     height: 100,
    }
jayiitb
źródło
1

co jeśli div zawijania był w 100% i użyłeś dopełniania dla liczby pikseli, to jeśli dopełnianie # musi być dynamiczne, możesz łatwo użyć jQuery do zmodyfikowania ilości dopełniania, gdy uruchamiają się zdarzenia.

dfasdljkhfaskldjhfasklhf
źródło
1

Miałem podobny problem, w którym chciałem mieć baner na górze ekranu, który miał jeden obraz po lewej stronie i powtarzający się obraz po prawej stronie do krawędzi ekranu. Skończyło się to tak:

CSS:

.banner_left {
position: absolute;
top: 0px;
left: 0px;
width: 131px;
height: 150px;
background-image: url("left_image.jpg");
background-repeat: no-repeat;
}

.banner_right {
position: absolute;
top: 0px;
left: 131px;
right: 0px;
height: 150px;
background-image: url("right_repeating_image.jpg");
background-repeat: repeat-x;
background-position: top left;
}

Kluczem był właściwy tag. Zasadniczo określam, że chcę, aby powtarzał się od 131 pikseli z lewej do 0 pikseli z prawej.

Mike Carey
źródło
0

W niektórych kontekstach możesz wykorzystać ustawienia marginesów, aby skutecznie określić „szerokość 100% minus N pikseli”. Zobacz zaakceptowaną odpowiedź na to pytanie .

chaos
źródło