label e input in grid

  • Creatore Discussione Creatore Discussione Gae
  • Data di inizio Data di inizio

Gae

Utente Attivo
15 Mar 2021
55
4
8
Salve non riesco a trovare una soluzione dinamica. Ho un form in cui visualizzo la label e l'input sulla stessa riga ed uso la classe grid e va bene
Adesso devo, in maniera non fissa, avere delle righe con caratteristiche diverse:
span di tutte le colonne
label - input
label - input, label - input, label - input
label - input, label - input
label - input
e così via
Vi allego il codice:
CSS

.container-wrapper {
text-align: center;
}

.container {
display: inline-block; /* Si adatta al contenuto */
box-sizing: border-box;
padding: 5px 30px 15px 25px;
background-color: black;
color: white;
}

form {
display: grid;
/*grid-template-columns: auto 1fr;*/ /* Due colonne: la prima si adatta al contenuto, la seconda occupa lo spazio rimanente */
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); /* Colonne automatiche */
gap: 10px;
}
.form-inte {
font-size: 2em;
padding: 10px;
margin-bottom: 20px;
}

.form-row {
display: contents; /* Fa sì che il comportamento del grid venga applicato alle righe di contenuto */
}

.form-row label {
/*grid-column: 1;*/ /* Prima colonna */
span: 1;
text-align: right; /* Allinea il testo a destra */
white-space: nowrap; /* Impedisce che il testo venga a capo */
}

.form-row input,
.form-row select {
/*grid-column: 2;*/ /* Seconda colonna */
span: 1;
width: 100%; /* Occupano tutto lo spazio rimanente */
}

.form-row.buttons-row {
display: flex;
justify-content: flex-end; /* Allinea i pulsanti a destra */
gap: 30px; /* Spazio tra i pulsanti */
margin-top: 30px;
/*grid-column: 1 / span 2;*/ /* Estende la riga dei pulsanti su entrambe le colonne della griglia */
}

.form-row.buttons-row button,
.form-row.buttons-row a {
margin: 0; /* Rimuove margini verticali che potrebbero causare l'impilamento */
}


HTML

<div class="container-wrapper">
<div class="container">
<div class="form-inte"> Modulo di Registrazione </div>

<form method="post" action="">
{% csrf_token %}

<div class="form-row">
<label for="username">Nome Utente:</label>
<input type="text" id="username" name="username" placeholder="Inserisci il tuo nome utente" required>

<label for="password">Password:</label>
<input type="password" id="password" name="password" placeholder="Inserisci la tua password" required>
</div>

<div class="form-row">
<label for="email">Email:</label>
<input type="email" id="email" name="email" placeholder="Inserisci la tua email" required>
</div>

<div class="form-row">
<label for="gender">Genere:</label>
<select id="gender" name="gender" required>
<option selected disabled value="">Scegli...</option>
<option value="male">Maschio</option>
<option value="female">Femmina</option>
<option value="other">Altro</option>
</select>
</div>

<div class="form-row">
<label for="terms">Accetto i termini e le condizioni</label>
<input type="checkbox" id="" name="terms" required>
</div>

<div class="form-row buttons-row">
<a href="#">Annulla</a>
<button type="submit">Invia</button>
</div>
</form>
</div>
</div>
 
Ciao, posso giusto supporre che forse in questo caso tu non abbia bisogno di grid; potrebbe essere sufficiente impostare le righe con flexbox, se non ti serve rispettare esattamente l'incolonnamento delle celle in ogni riga, però non mi è ben chiaro quale risultato vorresti ottenere. Puoi fare un esempio più chiaro, magari con una bozza disegnata?
 
