Perché la larghezza si applica a un pulsante con display in linea?

Secondo MDN , un button è un elemento in linea.

Tuttavia, gli elementi dei pulsanti hanno uno stile predefinito con display: inline-block (vedere questa domanda )

 button, textarea, input, select { display: inline-block } 

Fin qui tutto bene.

Però:

Se ora imposto il pulsante con display:inline – la larghezza è ancora valida !!

DEMO

Ora, secondo le specifiche : la width non si applica agli elementi in linea (che non sono sostituiti)

Si applica a: tutti gli elementi, ma elementi inline non sostituiti, righe di tabella e gruppi di righe

Stando così le cose:

Perché la larghezza si applica ancora a un elemento del button incorporato?

Come accennato nei commenti, sono abbastanza sicuro che ciò abbia a che fare con il comportamento di rendering specifico del browser, così tipico degli elementi del modulo. Quello che credo stia accadendo quando imposta la display: inline sul pulsante è … niente. In effetti, è lo stesso della tipica display: inline-block predefinita del browser display: inline-block , su cui si applica la proprietà width .

Fare riferimento alla sezione 10.2 , che descrive la proprietà della width stessa. In particolare, spiega perché esattamente la proprietà width non si applica agli elementi inline (o ai box in linea ):

Questa proprietà non si applica agli elementi inline non sostituiti. La larghezza del contenuto delle caselle di un elemento in linea non sostituito è quella del contenuto visualizzato al loro interno (prima di qualsiasi offset relativo dei bambini). Ricorda che le scatole in linea scorrono nelle caselle di linea. La larghezza delle caselle di riga è data dal loro blocco contenitore, ma può essere abbreviata dalla presenza di float.

In breve, è perché il contenuto degli elementi in linea risiede nelle caselle di riga . La larghezza di una casella di riga non può essere controllata direttamente; è determinato interamente dal blocco contenitore e da eventuali galleggianti accidentali. È ansible visualizzare un esempio di rendering di riquadri di riga nella sezione 9.4.2 , che descrive i contesti di formattazione in linea.

Se display: inline effettivamente reso un pulsante di rendering come un riquadro in linea, tutto il suo contenuto si rovescia e non apparirebbe più, o funzionerebbe, come un pulsante. Ha senso voler evitare che ciò accada, e penso che sia proprio quello che fanno i browser.

Quindi cosa fanno esattamente per impedirlo? Un pulsante è un elemento sostituito? Non posso dire di sicuro. Ma nota, nella sezione 9.2.2 , dice:

Le caselle a livello interno che non sono caselle in linea (come elementi di livello inline sostituiti, elementi di blocco inline e elementi di tabella inline) sono chiamate caselle a livello in linea atomico poiché partecipano al loro contesto di formattazione in linea come una singola casella opaca.

La Sezione 10 non menziona esplicitamente le caselle atomiche a livello di linea, ma ha sezioni per calcolare le dimensioni per gli elementi sostituiti in linea, così come gli elementi di blocco in linea, sostituiti o non sostituiti, che sono tutti considerati inline atomici come menzionato sopra. In tutti questi casi, la proprietà width applica normalmente se non è auto .

Quindi, mentre è ancora discutibile se un pulsante sia o meno un elemento sostituito, probabilmente non ha alcuna importanza ai fini di questa domanda. Ma è ancora una sorta di elemento in linea atomico, poiché partecipa ancora a un contesto di formattazione in linea. Per quello che vale, però, sembra ridursi per adattarsi ai suoi contenuti se non si imposta una larghezza, quindi il suo comportamento è probabilmente più vicino a quello di un blocco in linea in quel caso. Si potrebbe quindi affermare che il valore reale del display diventa inline-block , sebbene questo non si rifletta mai negli strumenti di sviluppo perché il valore calcolato non cambia (di nuovo un effetto collaterale del comportamento di rendering specifico del browser).

Dato che, come Boltclock, non penso che ci sia una risposta semplice a questa, è una discarica dei miei pensieri sull’argomento come una risposta, ma spero che sia informativa.

Sebbene la proprietà di visualizzazione CSS sia superficialmente abbastanza semplice, in realtà contiene una moltitudine di aspetti. Il css-display del CSS 3 livello spec coglie una parte di questa complessità, ma non sembra comunque trattarlo adeguatamente.

Le specifiche HTML5 dicono per il rendering degli elementi :

Quando l’associazione del pulsante si applica a un elemento del pulsante, è previsto che l’elemento venga visualizzato come una casella di “blocco in linea” resa come un pulsante il cui contenuto è il contenuto dell’elemento.

Una casella di inline-block ha una serie di aspetti:

1. Un elemento a livello di riga

Ciò significa che partecipa a un contesto di formattazione incorporata all’interno di una casella di riga. Scorre in sequenza con altri elementi che si trovano sulla stessa linea. Il contenuto della casella di riga può essere allineato al centro con allineamento del text-align:center proprietà del text-align:center sul relativo contenitore e la casella di riga viene accorciata evitando elementi flottati.

2. Applica una proprietà di larghezza e il valore automatico viene ridimensionato

