Larghezza div 100% meno quantità fissa di pixel


316

Come posso ottenere la seguente struttura senza usare tabelle o JavaScript? I bordi bianchi rappresentano i bordi dei div e non sono rilevanti per la domanda.

Struttura 1

La dimensione dell'area al centro varierà, ma avrà valori di pixel esatti e l'intera struttura dovrebbe ridimensionarsi in base a tali valori. Per semplificarlo, avrei bisogno di un modo per impostare la larghezza "100% - n px" sui div top-middle e bottom-middle.

Apprezzerei una soluzione cross-browser pulita, ma nel caso non fosse possibile, gli hack CSS faranno.

Ecco un bonus. Un'altra struttura con cui ho avuto problemi e finisco per usare tabelle o JavaScript. È leggermente diverso, ma introduce nuovi problemi. Lo sto usando principalmente nel sistema di finestre basato su jQuery, ma mi piacerebbe mantenere il layout fuori dallo script e controllare solo le dimensioni di un elemento (quello centrale).

Struttura 2


Per il secondo elemento, stai dicendo che vuoi che l'altezza dell'elemento molto centrale sia fissata, ma gli altri elementi vicini siano dinamici
Casebash,

Risposte:


78

È possibile utilizzare elementi nidificati e riempimento per ottenere un bordo sinistro e destro sulla barra degli strumenti. La larghezza predefinita di un divelemento è auto, il che significa che utilizza la larghezza disponibile. È quindi possibile aggiungere un'imbottitura all'elemento e rimane comunque all'interno della larghezza disponibile.

Ecco un esempio che puoi usare per mettere le immagini come angoli arrotondati sinistro e destro e un'immagine centrale che si ripete tra loro.

HTML:

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

Il 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;
}

Grazie per quello Ho dovuto modificarlo un po 'per la mia situazione. Il primo div nidificato necessitava di un margine destro invece del riempimento, e anche il div centrale aveva lo stesso margine destro.
Max

3
Ottima soluzione solo una piccola cosa -> funziona perché ".Header div div" ignora ".Header div" . Dovrebbe essere invece ".Header> div" e ".Header> div> div" . In effetti, ".Header div" indica qualsiasi figlio div o sub div figlio mentre ".Header> div" significa solo figli diretti di .Header
Charles HETIER

@CharlesHETIER: Sì, funziona anche ed è più facile da usare in quanto non è necessario sostituire tutte le impostazioni della regola meno specifica. La risposta è stata scritta quando il supporto per l' >operatore non era ancora abbastanza buono per essere affidabile.
Guffa,

1
Questo è obsoleto, vedere la risposta di seguito sulla funzione calc su css.
María Arias de Reyna Domínguez,

2
@delawen: devi aspettare un po 'prima che diventi obsoleto. Non è supportato calcin IE 8 o nelle versioni correnti di Anroid Browser o Opera. caniuse.com/#search=calc
Guffa

760

Nuovo modo in cui mi sono appena imbattuto in: csscalc() :

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

Fonte: larghezza css 100% meno 100px


86
La migliore risposta nel 2013 IMHO. La risposta accettata è obsoleta.
Marinaio danubiano,

7
È ora che qualcuno si imbatta in questo. Ho finito con gli hack adesso che lo so. +1 @lechlukasz
preahkumpii

47
Dopo 10 anni di lotte CSS, questa risposta merita +20000! Non riesco ancora a credere ai miei occhi ...
skobaljic

8
Tutto ciò che posso dire è ... youtube.com/…
Jazz

5
Più compatibile? -> $ ('# yourEl'). css ('larghezza', '100%'). css ('larghezza', '- = 100px'); (jQuery)
sboy031

7

Mentre la risposta di Guffa funziona in molte situazioni, in alcuni casi potresti non volere che i pezzi di imbottitura sinistra e / o destra siano i genitori del div centrale. In questi casi, è possibile utilizzare un contesto di formattazione dei blocchi al centro e spostare i div di riempimento a sinistra e a destra. Ecco il codice

HTML:

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

Il 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;
}

Sento che questa gerarchia di elementi è più naturale rispetto ai div annidati nidificati e rappresenta meglio ciò che è nella pagina. Per questo motivo, bordi, imbottitura e margine possono essere applicati normalmente a tutti gli elementi (cioè: questa "naturalezza" va oltre lo stile e ha ramificazioni).

Nota che questo funziona solo su div e altri elementi che condividono la sua proprietà 'riempire il 100% della larghezza di default'. Gli input, le tabelle e possibilmente altri richiederanno di avvolgerli in un div contenitore e aggiungere un po 'più di CSS per ripristinare questa qualità. Se sei abbastanza sfortunato da trovarti in quella situazione, contattami e mi occuperò del css.

jsfiddle qui: jsfiddle.net/RgdeQ

Godere!


6

È possibile utilizzare il layout Flexbox . È necessario impostare flex: 1l'elemento per il quale è necessario disporre di larghezza o altezza dinamicheflex-direction: row and column .

Larghezza dinamica:

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*/
}

Produzione:


Altezza dinamica:

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*/
}

Produzione:


3

Il solito modo di farlo è come indicato da Guffa, elementi nidificati. È un po 'triste dover aggiungere markup extra per ottenere i ganci necessari per questo, ma in pratica un div wrapper qui o lì non farà male a nessuno.

Se devi farlo senza elementi extra (ad es. Quando non hai il controllo del markup della pagina), puoi usare il ridimensionamento della casella , che ha un supporto del browser abbastanza decente ma non completo o semplice. Probabilmente più divertente di dover fare affidamento sullo scripting però.


3

Forse sono stupido, ma la tabella non è la soluzione ovvia qui?

<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}

Un altro modo che ho capito in Chrome è ancora più semplice, ma amico è un trucco!

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

Questo da solo dovrebbe riempire il resto della linea in orizzontale, come fanno le celle della tabella. Tuttavia, si verificano alcuni strani problemi che vanno oltre il 100% del suo genitore, impostando la larghezza su un valore percentuale lo risolve comunque.


2

Possiamo raggiungere questo obiettivo utilizzando la scatola flessibile molto facilmente.

Se abbiamo tre elementi come Header, MiddleContainer e Footer. E vogliamo dare un'altezza fissa a Header e Footer. allora possiamo scrivere così:

Per React / RN (i valori predefiniti sono 'display' come flex e 'flexDirection' come colonna), nel web css dovremo specificare il contenitore del corpo o il contenitore contenente questi come display: 'flex', flex-direction: 'column' come sotto:

    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,
    }

1

cosa succede se il div wrapping era al 100% e hai usato il padding per una quantità di pixel, quindi se il padding # deve essere dinamico, puoi facilmente usare jQuery per modificare la quantità di padding quando i tuoi eventi si attivano.


1

Ho avuto un problema simile in cui volevo un banner nella parte superiore dello schermo con un'immagine a sinistra e un'immagine ripetuta a destra fino al bordo dello schermo. Ho finito per risolverlo in questo modo:

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;
}

La chiave era il tag giusto. Fondamentalmente sto specificando che voglio che si ripeta da 131px da sinistra a 0px da destra.


0

In alcuni contesti, è possibile sfruttare le impostazioni dei margini per specificare in modo efficace "Larghezza 100% meno N pixel". Vedi la risposta accettata a questa domanda .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.