Ciao, posso giusto supporre che forse in questo caso tu non abbia bisogno di grid; potrebbe essere sufficiente impostare le righe con flexbox, se non ti serve rispettare esattamente l'incolonnamento delle celle in ogni riga, però non mi è ben chiaro quale risultato vorresti ottenere. Puoi fare un esempio più chiaro, magari con una bozza disegnata?
Grazie per la risposta, ti allego l'immagine di quello che realizzato. L'utlimo rigo che é una replica del precedente dovrebbe essere visualizzato sul rigo della primo campo descrizione. Tra le varie righe non é importante che che i 2 e 3 campi siano allineati in verticale

py.PNG
 
Tra le varie righe non é importante che che i 2 e 3 campi siano allineati in verticale
Bene, ed è proprio per questo motivo che non è necessario avere una impaginazione a griglia.
Come già anticipato ti basta applicare il display:flex alle righe (ovviamente dovrai rimuovere il display:grid dall'elemento contenitore), poi vedi tu come dimensionare i vari elementi contenuti nelle righe.
Fai magari qualche prova e fai sapere se riesci o se hai bisogno di ulteriore aiuto.
 
Bene, ed è proprio per questo motivo che non è necessario avere una impaginazione a griglia.
Come già anticipato ti basta applicare il display:flex alle righe (ovviamente dovrai rimuovere il display:grid dall'elemento contenitore), poi vedi tu come dimensionare i vari elementi contenuti nelle righe.
Fai magari qualche prova e fai sapere se riesci o se hai bisogno di ulteriore aiuto.

in che cosa differisce flex dalla grid per poter avere campi in linea ?
Così posso farmi un'idea su come operare
 
Ti risposi qualche mese fa ad una tua stessa discussione per quel che riguarda la differenza principale:

Partiamo quindi da questo punto: flex è concepito per agire su una sola dimensione alla volta, mentre grid è concepito per agire contemporaneamente sulle due dimensioni (un po' come accade con le tabelle).

Con flex hai quindi la possibilità di gestire al meglio gli elementi in modo allineato e/o distribuito dentro un contenitore, secondo un unico verso (orizzontale oppure verticale).
Con grid hai invece possibilità di allineare gli elementi contemporaneamente vincolandone la disposizione sia in orizzontale sia in verticale, secondo ciò che ti serve fare.

Queste due modalità dispongono di un corredo di svariate altre proprietà che ti permettono di impostare al meglio gli elementi rispettivamente in una o due dimensioni.
Chiaramente ci sono poi tantissime possibili casistiche da valutare di caso in caso per poter capire cosa utilizzare di preciso e come poterlo impostare.

Va da sé che in questo specifico caso è più ottimale l'uso di flex, perché appunto non ti serve avere una disposizione a griglia (in cui gli elementi sono vincolati contemporaneamente sulle righe e sulle colonne) ma ti serve solo distribuire gli elementi in orizontale (anche se su più righe).

Applicando flex alle righe, e definendo opportunamente le relative proprietà, puoi ottenere la distribuzione ottimale degli elementi all'interno delle singole righe.

Dalle tue precedenti discussioni so che hai già avuto modo di cimentarti con flex, per cui non voglio fornirti un esempio già pronto ma ti invito piuttosto a fare tu stesso qualche prova per cercare di impostare al meglio il tuo elaborato.
 
Ciao, confermo quello che hai scritto sulle mie precedenti richieste ma non sono mai riuscito a capire appieno sia Flex che grid. Se non ti dispiace stavolta vorrei approfondirle e capirle per bene.
Ho seguito il tuo consiglio e azzerato e riscritto il codice di un piccolo esempio. Parto sempre così e poi aumento la difficoltà

Sono partito per l'elaborazione di una form che sia centrata sia in rizzontale che inverticale e che abbia sulle varie righe 1 sola label e input o pù label e più input

1) Definisco il body con altezza, 100% per prendere tutto il viewPort. Mi servirà in seguito per vaere il footer in fondo al video quando il contenuto é corto

2) definisco la classe container-flex, come il body. Se ho capito bene é meglio scrivere anche qui i parametri

3) definisco la form, il form-group per lo spazio verticale tra i campi, il form-label

