Posso usare classi CSS inesistenti?


260

Ho una tabella in cui mostro / nascondo una colonna completa di jQuery tramite una classe CSS che non esiste:

<table>
   <thead>
      <tr>
         <th></th>
         <th class="target"></th>
         <th></th>
      </tr>
   </thead>
   <tbody>
      <tr>
         <td></td>
         <td class="target"></td>
         <td></td>
      </tr>
      <tr>
         <td></td>
         <td class="target"></td>
         <td></td>
      </tr>
   </tbody>
</table>

Con questo DOM posso farlo in una riga tramite jQuery: $('.target').css('display','none');

Funziona perfettamente, ma è valido usare classi CSS che non sono definite? Devo creare una classe vuota per questo?

<style>.target{}</style>

Ci sono effetti collaterali o esiste un modo migliore per farlo?


9
Non vedo nulla di sbagliato al riguardo, anche se l'avrei reso parte del foglio di stile se possibile piuttosto che utilizzare .css, gli stili impostati con .css sono molto difficili da ignorare senza causare altri problemi, quindi tendo ad evitarli.
Kevin B,

8
come nota a margine che potresti voler usare .toggle(), è un po 'più breve nel tuo codice.
Chiller matematico,

4
In Visual Studio + ReSharper, se usi una classe non definita, ti darà un avvertimento, che è utile se ho solo un refuso, ma è fastidioso in situazioni come questa. In questo caso, hai la possibilità di aggiungere lo stile vuoto o disabilitare l'avviso (o semplicemente ignorarlo) - personalmente, aggiungo solo lo stile vuoto. Non so se altri IDE si comportino in modo simile.
Joe Enos,

8
Non è solo possibile, ma è esplicitamente raccomandato da alcuni. Dato che il tuo targetè per scopi di JavaScript, molte persone usano il prefisso js-per tali classi, ad es js-target. A proposito: l'obiettivo è una specie di brutto nome;) Per ulteriori informazioni, consultare: philipwalton.com/articles/decoupling-html-css-and-javascript
k0pernikus,

1
stackoverflow.com/questions/2832117/… è più o meno un duplicato di questo, senza il malinteso.
naught101

Risposte:


491

"Classe CSS" è un termine improprio; classè un attributo (o una proprietà, in termini di scripting) assegnato a elementi HTML. In altre parole, dichiari le classi in HTML, non CSS, quindi nel tuo caso la classe "target" esiste effettivamente su quegli elementi specifici e il tuo markup è perfettamente valido così com'è.

Questo non significa necessariamente che devi avere una classe dichiarata nell'HTML prima di poterla usare anche nei CSS. Vedi il commento di ruakh. La validità o meno di un selettore dipende interamente dalla sintassi del selettore e CSS ha il proprio set di regole per la gestione degli errori di analisi , nessuno dei quali riguarda affatto il markup. In sostanza, ciò significa che HTML e CSS sono completamente indipendenti l'uno dall'altro nell'aspetto della validità. 1

Una volta capito, diventa chiaro che non vi sono effetti collaterali nel non definire una .targetregola nel foglio di stile. 2 Quando assegni delle classi ai tuoi elementi, puoi fare riferimento a tali elementi per quelle classi in un foglio di stile, in uno script o in entrambi. Nessuno dei due ha una dipendenza dall'altro. Invece, entrambi fanno riferimento al markup (o, più precisamente, alla sua rappresentazione DOM). Questo principio si applica anche se stai usando JavaScript per applicare gli stili, come nel tuo one-liner jQuery.

Quando scrivi una regola CSS con un selettore di classe, tutto ciò che stai dicendo è "Voglio applicare gli stili agli elementi che appartengono a questa classe". Allo stesso modo, quando scrivi uno script per recuperare elementi con un certo nome di classe, stai dicendo "Voglio fare cose con elementi che appartengono a questa classe". O se non ci sono elementi che appartengono alla classe in questione è una questione separata del tutto.


1 Questo è anche il motivo per cui un selettore ID CSS abbina tutti gli elementi con l'ID specificato indipendentemente dal fatto che l'ID appaia esattamente una volta o più volte (risultando in un documento HTML non conforme).

2 L'unica situazione di cui sono a conoscenza è necessaria una regola CSS vuota come quella in cui alcuni browser si rifiutano di applicare determinate altre regole correttamente a causa di un bug; la creazione di una regola vuota comporterà l'applicazione di altre regole per qualche motivo. Vedi questa risposta per un esempio di tale bug. Tuttavia, questo è sul lato CSS e quindi non dovrebbe avere nulla a che fare con il markup.


5
Mi ci sono voluti anni per capire che le lezioni non hanno nulla a che fare con i CSS. Nello stesso periodo, tutti gli altri si resero conto e arrivarono i microformati.
Konrad Rudolph,

