Esiste un modo per aumentare la larghezza di un DIV figlio rispetto al DIV principale mediante CSS?


229

C'è un modo per avere un DIV figlio all'interno di un DIV contenitore contenitore che sia più largo del suo genitore. Il DIV figlio deve avere la stessa larghezza della finestra del browser.

Vedi l'esempio seguente: inserisci qui la descrizione dell'immagine

Il DIV figlio deve rimanere come figlio del div genitore. So di poter impostare margini negativi arbitrari sul div figlio per renderlo più ampio, ma non riesco a capire come essenzialmente farlo al 100% di larghezza del browser.

So che posso fare questo:

.child-div{
    margin-left: -100px;
    margin-right: -100px;
}

Ma ho bisogno che il bambino abbia la stessa larghezza del browser che è dinamico.

Aggiornare

Grazie per le risposte, sembra che la risposta più vicina finora sia rendere la posizione DIV figlio: assoluta e impostare le proprietà sinistra e destra su 0.

Il prossimo problema che ho è che il genitore ha position: relative, il che significa che le proprietà left e right sono ancora relative al div parent e non al browser, vedi esempio qui: jsfiddle.net/v2Tja/2

Non riesco a rimuovere la posizione relativa dal genitore senza rovinare tutto il resto.


Le tue esigenze non hanno davvero senso. Il "div figlio" deve rimanere come figlio del div genitore, eppure il div genitore ha position: relative? Di cosa hai bisogno position: relative? Immagino che quello che chiedo sia: cosa stai cercando di fare?
trenta,

@Camsoft Hai visto il mio commento sulla mia risposta? Per me funziona, controlla anche il mio sito web edocuments.co.uk che fa quello che stai cercando di fare in modo diverso
Blowsie

1
@Camsoft, inoltre, non dovrebbe esserci davvero bisogno di jquery / js nella tua soluzione
Blowsie

Risposte:


112

Usa posizionamento assoluto

.child-div {
    position:absolute;
    left:0;
    right:0;
}

14
Ok, prossima domanda, cosa succede se il genitore o un altro antenato ha una disposizione, ovvero posizione: relativa, vedi: jsfiddle.net/v2Tja/2
Camsoft

che ne dici di un altro div genitore in posizione: statico, e un altro div dentro con posizione: relativo? jsfiddle.net/blowsie/v2Tja/3
Blowsie

10
c'è un modo per farlo, con l'altezza automatica del .child-div e avere ancora il posizionamento corretto di seguito?
Philippe Gilbert,

2
e non impostare il div parent su "overflow: hidden" ^^
chris,

@Blowsie che ne dici position:fixed . perché non funziona correttamente?
Mostafa Ghadimi,

227

Ecco una soluzione generica che mantiene l'elemento figlio nel flusso del documento:

.child {
  width: 100vw;
  position: relative;
  left: calc(-50vw + 50%);
}

Impostiamo l' widthelemento figlio per riempire l'intera larghezza della finestra, quindi lo facciamo incontrare il bordo dello schermo spostandolo a leftuna distanza di metà della finestra, meno il 50% della larghezza dell'elemento padre.

demo:

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  overflow-x: hidden;
}

.parent {
  max-width: 400px;
  margin: 0 auto;
  padding: 1rem;
  position: relative;
  background-color: darkgrey;
}

.child {
  width: 100vw;
  position: relative;
  left: calc(-50vw + 50%);

  height: 100px;
  border: 3px solid red;
  background-color: lightgrey;
}
<div class="parent">
  Pre
  <div class="child">Child</div>
  Post
</div>

Supporto browser per vw e per calc () può essere generalmente visto come IE9 e successivi.

Nota: ciò presuppone che il modello di casella sia impostato suborder-box . Senza border-box, dovresti anche sottrarre padding e bordi, rendendo questa soluzione un casino.

Nota: si consiglia di nascondere l'overflow orizzontale del contenitore di scorrimento, poiché alcuni browser potrebbero scegliere di visualizzare una barra di scorrimento orizzontale nonostante non sia presente un overflow.


4
Cosa sai, funziona davvero in IE9. +1 Nice
CatShoes,

13
Questo era esattamente quello che stavo cercando, grazie mille. IMO questa è una risposta migliore di quella accettata poiché questa non interrompe il flusso di documenti
Rémi,

18
vw non va bene. Se hai una barra di scorrimento verticale, 100vw ti darà una barra di scorrimento orizzontale.
Sunny,

2
Sembra che questo funzioni solo di un livello inferiore. C'è un modo per farlo funzionare indipendentemente da quanti elementi padre ha un elemento figlio?
mythofechelon,

3
Questa è la risposta giusta per avvolgere un elemento figlio più ampio in un position: relativegenitore!
Hanfei Sun

14

Ho cercato in lungo e in largo una soluzione a questo problema per molto tempo. Idealmente vogliamo avere il figlio più grande del genitore, ma senza conoscere in anticipo i vincoli del genitore.

E finalmente ho trovato una brillante risposta generica qui . Copiandolo alla lettera:

L'idea qui è: spingere il contenitore al centro esatto della finestra del browser con sinistra: 50%; quindi tirarlo indietro sul bordo sinistro con un margine negativo di -50vw.