4) in ultimo il bottone

La prima cosa che non sono riuscito a a fare é avere la prima label incolonnata a dx sulla label più larga. Ci riesco solo se definisco una larghezza fissa. La form dev'essere dinamica per utilizzarla con qualsiai campo o situazione

Ti allego Immagine con flex (flex) e l'immagine di come dovrebbe venire per l'incolonnamento della prima label a dx (grid)

Se non sarà possibile seguirmi nel ragionamento dimmelo così non ti diturbo

Grazie


HTML
<body>
<div class="container-flex">
<form class="form">
<div class="form-group">
<label for="nome">Nome:</label>
<input type="text" id="nome" name="nome">
</div>
<div class="form-group">
<label for="email">Email:</label>
<input type="email" id="email" name="email">

<label for="email">Email:</label>
<input type="email" id="email" name="email">
<label for="email">Email:</label>
<input type="email" id="email" name="email">

</div>
<div class="form-group">
<label for="telefono">Telefono:</label>
<input type="tel" id="telefono" name="telefono">
</div>
<div class="form-group">
<div class="input-group">
<label for="citta">Città:</label>
<input type="text" id="citta" name="citta">

<label for="cap">CAP:</label>
<input type="text" id="cap" name="cap">
</div>
</div>
<button type="submit">Invia</button>
</form>
</div>
<footer>
<p>Questo è il footer.</p>
</footer>
</body>

CSS
body, html {
margin: 0;
padding: 0;
height: 100%;
font-family: Arial, sans-serif;
}

/* Container flex con posizionamento centrale sia in verticale che orizzontale */
.container-flex {
display: flex;
justify-content: center;
align-items: center;
height: 100%; /* lo centra in Verticale */
}

/* Stile della form */
.form {
background-color: #f5f5f5;
padding: 20px;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}

/* Spazio in verticale tra un campo e l'altro */
.form-group {
margin-bottom: 15px;
}

/* Label e input sulla stessa linea */
.form-group label {
/*width: 100px;*/
text-align: right;
margin-right: 10px; /* Distanza dell'input */
}

.form-group input {
width: 100px; /* Larghezza degli input */
padding: 5px;
border: 1px solid #ccc;
border-radius: 4px;
}

/* Stili per il pulsante di invio */
button {
display: block;
width: 100%;
padding: 10px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}

button:hover {
background-color: #45a049;
}

/* Stili per il footer */
footer {
position: fixed;
bottom: 0;
width: 100%;
background-color: #333;
color: white;
text-align: center;
padding: 10px 0;
}
 

Allegati

  • flex.PNG
    flex.PNG
    5,6 KB · Visite: 26
  • grid.PNG
    grid.PNG
    3,4 KB · Visite: 24
Ciao, scusami ma non ho avuto modo di risponderti prima,
Ho visto il tuo elaborato, cerco di analizzare brevemente i punti da te indicati (anche quelli "marginali") benché non sia così semplice perché bisognerebbe approfondire svariate sfaccettature dell'argomento e non è fattibile farlo in questo contesto.
1) Definisco il body con altezza, 100% per prendere tutto il viewPort. Mi servirà in seguito per vaere il footer in fondo al video quando il contenuto é corto
No, il footer ha position fixed, quindi non è posizionato in riferimento al body ma bensì alla finestra stessa del browser (viewport). Il body potrebbe anche avere altezza 0 che vedresti comunque il footer appiccicato in basso al viewport, proprio perché è fixed.

Impostando height 100% al body avresti piuttosto dei problemi collaterali; avendo dato 100% anche a .container-flex, se l'altezza dei contenuti dovesse eccedere quella dimensione (cioè l'altezza stessa del viewport), i contenuti risulteranno tagliati e la pagina non scorrerebbe del tutto per poterli raggiungere.