13
+1, sebbene questa risposta possa essere interpretata come implicita, a torto, che i CSS possono fare riferimento solo alle classi effettivamente presenti nell'HTML. In realtà è abbastanza comune per un sito utilizzare CSS a livello di sito su tutte le pagine, anche se alcune delle classi a cui fa riferimento non vengono visualizzate in ogni singola pagina. (Ad esempio, il sito potrebbe avere uno stile personalizzato per collegamenti esterni, a.extlinko quant'altro, anche se alcune pagine non contengono collegamenti esterni.)
ruakh

1
@ruakh: punto eccellente, grazie. Non sono riuscito a trovare un modo per adattarlo alla mia breve, originale risposta senza virare fuori tema, ma vedo come l'uso del termine dipendenza possa aver dato quell'impressione, quindi l'ho cambiato un po '. Detto questo, ho aggiunto una nota a piè di pagina che fa riferimento al tuo commento e che elabora ulteriormente.
BoltClock

66

Non ci sono effetti negativi per usare le classi che non hanno stili. In effetti, ciò che fa parte dell'utilità dei CSS è che è disaccoppiato dal markup e può modellare o meno elementi / classi / ecc. come necessario.

Non pensarli come "classi CSS". Pensa a loro come a "classi" che CSS usa anche se è necessario.


11
+1 per "Non pensarli come" classi CSS ". Pensare a loro come 'classi' che accade CSS di utilizzare anche se ha bisogno di"
laike9m

48

Secondo le specifiche HTML5 :

Un attributo di classe deve avere un valore che è un insieme di token separati da spazio che rappresentano le varie classi a cui appartiene l'elemento. ... Non ci sono restrizioni aggiuntive sui token che gli autori possono usare nell'attributo class, ma gli autori sono incoraggiati a usare valori che descrivono la natura del contenuto, piuttosto che valori che descrivono la presentazione desiderata del contenuto.

Inoltre, nel versione 4 :

L'attributo class ha diversi ruoli in HTML:

  • Come un selettore di fogli di stile (quando un autore desidera assegnare informazioni di stile a un insieme di elementi).
  • Per elaborazioni generiche da parte di agenti utenti.

Il tuo caso d'uso rientra nel secondo scenario, che lo rende un esempio legittimo dell'uso di un attributo di classe.


13
+1 per la citazione delle specifiche pertinenti. Mi sono dimenticato di farlo molto.
BoltClock

40

Puoi usare una classe che non ha stili, questo è HTML completamente valido.

Una classe a cui fa riferimento un file CSS non è una definizione di una classe, ma viene utilizzata come regola di selezione per scopi di stile.


25

Quando usi un nome di classe in JavaScript, non cerca il CSS per trovare quella classe. Sembra direttamente nel codice HTML.

Tutto ciò che serve è che il nome della classe sia nell'HTML. Non ha bisogno di essere nel CSS.

In effetti, molte persone pensano che in realtà sia una buona idea mantenere l'uso di classi separate con CSS e Javascript , in quanto consente ai vostri progettisti e programmatori di lavorare in modo indipendente senza intralciarsi a vicenda utilizzando le lezioni reciproche.