.child-div {
  width: 100vw;
  position: relative;
  left: 50%;
  right: 50%;
  margin-left: -50vw;
  margin-right: -50vw;
}

1
Ho scoperto che se voglio che sia, diciamo, il 90% della larghezza della finestra, posso usare quanto sopra ma impostare la larghezza su 90vw. Inoltre, sembra che margin-rightnon abbia alcun effetto in ogni caso.
Jason Dufair,

ho dovuto cambiare i valori di margine sinistro e destro perché il mio wrapper è l'80% della larghezza della finestra. Quindi nel mio caso doveva essere margin-left: -10vw e margin-right: -10vw e poi ha funzionato perfettamente! Grazie!
Timotheus Triebl,

1
Questa è stata una risposta brillante! Grazie.
Cullanrocks,

7

Sulla base del tuo suggerimento suggerimento originale (impostazione dei margini negativi), ho provato a trovare un metodo simile usando le unità percentuali per la larghezza dinamica del browser:

HTML

<div class="grandparent">
    <div class="parent">
        <div class="child">
            <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolore neque repellat ipsum natus magni soluta explicabo architecto, molestias laboriosam rerum. Tempore eos labore temporibus alias necessitatibus illum enim, est harum perspiciatis, sit, totam earum corrupti placeat architecto aut minus dignissimos mollitia asperiores sint ea. Libero hic laudantium, ipsam nostrum earum distinctio. Cum expedita, ratione, accusamus dicta similique distinctio est dolore assumenda soluta dolorem quisquam ex possimus aliquid provident quo? Enim tempora quo cupiditate eveniet aperiam.</p>
        </div>
    </div>
</div>

CSS:

.child-div{
   margin: 0 -100%;
   padding: 0 -100%;
}

.parent {
    width: 60%;
    background-color: red;
    margin: 0 auto;
    padding: 50px;
    position:relative;
}

.grandparent {
        overflow-x:hidden;
        background-color: blue;
        width: 100%;
        position:relative;
    }

I margini negativi consentiranno al contenuto di uscire dal DIV principale. Pertanto ho impostato ilpadding: 0 100%; per riportare il contenuto ai limiti originali del DIV Chlid.

I margini negativi faranno espandere anche la larghezza totale del .child-div fuori dalla vista del browser, risultando in uno scorrimento orizzontale. Quindi dobbiamo tagliare la larghezza dell'estrusione applicando unoverflow-x: hidden a un DIV nonno (che è il genitore del Div genitore):

Ecco il JSfiddle

Ho provato Nils Kaspersson left: calc(-50vw + 50%); ha funzionato perfettamente in Chrome e FF (non sono ancora sicuro di IE) fino a quando non ho scoperto che i browser Safari non lo fanno correttamente. Spero che lo abbiano risolto presto perché in realtà mi piace questo metodo semplice.

Ciò può anche risolvere il problema in cui deve essere l'elemento DIV principale position:relative