2) definisco la classe container-flex, come il body. Se ho capito bene é meglio scrivere anche qui i parametri
Vale lo stesso discorso fatto per il body, in questo contesto non hai motivo di applicare height 100%. Piuttosto, essendo il footer impostato come fixed, i contenuti gli scorrono sotto, per cui se questi eccedono l'altezza disponibile del viewport (cioè quella restante al netto di quella del footer) allora risulteranno coperti dal footer stesso. Cioè, in questa situazione, la parte bassa dei contenuti risulterà sempre coperta dal footer.

Per ovviare a questo problema ci sono svariate soluzioni a seconda di cosa si vuole ottenere nello specifico.
Ti invito a fare qualche ricerca del tipo "css fixed footer variable height".

L'uso di grid può essere una semplice soluzione per questo particolare punto. Anche con flex puoi arrivare a risultati equivalenti in modo relativamente semplice.

Per il momento non mi dilungo su questo punto "marginale" ma ti invito ad affrontarlo con qualche ricerca, come indicato, e avendo comunque chiaro quali siano i problemi collaterali per come invece hai impostato tu l'elaborato.

3) definisco la form, il form-group per lo spazio verticale tra i campi, il form-label
La prima cosa che non sono riuscito a a fare é avere la prima label incolonnata a dx sulla label più larga. Ci riesco solo se definisco una larghezza fissa.
Arriviamo al dunque. Gli elementi form-group, da ciò che vedo, sono sostanzialmente le righe del form, nelle quali vuoi "distribuire" i vari campi (e relative etichette).

Non mi è ancora chiaro il risultato visivo finale che vorresti ottenere tenendo conto che ogni riga può avere un numero variabile di campi. Purtroppo le due immagini di esempio non chiariscono. Sarebbe utile se tu facessi una bozza di esempio.

L'immagine con grid che stai prendendo come esempio ha solo un etichetta+campo per ogni riga. Per tale motivo è possibile rispettare un incolonnamento degli elementi, perché tutte le righe hanno lo stesso numero di colonne (label e input) e per questo ogni label può essere allineata all'interno della prima colonna; infatti la larghezza di ogni colonna (per grid) viene calcolata automaticamente rispettando (tra tutte le righe) la larghezza del contenuto con ingombro maggiore (per la relativa colonna).

Va da sé che l'allineamento a destra di ogni label, usando grid, risulta possibile perché viene rispettata la larghezza della colonna.

Nei primi post ti ho chiesto esplicitamente se ti servisse rispettare l'allineamento degli elementi in colonna, proprio per capire come poter procedere.
Mi hai dato questa risposta:
Tra le varie righe non é importante che che i 2 e 3 campi siano allineati in verticale
per cui deduco che l'allineamento in colonna (che sia a destra, a sinistra, al centro) per quelle label, dovrebbe essere irrilevante.

Ora, non c'è alcun problema se vuoi allineare questi elementi, come non c'è nessun problema se per questo sia necessario l'uso di grid, ma il problema nasce quando, oltre l'allineamento in colonna, vuoi poter avere un numero variabile di elementi per ogni riga... la botte piena è la moglie ubriaca, dice il saggio ;)

Potrei ipotizzare che la prima etichetta col primo campo debbano rispettare, per ogni riga, l'allineamento in colonna mentre gli altri eventuali elementi per ogni riga possono essere appesi a seguire senza uno specifico allineamento in colonna. Potrei ipotizzare che la larghezza degli elementi input debba estendersi automaticamente per riempire lo spazio restante per ciascuna relativa riga... e così via. Potrei fare altre varie ipotesi ma sarebbe meglio chiarire quale debba essere il risultato.

Quindi ti chiedo nuovamente: potresti fare uno schizzo di ciò che vuoi ottenere, magari prendendo come ipotesi proprio gli elementi dell'ultimo elaborato?
 
Gentilissimo a darmi una risposta dettagliata

