Posizionamento assoluto ignorando l'imbottitura del genitore


173

Come si fa a rendere un elemento posizionato in modo assoluto il rispetto dell'imbottitura del suo genitore? Voglio che un div interno si estenda su tutta la larghezza del suo genitore e sia posizionato nella parte inferiore di quel genitore, sostanzialmente un piè di pagina. Ma il bambino deve onorare l'imbottitura del genitore e non lo sta facendo. Il bambino viene premuto contro il bordo del genitore.

Quindi voglio questo:

inserisci qui la descrizione dell'immagine

ma sto ottenendo questo:

inserisci qui la descrizione dell'immagine

<html>
  <body>
    <div style="background-color: blue; padding: 10px; position: relative; height: 100px;">
      <div style="background-color: gray; position: absolute; left: 0px; right: 0px; bottom: 0px;">css sux</div>
    </div>
  </body>
</html>

Posso farlo accadere con un margine attorno al div interno, ma preferirei non doverlo aggiungere.


5
Perché non cambiare il div sinistro / destro / inferiore del div interno in style="background-color: gray; position: absolute; left: 10px; right: 10px; bottom: 10px;"?
j08691,

12
Sì, ci ho pensato, ma diventa rapidamente un mal di testa di mantenimento perché ogni bambino deve avere il proprio set di offset per spiegarlo. Se onorassero solo l'imbottitura del genitore, potresti semplicemente impostarlo una volta nel genitore e non preoccuparti di tutti i bambini.
d512,

Come sottolineato in precedenza, se si utilizza il valore dell'imbottitura del genitore (posizionato relativo) come left:e right:sul figlio (posizionato assoluto), il problema è risolto. Sto aggiungendo questo b / c che è la risposta che probabilmente gli altri con lo stesso problema stanno cercando.
rda3000,

Hai un problema simile qui: jsfiddle.net/5n4By/6 . Il piè di pagina sta onorando l'imbottitura sinistra dei suoi genitori, ma trabocca a destra. Ti aspetteresti che onori anche la giusta imbottitura per rimanere coerente ...
rafiki_rafi

Risposte:


186

Innanzitutto, vediamo perché questo sta accadendo.

La ragione è che, sorprendentemente, quando una scatola ha la position: absolutesua scatola di contenimento è la scatola di imbottitura del genitore (cioè la scatola attorno alla sua imbottitura). Ciò è sorprendente perché di solito (ovvero quando si utilizza il posizionamento statico o relativo) la casella contenente è la casella del contenuto del genitore .

Ecco la parte rilevante della specifica CSS :

Nel caso in cui l'antenato sia un elemento inline, il blocco contenitore è il riquadro di delimitazione attorno alle caselle di riempimento della prima e dell'ultima casella in linea generate per quell'elemento .... Altrimenti, il blocco di contenimento è formato dal bordo di riempimento di l'antenato.

L'approccio più semplice, come suggerito nella risposta di Winter, è quello di utilizzare padding: inheritl'assolutamente posizionato div. Funziona solo se non si desidera che l'assolutamente posizionato divabbia un'imbottitura aggiuntiva propria. Penso che le soluzioni più generiche (in quanto entrambi gli elementi possono avere una propria imbottitura indipendente) sono:

  1. Aggiungi un ulteriore relativamente posizionato div(senza imbottitura) attorno al assolutamente posizionato div. Quel nuovo divrispetterà l'imbottitura del suo genitore e il assolutamente posizionato divlo riempirà.

    Il rovescio della medaglia, ovviamente, è che stai scherzando con l'HTML semplicemente a scopo di presentazione.

  2. Ripeti l'imbottitura (o aggiungila) sull'elemento posizionato in modo assoluto.

    Il rovescio della medaglia qui è che devi ripetere i valori nel tuo CSS, che è fragile se stai scrivendo direttamente il CSS. Tuttavia, se si utilizza uno strumento di pre-elaborazione simile SASSo LESSè possibile evitare tale problema utilizzando una variabile. Questo è il metodo che uso personalmente.


Perché è l'impostazione predefinita per position: absolute? È sorprendente che la casella di contenimento sia la casella di riempimento, ma deve esserci stata una ragione, proprio come sono sicuro che ci sia un motivo per cui (senza box-sizing) il width& heightnon includere il riempimento o il bordo.
trysis,

1
Solo un'aggiunta: nulla di tutto ciò è influenzato dalla box-sizingproprietà, sul genitore o sul figlio. Questo perché influisce sul dimensionamento , come in larghezza / altezza, ma non sulla scatola di contenimento, anche se ammetto che avrebbe più senso se interessasse entrambi.
trysis,

2
Questa è una buona informazione, ma è la risposta ERRATA. La risposta giusta è Winter qui sotto .... usa il padding: eredit e il tuo elemento Absolute otterrà il padding di cui ha bisogno. Non so perché questo abbia più voti che la risposta giusta ...: P
NotaGuruAtTutti il

1
@NotaGuruAtAll: padding: inheritfunziona bene se l'assolutamente posizionato divnon ha bisogno di alcuna imbottitura propria, e ho aggiunto una menzione di quella tecnica. È meno flessibile, tuttavia, perché non è possibile aggiungere alcuna imbottitura aggiuntiva al posizionamento assoluto div(cioè non si può dire padding: inherit + 5px). Ecco perché preferisco le tecniche che menziono qui.
Kevin Christopher Henry,

1
L'imbottitura ereditata sull'elemento position:absolutefiglio funziona davvero se stai solo cercando il figlio per rispettare l'imbottitura del genitore. Tuttavia, se stai cercando di aggiungere un'ulteriore imbottitura al bambino, dovrai tenere sotto controllo il rapporto tra le imbottiture nel tuo codice. Nessun modo pulito per farlo con solo CSS.
Dylan Pierce,