(nota, il paragrafo precedente è ovviamente più applicabile per progetti più grandi, quindi non pensare che devi andare a questo estremo se lavori da solo; l'ho menzionato per sottolineare che i due possono essere completamente separati )


13

Puoi usare le classi CSS senza usarlo, ma suggerisco che se stai aggiungendo classi CSS solo per il codice JavaScript / jQuery, aggiungi il prefisso in js-YourClassNamemodo che gli sviluppatori front-end non usino mai queste classi per modellare gli elementi. Dovrebbero capire che queste classi possono essere rimosse in qualsiasi momento.


10

Nel momento in cui aggiungi la Classe nel tuo HTML, la Classe verrà definita, quindi la tua soluzione andrà benissimo


7
L'uso della classe in HTML non lo definisce. Direi piuttosto che la definizione è irrilevante: non ci sono penalità per l'uso di classi indefinite.
JAL

10

Non è necessario definire le classi CSS nel tuo foglio di stile. Dovrebbe funzionare bene. Tuttavia, aggiungerlo non danneggerà.


Non sto dicendo di aggiungere quegli stili, sta a lui se lo vuole, se ha intenzione di supportare quegli stili, allora perché no? comunque grazie per l'inutile voto
negativo

Hai detto "non danneggerà", ma alla fine lo farà.
Pavlo,

sì, non farà male. se ha i sensi per aggiungere quegli stili vuoti, allora ovviamente avrà i sensi per gestirli. Ovviamente non aggiungerò..non sto consigliando di aggiungere.
Rameez,

8

Una cosa che nessuno qui ha completamente menzionato è che JavaScript (aiutato da jQuery in questo caso) non è in grado di modificare direttamente il foglio di stile a cascata di un documento. Il css()metodo di jQuery cambia semplicemente il set di elementi abbinato 'style proprietà . CSS e JavaScript sono completamente indipendenti da questo aspetto.

$('.target').css('display','none');non cambia affatto la tua .target { }dichiarazione CSS. Quello che è successo qui invece è che qualsiasi elemento con un class"target" ora assomiglia a questo:

<element class="target" style="display:none;"></element>

Ci sono effetti collaterali causati dalla non pre-definizione di una regola di stile CSS? Assolutamente no.

C'è un modo migliore per farlo? Per quanto riguarda le prestazioni, sì, c'è!

Come si possono migliorare le prestazioni?

Anziché modificare direttamente l' styleelemento di ciascun elemento, è possibile pre-definire una nuova classe e aggiungerla agli elementi corrispondenti utilizzandoaddClass() (un altro metodo jQuery).

Sulla base di questo JSPerf preesistente che si confronta css()con addClass(), possiamo vedere che in addClass()realtà è molto più veloce:

css () vs addClass ()

Come possiamo implementarlo da soli?

Innanzitutto possiamo aggiungere nella nostra nuova dichiarazione CSS:

.hidden {
    display: none;
}

Il tuo HTML rimarrebbe lo stesso, questa classe predefinita è semplicemente pronta per un uso successivo.

Ora possiamo modificare JavaScript per utilizzare addClass()invece:

$('.target').addClass('hidden');

Quando si esegue questo codice, anziché modificare direttamente la styleproprietà di ciascuno degli elementi "target" corrispondenti, questa nuova classe sarà ora aggiunta:

<element class="target hidden"></element>

Con la nuova classe "nascosta", questo elemento erediterà lo stile dichiarato nel tuo CSS e il tuo elemento non verrà più visualizzato.


Buon Consiglio. Raramente c'è un buon motivo per usare .css()invece di alternare le classi IMO.
BoltClock

6

Come è già stato detto da molti altri, sì, l'utilizzo di classi senza CSS assegnato è perfettamente valido e piuttosto che considerarle come "classi CSS" è necessario semplicemente riconoscere la semantica di classe e ID come gruppi e singoli elementi rispettivamente.

Volevo fare il chip in quanto ho sentito che un esempio importante non è stato sollevato come esempio. Se hai mai bisogno di fare manipolazioni visive su una lunghezza variabile di elementi (in questo caso stai usando le righe della tabella), ha sempre senso riconoscere che il costo per farlo attraverso Javascript potrebbe essere potenzialmente molto costoso (ad esempio se hai migliaia di righe).

In questa situazione diciamo che sappiamo che la colonna 2 ha sempre il potenziale per essere nascosta (è una funzione consapevole della tua tabella), quindi ha senso progettare uno stile CSS per gestire questo caso d'uso.

table.target-hidden .target { display: none; }

Quindi, invece di usare JS per attraversare il DOM alla ricerca di N elementi, dobbiamo semplicemente attivare una classe su uno (la nostra tabella).

$("table").addClass("target-hidden")

Assegnando alla tabella un ID questo sarebbe ancora più veloce e potresti persino fare riferimento alla colonna usando il :nth-childselettore che ridurrebbe ulteriormente il markup ma non posso commentare l'efficienza. Un altro motivo per farlo è che odio lo stile in linea e farò di tutto per sradicarlo!


1
+1 per "gruppi e singoli elementi" e per un uso efficiente della struttura del documento
deltab

5

Non avrà alcun effetto se si applica una classe su un elemento HTML e tale classe non è definita nei CSS. È una pratica comune e come ha detto Aamir afridi se si usano le classi per il solo scopo di js, è una buona pratica anteporre loro js-.

Non è valido solo per i calsses, ma anche per l'attributo id degli elementi html.


4

Non c'è alcun problema nell'usare le classi solo per cercare elementi. Ho usato per dare a tali nomi di classe il sys-prefisso (ad esempio, chiamerò la tua classe sys-target) per distinguerli dalle classi utilizzate per lo styling. Questa era una convenzione utilizzata da alcuni sviluppatori Microsoft in passato. Ho anche notato una pratica crescente di utilizzo dijs- prefisso per questo scopo.

Se non hai dimestichezza con l'uso delle classi per scopi diversi dallo stile, ti consiglio di utilizzare il plug-in jQuery Role.js che ti consente di raggiungere lo stesso scopo utilizzando l' roleattributo, quindi puoi scrivere il tuo markup <td role="target">e interrogarlo usando $("@target"). La pagina del progetto ha una buona descrizione ed esempi. Uso questo plugin per grandi progetti perché mi piace molto tenere le lezioni solo a scopo di styling.


3

Fare riferimento al motore di convalida di jQuery . Anche lì usiamo anche classi inesistenti per aggiungere regole di validazione sugli attributi HTML . Quindi non c'è niente di sbagliato nell'usare classi che non sono effettivamente dichiarate in un foglio di stile.

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.