Centrare un DIV in modo diseguale utilizzando CSS


23

Sto centrando un DIV all'interno di un altro DIV usando un flexbox. Pensa a una finestra di dialogo che viene visualizzata al centro dello schermo quando necessario.

Funziona bene, tuttavia sarebbe molto meglio se lo spazio sopra e sotto la finestra di dialogo non fosse esattamente uguale, avendo il 40% dello spazio rimanente sopra e il 60% sotto la finestra. Diventa complicato perché l'altezza della finestra di dialogo varia con la quantità di testo all'interno.

Ad esempio, se l'altezza del browser è di 1000 px e l'altezza della finestra di dialogo è di 400 px, voglio che lo spazio verticale rimanente (600 px) sia di 240 px sopra e 360 ​​px sotto la finestra di dialogo. Potrei farlo con Javascript, ma sono curioso di sapere se esiste un modo intelligente con CSS. Ho provato ad aggiungere un margine inferiore al DIV #dialogBox, ma non funziona quando l'altezza della finestra di dialogo si avvicina all'altezza del browser.

#dialogBoxPanel
  {
  position:absolute;
  display:flex;
  align-items:center;
  justify-content:center;
  left:0px;
  top:0px;
  width:100%;
  height:100%;
}
#dialogBox
  {
  width:350px;
}
<div id="dialogBoxPanel">
  <div id="dialogBox">Text</div>
</div>


È necessario il pannello esterno per coprire l'intera finestra? Altrimenti, sceglierei la soluzione di css-tricks.com/centering-css-complete-guide , sezione "Sia in orizzontale che in verticale / L'elemento ha larghezza e altezza sconosciute?", E modificherei i valori percentuali di traduzione. (E anche se hai bisogno della dimensione completa del riquadro di visualizzazione del genitore [fondale?], Dovresti essere in grado di combinare entrambi - elimina le cose flessibili, i soggiorni restano.)
04FS

Sì, ho un effetto oscurante sul pannello esterno, quindi deve coprire l'intera finestra. Ma potrei aggiungere un altro DIV al suo interno e la tua soluzione funzionerebbe bene. Grazie 04FS!
Björn Morén,

Per motivi di precisione, stai parlando di allineamento verticale, non di centratura.
Michael Benjamin,

Risposte:


11

Usa lo pseudo elemento e la direzione della colonna per simulare lo spazio bianco. Basta regolare lo flex-growpseudo elemento per controllare la quantità di spazio libero che ciascuno dovrebbe occupare. L'uguale flex-grow darà lo stesso spazio:

Puoi anche usare 2e 3. Dobbiamo semplicemente mantenere lo stesso rapporto:

Un'altra idea è quella di utilizzare un valore superiore uguale 40%e rettificare la posizione con translate (stessa logica con il 50%centraggio)

#dialogBoxPanel {
  position: absolute;;
  left: 0px;
  top: 0px;
  width: 100%;
  height: 100%;
  /* the center */
  background:linear-gradient(red,red) center/100% 1px no-repeat;
}

#dialogBox {
  position:relative;
  top:40%;
  width: 350px;
  transform:translateY(-40%);
  margin:auto;
  border:1px solid;
}
<div id="dialogBoxPanel">
  <div id="dialogBox">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc hendrerit diam eu nisl fringilla ornare. Pellentesque aliquam quam et tellus egestas sodales. Interdum et malesuada fames ac ante ipsum primis in faucibus. Proin bibendum,</div>
</div>


Grazie mille Temani! Entrambe le soluzioni funzionano perfettamente e sembrano identiche ad eccezione del caso speciale in cui la finestra di dialogo è più alta del browser. La prima soluzione mantiene la parte superiore della finestra di dialogo allineata con la parte superiore del browser, ritagliandola nella parte inferiore. Il secondo coltiva sia il fondo che la cima. Solo una questione di preferenza.
Björn Morén,