ho inserito altezza 100% per body e container-text per far visualizzare il footer al centro in verticale. E qualora il body sia inferiore all'altezz del viewport far visualizzare il footer in fondo al video e non alla fine del body

Avevo letto un articolo in cui si diveva che usando il min-hight: 100% o hight: 100% si otteneva tale risultato e non riuscendoci ho inserito il fixed nella classe footer
Dall'immagine bf.png il risultato senza fixed

Il primo punto importante é avere la prima colonna della label incolonnata a dx e la larghezza del form dinamica a seconda della larghezza più larga data dalla somma sulla singola riga delle label ed input. Ti allego immagine form del risultato che vorrei ottenere, form.png

Spero di essere stato chiaro, altrimenti dimmelo
 

Allegati

  • bf.PNG
    bf.PNG
    16,8 KB · Visite: 24
  • body.PNG
    body.PNG
    7,4 KB · Visite: 26
  • form.PNG
    form.PNG
    7,1 KB · Visite: 23
Il primo punto importante é avere la prima colonna della label incolonnata a dx e la larghezza del form dinamica a seconda della larghezza
ok, quindi penso che in questo caso serva il grid per poter impostare anche giusto la prima colonna in modo da allineare le label.
Impegni a parte, appena posso provo qualcosa e ti aggiorno, sempre che tu non riesca a risolvere prima.
 
ok, quindi penso che in questo caso serva il grid per poter impostare anche giusto la prima colonna in modo da allineare le label.
Impegni a parte, appena posso provo qualcosa e ti aggiorno, sempre che tu non riesca a risolvere prima.
ci continuo a lavorare. se hai info mi farebbe piacere
 
Ciao, ho fatto qualche prova e sono arrivato ad una conclusione.

Considerando il fatto che vuoi avere una prima colonna fissa (quella dei label con allineamento a destra) e a seguire un numero indefinito di altri elementi per riga, a mio parere è necessario avere comunque una griglia di base con un numero ben definito di colonne - supponiamo 3 colonne - in cui nella 1a hai il label, nella 2a hai l'input relativo al primo label e nella 3a hai un elemento (ad es. div) che racchiude la serie degli altri elementi relativi alla riga.

Sarebbe possibile anche avere giusto 2 colonne, dove il primo input di ogni riga lo vai a mettere assieme al gruppo dei restanti elementi, ma per convenzione ho preferito mantenere "affiancati" (a livello di codice) i due elementi label+input.

Puoi quindi impostare grid come base per ottenere un layout a 3 colonne, mentre per i gruppi della 3a colonna puoi impostare flex in modo da poterli disporre in modo ottimale.

Qui un esempio di ciò che per me si potrebbe fare:
HTML:
<body>
  <div class="container-flex">
    <form class="form">

      <label for="nome">Nome:</label>
      <input type="text" id="nome" name="nome">
      <div></div>

      <label for="email">Email:</label>
      <input type="email" id="email" name="email">
      <div class="form-group">
        <label for="email2">Email 2:</label>
        <input type="email" id="email2" name="email">
        <label for="email3">Email 3:</label>
        <input type="email" id="email3" name="email">
      </div>

      <label for="telefono">Telefono:</label>
      <input type="tel" id="telefono" name="telefono">
      <div></div>

      <label for="citta">Città:</label>
      <input type="text" id="citta" name="citta">
      <div class="form-group">
        <label for="cap">CAP:</label>
        <input type="text" id="cap" name="cap">
      </div>

      <button type="submit">Invia</button>
    </form>
  </div>
  <footer>
    <p>Questo è il footer.</p>
  </footer>
</body>