51

Una cosa che potresti provare è usare i seguenti css:

.child-element {
    padding-left: inherit;
    padding-right: inherit;
    position: absolute;
    left: 0;
    right: 0;
}

Consente all'elemento figlio di ereditare l'imbottitura dal genitore, quindi il figlio può essere posizionato in modo da corrispondere all'ampiezza e all'imbottitura dei genitori.

Inoltre, sto usando box-sizing: border-box;per gli elementi coinvolti.

Non l'ho provato in tutti i browser, ma sembra funzionare in Chrome, Firefox e IE10.


Ho combinato questa risposta e la risposta di @NewSpender. Nel mio caso particolare, il div posizionato in modo assoluto continuava a ignorare il padding ma era limitato dal suo elemento genitore. Quindi dare il div posizionato in assoluto con bordi spessi bianchi ha sminuito l'imbottitura di cui avevo bisogno. Un prerequisito è che lo sfondo deve essere dello stesso colore.
Ogier Schelvis il

Ma OP non vuole che il figlio erediti l'imbottitura del genitore. Vuole che il bambino sia compensato in base all'imbottitura del genitore.
Michael Gummelt,

30

Bene, questa potrebbe non essere la soluzione più elegante (semanticamente), ma in alcuni casi funzionerà senza inconvenienti: invece di riempire, usa un bordo trasparente sull'elemento genitore. Gli elementi figlio posizionati in modo assoluto onoreranno il bordo e sarà reso esattamente lo stesso (tranne per il fatto che stai usando il bordo dell'elemento genitore per lo stile).



6

Ecco il mio colpo migliore. Ho aggiunto un altro Div e l'ho reso rosso e ho cambiato l'altezza del tuo genitore a 200px solo per testarlo. L'idea è che il bambino ora diventa il nipote e il genitore diventa il nonno. Quindi il genitore rispetta il suo genitore. Spero che tu abbia la mia idea

<html>
  <body>
    <div style="background-color: blue; padding: 10px; position: relative; height: 200px;">
     <div style="background-color: red;  position: relative; height: 100%;">    
        <div style="background-color: gray; position: absolute; left: 0px; right: 0px;bottom: 0px;">css sux</div>
     </div>
    </div>
  </body>
</html>

Modificare:

Penso che ciò che stai cercando di fare non possa essere fatto. La posizione assoluta significa che le darai le coordinate che deve onorare. Cosa succede se il genitore ha un'imbottitura di 5px. E posizioni assolutamente il bambino in alto: -5px; a sinistra: -5px . Come è possibile onorare te e il genitore allo stesso tempo ??

La mia soluzione

Se vuoi che onori il genitore, allora non posizionarlo assolutamente.


Grazie, apprezzo il post, ma è comunque una soluzione alternativa al vero problema. Quello che voglio davvero sapere è se riesci a far onorare i bambini all'imbottitura dell'elemento genitore. Se si scopre che la risposta è no, ti darò il rappresentante.
d512,

Se li posizioni assolutamente, allora non onoreranno il loro elemento genitore. Ti onoreranno. Per lo stesso motivo, se non li posizioni assolutamente, non puoi davvero usare cose come bottom: 10px perché onorano il loro elemento genitore. Ma quello che vuoi fare, immagino farà spazio a una contraddizione e, quindi, differirà sui browser. Penso che solo un lavoro intorno farà.
Tocca il

3
Il posizionamento assoluto onora il genitore, questo è il sistema di coordinate che utilizza. Quando dici top 0px, significa 0px di distanza dalla parte superiore del genitore. La domanda è se debba tenere conto o meno dell'imbottitura dei genitori. Se il genitore avesse un'imbottitura di 5px e tu avessi dato il bambino in cima: -5px, lo avrebbe messo a filo con il genitore se il padding del genitore fosse stato rispettato, o 5px sopra il genitore se non lo fosse.
d512,

3

1.) non è possibile utilizzare il bordo grande sul genitore - nel caso in cui si desideri disporre di un bordo specifico

2.) non è possibile aggiungere margine - nel caso in cui il genitore faccia parte di un altro contenitore e si desidera che il genitore occupi l'intero larghezza di quel nonno.

L'unica soluzione che dovrebbe essere applicabile è quella di avvolgere i tuoi figli in un altro contenitore in modo che il tuo genitore diventi il ​​nonno e quindi applicare l'imbottitura al nuovo involucro / genitore dei bambini. Oppure puoi applicare direttamente l'imbottitura ai bambini.

Nel tuo caso:

.css-sux{
  padding: 0px 10px 10px 10px;
}

1

Avrebbe potuto facilmente farlo usando un ulteriore livello di Div.

<div style="background-color: blue; padding: 10px; position: relative; height: 100px;">
  <div style="position: absolute; left: 0px; right: 0px; bottom: 10px; padding:0px 10px;">
    <div style="background-color: gray;">css sux</div>
  </div>
</div>

Demo: https://jsfiddle.net/soxv3vr0/


0

aggiungi imbottitura: eredita nella tua posizione assoluta

.box{
  background: red;
  position: relative;
  padding: 30px;
  width:500px;
  height:200px;
 box-sizing: border-box;
 

}
<div  class="box">

  <div style="position: absolute;left:0;top:0;padding: inherit">top left</div>
  <div style="position: absolute;right:0;top:0;padding: inherit">top right</div>
  <div style="text-align: center;padding: inherit">center</div>
  <div style="position: absolute;left:0;bottom:0;padding: inherit">bottom left</div>
  <div style="position: absolute;right:0;bottom:0;padding: inherit">bottom right</div>


</div>

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.