5

Questa soluzione utilizza display: grid, è una nuova funzionalità, quindi assicurati di controllare il supporto del browser e fai clic qui per saperne di più.

Questa è la linea che controlla gli spazi superiore e inferiore:

grid-template-rows: 40fr [content-start] auto [content-end] 60fr;

Il contenuto del testo dello snippet può essere modificato in modo da verificare che la casella rimanga centrata anche se l'altezza cambia.

#dialogBoxPanel {
    display: grid;
    place-content: center;
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    grid-template-rows: 40fr [content-start] auto [content-end] 60fr;
}
#dialogBox {
    border: 1px solid;
    width: 350px;
    grid-area: content;
}
<div id="dialogBoxPanel">
   <div id="dialogBox" contenteditable>Text</div>
</div>


1
Vorrei prendere in considerazione l'uso di 4fr auto 6fr. Quello che hai funziona ma con un po 'di overflow dal 40% + 60% + 1fr sarà sempre maggiore del 100% e stai centrando in modo che l'overlow sia diviso equamente dall'alto e dal basso: jsfiddle.net/cobutn0e/2 . Noterai anche che non è al 100% come previsto
Temani il

Ho appena cambiato 1fr in auto, preferirei lasciarlo come% per abbinare i valori della domanda. Grazie mille per aver segnalato l'errore!
rafaelcastrocouto,

auto e 1fr daranno lo stesso risultato nel tuo caso, il problema è l'uso della percentuale; 1fr=minmax(auto,1fr)e nel tuo caso cadrà autoperché non c'è spazio libero dal 40% + 60% = 100% (ecco perché avrai sempre un overflow)
Temani Afif

1
ecco un altro violino per illustrare il mio punto: jsfiddle.net/cobutn0e/3 nota come i primi 3 siano gli stessi, il terzo scenda a 0 e l'ultimo è quello che ho suggerito
Temani Afif

Ora capisco, ha senso. Utilizzerò 40fr e 60fr poiché è lo stesso alla fine della giornata. Grazie ancora per aver dedicato del tuo tempo ad insegnarmi!
rafaelcastrocouto,

4

È possibile aggiungere div spaziatori e impostare la crescita flessibile con rapporto 4: 6.

#dialogBoxPanel {
  position: absolute;
  display: flex;
  flex-direction: column;
  align-items: center;

  left: 0px;
  top: 0px;
  width: 100%;
  height: 100%;
}

#dialogBox {
  width: 350px;
  border: 1px solid black;
}

.spacer-top{
  flex-grow: 4;
}
.spacer-bottom{
  flex-grow: 6;
<div id="dialogBoxPanel">
  <div class="spacer-top"></div>
  <div id="dialogBox">Text</div>
  <div class="spacer-bottom"></div>
</div>


Solo ora ho visto la risposta di @Temani Afif, ma funziona allo stesso modo con "after" e "before"
Itay Gal

0

In modo semplice utilizzando posizione e margine, ho ipotizzato che l'altezza della finestra di dialogo sia sempre il 40% dell'altezza del browser.

.modal{
            max-height:50%;
            width:400px;
            margin: 10% auto 5% auto;
            position:absolute;
            top:0;
            bottom:0;
            right:0;
            left:0;
            overflow-y: auto
        }
        .modal-body{
            background-color: beige;
            padding: 20px;
            line-height: 21px
        }

HTML

<div class="modal">
 <div class="modal-body">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea </div>
</div>

Ciao benvenuto, la prossima volta leggi attentamente la domanda, si afferma: "l'altezza della finestra di dialogo varia con la quantità di testo all'interno".
rafaelcastrocouto,

1
@rafaelcastrocouto - ora controllandolo in altezza massima in percentuale, poiché lasciarlo senza altezza non risolverà lo scopo delle domande dell'estetica dello spazio superiore e inferiore.
Anshul Chaurasia,
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.