CSS:
body,
html {
  margin: 0;
  padding: 0;
  min-height: 100vh;
  font-family: Arial, sans-serif;
}
body {
  display: flex;
  flex-direction: column;
}
.container-flex {
  display: flex;
  margin: auto;
}
.form {
  display: grid;
  grid-template-columns: repeat(3, auto);
  align-items: center;
  gap: 10px;
  padding: 20px 20px;
  border-radius: 8px;
  background-color: #f5f5f5;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
}
.form-group {
  display: flex;
  align-items: inherit;
  gap: inherit;
}
.form > label {
  text-align: right;
}
.form input {
  width: 100px;
  padding: 5px;
  border: 1px solid #ccc;
  border-radius: 4px;
}
button {
  display: block;
  grid-column: span 3;
  padding: 10px;
  background-color: #4caf50;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}
button:hover {
  background-color: #45a049;
}
footer {
  position: sticky;
  bottom: 0;
  width: 100%;
  padding: 10px 0;
  color: white;
  text-align: center;
  background-color: #333;
}

Ho impostato anche il layout principale in base a quanto ti ho indicato nei precedenti post. Non ho commentato il codice per questioni di tempo, ti invito comunque a giocarci un po' e cercare di capire come funziona sia la struttura html sia la parte css.
Se poi hai dubbi chiedi pure, risponderò appena posso. Per ora è tutto, fai sapere :)
 
Scusa il ritardo ma sono stato molto impegnato
Ti ringrazio per l'esempio ma va bene in parte in quanto la colonna della prima label dev'essere incolonnata a dx e larga quanto la label + larga
 
Scusa il ritardo ma sono stato molto impegnato
Nessun problema, figurati.

ma va bene in parte in quanto la colonna della prima label dev'essere incolonnata a dx e larga quanto la label + larga
Dovrebbe funzionare esattamente come stai dicendo.

Fammi capire, hai provato il codice?
Lo hai provato da solo, in un nuovo documento html?
Oppure lo hai inserito nel tuo elaborato già esistente?

Se lo stai inserendo in un contesto dove già è presente del css che agisce su tali elementi, allora è possibile che ci siano dei conflitti tra le regole css. In tal caso bisogna capire come "aggiustare" il css,

Fai sapere.
 
Nessun problema, figurati.


Dovrebbe funzionare esattamente come stai dicendo.

Fammi capire, hai provato il codice?
Lo hai provato da solo, in un nuovo documento html?
Oppure lo hai inserito nel tuo elaborato già esistente?

Se lo stai inserendo in un contesto dove già è presente del css che agisce su tali elementi, allora è possibile che ci siano dei conflitti tra le regole css. In tal caso bisogna capire come "aggiustare" il css,

Fai sapere.

Ho creato un nuovo file html e css
 

Allegati

  • a.PNG
    a.PNG
    4,7 KB · Visite: 19
Non è ciò che visualizzo io con lo stesso codice che ho postato. Qualcosa non quadra.

Puoi postare esattamente il codice (completo) del tuo file html e di quello css che stai usato per mostrare quel risultato?
Se hai incluso il css come file esterno, assicurati che il tag link stia puntando al file corretto.
Puoi indicare che browser stai usando e che versione?

Ho inserito su codepen l'esempio che ho postato, qui il link:
https://codepen.io/OpenDec/pen/bGPxmyV

Puoi dirmi se in questo caso vedi il risultato voluto oppure se vedi sempre quello non corretto?
Fai sapere
 
Ultima modifica:
Controllato su CodePen ed é come dici tu e corrisponde a quello che serve a me.
Riguaderò il codice
Grazie per l'aiuto
 
Controllato su CodePen ed é come dici tu e corrisponde a quello che serve a me.
Riguaderò il codice

Bene :) almeno possiamo essere certi che il tuo browser non ha problemi di supporto.
Lascio l'esempio su codepen, puoi quindi prendere quello come base per eventuali test e per rielaborarlo sul tuo progetto.

Grazie per l'aiuto
Figurati!
Buon proseguimento. Fai sapere poi se riuscirai a far funzionare il tutto ;)
 

Discussioni simili