I 2 svantaggi di questo metodo di soluzione alternativa sono:

  • Richiede markup extra (ovvero un elemento nonno (proprio come il buon metodo di allineamento verticale della vecchia tabella non è vero ...)
  • Il bordo sinistro e destro del DIV secondario non verrà mai visualizzato, semplicemente perché si trovano al di fuori della vista del browser.

Per favore fatemi sapere se c'è qualche problema riscontrato con questo metodo;). Spero che sia d'aiuto.


4

Flexbox può essere utilizzato per rendere un bambino più largo del suo genitore con tre linee di CSS.

Solo il bambino display, margin-lefte widthdeve essere impostato. margin-leftdipende da quello del bambino width. La formula è:

margin-left: calc(-.5 * var(--child-width) + 50%);

Le variabili CSS possono essere utilizzate per evitare il calcolo manuale del margine sinistro.

Demo n. 1: calcolo manuale

.parent {
  background-color: aqua;
  height: 50vh;
  margin-left: auto;
  margin-right: auto;
  width: 50vw;
}

.child {
  background-color: pink;
  display: flex;
}

.wide {
  margin-left: calc(-37.5vw + 50%);
  width: 75vw;
}

.full {
  margin-left: calc(-50vw + 50%);
  width: 100vw;
}
<div class="parent">
  <div>
    parent
  </div>
  <div class="child wide">
    75vw
  </div>
  <div class="child full">
    100vw
  </div>
</div>

Demo n. 2: utilizzo delle variabili CSS

.parent {
  background-color: aqua;
  height: 50vh;
  margin-left: auto;
  margin-right: auto;
  width: 50vw;
}

.child {
  background-color: pink;
  display: flex;
  margin-left: calc(-.5 * var(--child-width) + 50%);
  width: var(--child-width);
}

.wide {
  --child-width: 75vw;
}

.full {
  --child-width: 100vw;
}
<div class="parent">
  <div>
    parent
  </div>
  <div class="child wide">
    75vw
  </div>
  <div class="child full">
    100vw
  </div>
</div>


3

Ho usato questo:

HTML

<div class="container">
 <div class="parent">
  <div class="child">
   <div class="inner-container"></div>
  </div>
 </div>
</div>

CSS

.container {
  overflow-x: hidden;
}

.child {
  position: relative;
  width: 200%;
  left: -50%;
}

.inner-container{
  max-width: 1179px;
  margin:0 auto;
}

1

puoi provare la posizione: assoluta. e dare larghezza e altezza, in alto: 'asse y dall'alto' e sinistra: 'asse x'


1

Ho avuto un problema simile. Il contenuto dell'elemento figlio doveva rimanere nell'elemento padre mentre lo sfondo doveva estendere l'intera larghezza della finestra.

Ho risolto questo problema creando l'elemento figlio position: relativee aggiungendo uno pseudo elemento ( :before) con esso position: absolute; top: 0; bottom: 0; width: 4000px; left: -1000px;. Lo pseudo elemento rimane dietro al figlio effettivo come uno pseudo elemento di sfondo. Funziona su tutti i browser (anche IE8 + e Safari 6+ - non hanno la possibilità di testare versioni precedenti).

Piccolo violino di esempio: http://jsfiddle.net/vccv39j9/


Questo sembra funzionare, ma fa sì che il browser mostri una barra di scorrimento orizzontale poiché la larghezza è di 4000px. Qual è la soluzione alternativa per mantenere lo pseudo elemento all'interno della larghezza della finestra?
Aaron Hudon,

Ovviamente devi impostare il corpo o il div di avvolgimento della pagina su overflow-x: hidden.
Seika85,

1

Aggiungendo alla soluzione di Nils Kaspersson, sto risolvendo anche la larghezza della barra di scorrimento verticale. Sto usando 16pxcome esempio, che viene sottratto dalla larghezza della porta di visualizzazione. Ciò eviterà la visualizzazione della barra di scorrimento orizzontale.

width: calc(100vw - 16px);
left: calc(-1 * (((100vw - 16px) - 100%) / 2));

1
Credo che ciò 16pxche devi sottrarre perché sta causando la barra di scorrimento orizzontale è il margine / riempimento di default del browser, invece di sottrarlo basta usare questo html, body{ margin:0; padding:0 }quindi non dovrai fare calcoli extra per16px
Mi-Creativity

Questo è quando il contenuto della pagina è più lungo e scende sotto la piega e la barra di scorrimento appare automaticamente. Naturalmente, quando il contenuto è all'interno dell'ovile, questo non è necessario. Aggiungo il 16px alla formula solo quando so che il contenuto della pagina sarà lungo e la barra di scorrimento apparirà davvero.
A-Zone,

penso che non funzionerà sul cellulare. il cellulare non ha barra di scorrimento.
hjchin,

1

Supponendo che il genitore abbia una larghezza fissa, ad esempio #page { width: 1000px; }ed è centrato #page { margin: auto; }, si desidera che il figlio si adatti alla larghezza della finestra del browser che si potrebbe semplicemente fare:

#page {
    margin: auto;
    width: 1000px;
}

.fullwidth {
    margin-left: calc(500px - 50vw); /* 500px is half of the parent's 1000px */
    width: 100vw;
}

1

Per rendere il div bambino ampio quanto il contenuto, prova questo:

.child{
    position:absolute;
    left:0;
    overflow:visible;
    white-space:nowrap;
}

0
.parent {
    margin:0 auto;
    width:700px;
    border:2px solid red;
}
.child {
    position:absolute;
    width:100%;
    border:2px solid blue;
    left:0;
    top:200px;
}

Intelligente, ma non sembra funzionare (con intervalli incorporati all'interno di li, almeno).
ruffin,

0

So che questo è vecchio ma per chiunque venga a questo per una risposta lo faresti così:

Overflow nascosto su un elemento contenente l'elemento genitore, come il corpo.

Dai al tuo elemento figlio una larghezza molto più ampia della tua pagina e posizionalo in assoluto a sinistra del -100%.

Ecco un esempio:

body {
  overflow:hidden;
}

.parent{
  width: 960px;
  background-color: red;
  margin: 0 auto;
  position: relative;    
}

.child {
  height: 200px;
  position: absolute;
  left: -100%;
  width:9999999px;
}

Ecco anche un violino JS: http://jsfiddle.net/v2Tja/288/


0

Quindi la soluzione sarà la seguente.

HTML

<div class="parent">
    <div class="child"></div>
</div>

CSS

.parent{
        width: 960px;
        margin: auto;
        height: 100vh
    }
    .child{
        position: absolute;
        width: 100vw
    }

Sebbene questo codice possa rispondere alla domanda, fornire un contesto aggiuntivo riguardo a come e / o perché risolve il problema migliorerebbe il valore a lungo termine della risposta.
R Balasubramanian,

0

Ho provato alcune delle tue soluzioni. Questo :

margin: 0px -100%;
padding: 0 100%;

è di gran lunga il migliore, dal momento che non abbiamo bisogno di CSS extra per schermi più piccoli. Ho creato una codePen per mostrare i risultati: ho usato un div genitore con un'immagine di sfondo e un div divon figlio con contenuto interno.

https://codepen.io/yuyazz/pen/BaoqBBq

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.