A differenza della visualizzazione non sostituita display:inline elementi in display:inline , si applica il valore della larghezza. Ma anche, se non viene specificato un valore di larghezza, viene applicato un algoritmo di restringimento per determinare la larghezza. È come elementi fluttuanti o display:table elementi di display:table , ma diversi dalla display:block elementi di display:block che sono il più ampi ansible se non viene specificata alcuna larghezza. È anche diverso dagli elementi inline sostituiti e dagli elementi di blocco in linea sostituiti che, se non viene specificata alcuna larghezza, usano la loro larghezza intrinseca se ne hanno uno e un valore predefinito di 300 px se non lo sono. Shrink-to-fit è un concetto privo di significato per gli elementi sostituiti.

3. Un elemento block-container

Gli elementi del contenitore Block sono costituiti da una pila di riquadri di riga. Il contenuto scorre da una casella di riga a quella successiva e l’altezza degli elementi di blocco in linea aumenta (sobject a overflow) per contenere completamente tutte le caselle di riga.

4. La linea di base è la linea di base dell’ultima casella di riga contenuta

Quando l’elemento blocco in linea contiene più righe, la sua linea di base è l’ultima di quelle righe. Questo è diverso da float o display:table-cell elementi di display:table-cell che sono anche rimpiccioliti, elementi di contenitore a blocchi. I float sono al di fuori del stream normale, quindi non hanno una linea di base, che display:table-cell elementi di una display:table-cell hanno una linea di base che è la linea di base della loro casella di prima riga. Un pulsante che ha più linee si allinea verticalmente in base all’ultima regola della casella di riga.


Ora, questo va bene per l’impostazione di visualizzazione predefinita. e il requisito di rendering HTML5 significa che il valore utilizzato per la visualizzazione dei pulsanti è inline-block anche quando il valore specificato è in inline . Ma non tiene conto del comportamento quando il valore specificato è un block . In questo caso, l’elemento presenta un’interruzione di riga prima e dopo, e margin:auto centra la casella come display:block elemento display:block non è, e non è ciò che ci si aspetterebbe dal inline-block .

Tuttavia, la sua larghezza per un valore specificato di auto si riduce a misura come inline-block, mentre il comportamento previsto per la display:block è il più ampio ansible. Per quanto ne so, l’unico valore visualizzato che si comporta in questo modo è display:table , ma non c’è nient’altro da suggerire che display:table sia in uso.

Quindi non c’è nulla nelle specifiche che riesco a trovare che corrisponde esattamente a questo. Possiamo solo sperare che una volta completata la specifica del css-display, questo copra questo comportamento.

Ci sono 2 tipi di elementi.

  1. Elementi non sostituiti
  2. Sostituito elementi

Button appartiene alla categoria di elementi sostituiti.

Puoi trovare di più sul link qui sotto.

  • Littlewebhut
  • SitePoint

Quindi, per button , secondo le specifiche , diventa giusto.

Elementi in linea non sostituiti

La proprietà width non si applica. Un valore calcolato di auto per margin-left o margin-right diventa un valore utilizzato di 0 .

Elementi in linea, sostituiti (questa sezione si applica al button )

Un valore calcolato di auto per margin-left o margin-right diventa un valore utilizzato di 0 .

Se height e width hanno entrambi valori calcolati di auto e anche l’elemento ha una width intrinseca, allora quella width intrinseca è il valore usato della width .

Se height e width hanno entrambi valori calcolati di auto e l’elemento non ha width intrinseca, ma ha height intrinseca e un rapporto intrinseco; oppure se la width ha un valore calcolato di auto , l’ height ha qualche altro valore calcolato e l’elemento ha un rapporto intrinseco; allora il valore usato della width è:

  (used height) * (intrinsic ratio) 

Se height e width hanno entrambi i valori calcolati di auto e l’elemento ha un rapporto intrinseco ma nessuna height o width intrinseca, il valore utilizzato della width non è definito in CSS 2.1 . Tuttavia, si suggerisce che, se la width del blocco contenitore non dipende di per sé dalla width dell’elemento sostituito, il valore utilizzato della width viene calcolato dall’equazione del vincolo utilizzata per gli elementi a livello di blocco non sostituiti nel stream normale.

Se la width ha un valore calcolato di auto e l’elemento ha una width intrinseca, allora quella width intrinseca è il valore utilizzato di width .

Se la width ha un valore calcolato di width , ma nessuna delle condizioni di cui sopra è soddisfatta, il valore usato della width diventa 300px . Ma se 300px è troppo largo per adattarsi al dispositivo, gli UA dovrebbero usare la width del rettangolo più grande che ha un rapporto 2: 1 e si adatta invece al dispositivo.

Prova a impostare il margine su -2px .

 button, div { width: 200px; border: 1px solid red; display: inline; margin:-2px -2px -2px -2px; } 

La ragione per cui c’è ancora spazio tra gli elementi è perché persino display:inline; non rimuove tutto lo spazio. Rimuove lo stile predefinito del blocco che il browser normalmente applica. Tuttavia, il margine di -2px rimuove tutto lo spazio tra il pulsante e div.

VIOLINO