¿Puedo usar clases CSS no existentes?

260

Tengo una tabla donde muestro / oculto una columna completa de jQuery a través de una clase CSS que no existe:

<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 este DOM puedo hacer esto en una línea a través de jQuery: $('.target').css('display','none');

Esto funciona perfectamente, pero ¿es válido usar clases CSS que no están definidas? ¿Debo crear una clase vacía para ello?

<style>.target{}</style>

¿Hay algún efecto secundario o hay una mejor manera de hacerlo?

totymedli
fuente
9
No veo nada malo en ello, aunque lo habría hecho parte de la hoja de estilo si fuera posible en lugar de usar .css, los estilos configurados con .css son muy difíciles de anular sin causar otros problemas, por lo que tiendo a evitarlos.
Kevin B
8
como nota al margen que tal vez quieras usar .toggle(), es un poco más corto en tu código.
Enfriador de matemáticas
44
En Visual Studio + ReSharper, si usa una clase que no está definida, le dará una advertencia, que es útil si solo tengo un error tipográfico, pero es molesto en situaciones como esta. En este caso, tiene la opción de agregar el estilo vacío o deshabilitar la advertencia (o simplemente ignorarlo); personalmente, solo agrego el estilo vacío. No sé si otros IDE se comportan de manera similar.
Joe Enos
8
No solo es posible, sino que algunos lo recomiendan explícitamente. Dado que targetes para fines de javascript, muchas personas usan el prefijo js-para tales clases, es decir js-target. Por cierto: Target es una especie de mal nombre;) Para leer más, ver: philipwalton.com/articles/decoupling-html-css-and-javascript
k0pernikus
1
stackoverflow.com/questions/2832117/… es más o menos un duplicado de esto, sin la idea errónea.
naught101

Respuestas:

491

"Clase de CSS" es un nombre inapropiado; classes un atributo (o una propiedad, en términos de secuencias de comandos) que asigna a elementos HTML. En otras palabras, se declara clases en HTML, CSS no, por lo que en su caso la clase "objetivo" hace de hecho existen en aquellos elementos específicos, y su margen de beneficio es perfectamente válido como es.

Esto no significa necesariamente que deba tener una clase declarada en el HTML antes de poder usarla en CSS. Ver el comentario de ruakh. Si un selector es válido o no depende completamente de la sintaxis del selector , y CSS tiene su propio conjunto de reglas para manejar los errores de análisis , ninguno de los cuales se refiere al marcado. Básicamente, esto significa que HTML y CSS son completamente independientes entre sí en el aspecto de validez. 1

Una vez que comprenda eso, queda claro que no hay ningún efecto secundario de no definir una .targetregla en su hoja de estilo. 2 Cuando asigna clases a sus elementos, puede hacer referencia a esos elementos por esas clases, ya sea en una hoja de estilo, en un script o en ambos. Ninguno de los dos tiene dependencia del otro. En cambio, ambos se refieren al marcado (o, más precisamente, su representación DOM). Este principio se aplica incluso si está usando JavaScript para aplicar estilos, como lo hace en su jQuery one-liner.

Cuando escribe una regla CSS con un selector de clase, todo lo que dice es "Quiero aplicar estilos a los elementos que pertenecen a esta clase". De manera similar, cuando escribe una secuencia de comandos para recuperar elementos con un nombre de clase determinado, dice "Quiero hacer cosas con elementos que pertenecen a esta clase". Si hay o no son elementos que pertenecen a la clase en cuestión es un tema aparte por completo.


1 Esta es también la razón por la cual un selector de ID de CSS hace coincidir todos los elementos con la ID dada independientemente de si la ID aparece exactamente una vez o varias veces (lo que resulta en un documento HTML no conforme).

2 La única situación que conozco donde es necesaria una regla CSS vacía como esa es cuando algunos navegadores se niegan a aplicar ciertas otras reglas correctamente como resultado de un error; crear una regla vacía hará que esas otras reglas se apliquen por algún motivo. Vea esta respuesta para un ejemplo de tal error. Sin embargo, esto está en el lado de CSS y, por lo tanto, no debería tener nada que ver con el marcado.

BoltClock
fuente
55
Me llevó años darme cuenta de que las clases no tienen nada que ver con CSS. Pero casi al mismo tiempo, todos los demás se dieron cuenta y aparecieron los microformatos.
Konrad Rudolph el
13
+1, aunque esta respuesta podría tomarse como que implica, erróneamente, que CSS solo puede referirse a clases que realmente ocurren en el HTML. En realidad, es bastante común que un sitio use CSS en todo el sitio en todas las páginas, aunque algunas de las clases a las que se refiere no aparecen en cada página. (Por ejemplo, el sitio podría tener un estilo personalizado para enlaces externos, a.extlinko cualquier otra cosa, incluso si algunas páginas no contienen enlaces externos.)
ruakh
1
@ruakh: Excelente punto, gracias. No pude encontrar una manera de encajar en mi breve respuesta original sin desviarme del tema, pero veo cómo el uso del término dependencia podría haber dado esa impresión, así que lo cambié un poco. Dicho esto, he agregado una nota al pie de página que hace referencia a su comentario, así como más detalles.
BoltClock
66

No hay efectos negativos para usar clases que no tienen estilos. De hecho, eso es parte de la utilidad de CSS es que está desacoplado del marcado y puede dar estilo o no a elementos / clases / etc. según sea necesario.

No pienses en ellos como "clases de CSS". Piense en ellos como "clases" que CSS también usa si es necesario.

David
fuente
11
+1 para "No los consideres como 'clases de CSS'. Piense en ellos como 'clases' que CSS también usa si es necesario "
laike9m
48

Según la especificación HTML5 :

Un atributo de clase debe tener un valor que es un conjunto de tokens separados por espacios que representan las diversas clases a las que pertenece el elemento. ... No hay restricciones adicionales sobre los tokens que los autores pueden usar en el atributo de clase, pero se alienta a los autores a usar valores que describan la naturaleza del contenido, en lugar de valores que describan la presentación deseada del contenido.

Además, en la versión 4 :

El atributo de clase tiene varios roles en HTML:

  • Como un selector de hoja de estilo (cuando un autor desea asignar información de estilo a un conjunto de elementos).
  • Para fines generales de procesamiento por parte de agentes de usuario.

Su caso de uso se incluye en el segundo escenario, lo que lo convierte en un ejemplo legítimo del uso de un atributo de clase.

Vitalii Fedorenko
fuente
13
+1 para citar las especificaciones relevantes. Me he olvidado de hacer eso mucho.
BoltClock
40

Puede usar una clase que no tiene estilos, esto es HTML completamente válido.

Una clase a la que se hace referencia en un archivo CSS no es una definición de una clase, se usa como una regla de selección para propósitos de estilo.

Brusco
fuente
25

Cuando usa un nombre de clase en JavaScript, no mira el CSS para encontrar esa clase. Se ve directamente en el código HTML.

Todo lo que se requiere es que el nombre de la clase esté en el HTML. No necesita estar en el CSS.

De hecho, muchas personas piensan que en realidad es una buena idea mantener el uso de clases separadas con CSS y Javascript , ya que les permite a sus diseñadores y codificadores trabajar de forma independiente sin interponerse entre ellos al usar las clases de los demás.

(tenga en cuenta que el párrafo anterior es obviamente más aplicable para proyectos más grandes, así que no sienta que tiene que ir a este extremo si está trabajando solo; lo mencioné para señalar que los dos pueden estar completamente separados )

Spudley
fuente
13

Puede usar clases CSS sin usarlo, pero le sugiero que si agrega clases CSS solo para el código JavaScript / jQuery, coloque el prefijo js-YourClassNamepara que los desarrolladores front-end nunca usen estas clases para diseñar los elementos. Deben entender que estas clases se pueden eliminar en cualquier momento.

Aamir Afridi
fuente
10

En el momento en que agregue la Clase en su HTML, la Clase estará definida, por lo que su solución estará completamente bien.

koningdavid
fuente
77
Usar la clase en HTML no lo define. Más bien, diría que la definición es irrelevante: no hay penalización por usar clases indefinidas.
JAL
10

No es necesario definir clases CSS en su hoja de estilo. debería funcionar bien. Sin embargo, agregarlo no dañará.

Rameez
fuente
No estoy diciendo que agregue esos estilos, depende de él si quiere, si planea apoyar esos estilos, ¿por qué no? de todos modos, gracias por un voto negativo innecesario :)
Rameez
Dijiste "no ... no hará daño", pero eventualmente lo hará.
Pavlo
Sí, no hará daño. si tiene sentidos para agregar esos estilos vacíos, obviamente tendrá sentidos para administrarlos. Obviamente no agregaré ... tampoco estoy recomendando agregar.
Rameez
8

Una cosa que nadie aquí ha mencionado completamente es que JavaScript (ayudado por jQuery en este caso) no puede modificar directamente la hoja de estilo en cascada de un documento. El css()método de jQuery simplemente cambia la stylepropiedad del conjunto de elementos coincidentes . CSS y JavaScript no tienen relación alguna en este aspecto.

$('.target').css('display','none');no cambia su .target { }declaración CSS en absoluto. Lo que sucedió aquí en cambio es que cualquier elemento con un class"objetivo" ahora se parece a esto:

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

¿Hay algún efecto secundario causado por no predefinir una regla de estilo CSS? Ninguno en absoluto.

¿Hay una mejor manera de hacer esto? En cuanto al rendimiento, sí lo hay.

¿Cómo se puede mejorar el rendimiento?

En lugar de modificar directamente la stylede cada elemento, en su lugar, puede predefinir una nueva clase y agregarla a sus elementos coincidentes utilizandoaddClass() (otro método jQuery).

Basado en este JSPerf preexistente que se compara css()con addClass(), podemos ver que en addClass()realidad es mucho más rápido:

css () vs addClass ()

¿Cómo podemos implementar esto nosotros mismos?

En primer lugar, podemos agregar nuestra nueva declaración CSS:

.hidden {
    display: none;
}

Su HTML seguirá siendo el mismo, esta clase predefinida simplemente está en su lugar para su uso posterior.

Ahora podemos modificar el JavaScript para usar addClass()en su lugar:

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

Al ejecutar este código, en lugar de modificar directamente la stylepropiedad de cada uno de sus elementos "objetivo" coincidentes, ahora se habrá agregado esta nueva clase:

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

Con la nueva clase "oculta", este elemento heredará el estilo declarado en su CSS y su elemento se configurará para que ya no se muestre.

James Donnelly
fuente
Buen consejo. Rara vez hay una buena razón para usar en .css()lugar de alternar las clases IMO.
BoltClock
6

Como mencionan muchos otros, sí, el uso de clases sin CSS asignado es perfectamente válido y, en lugar de pensar en ellas como 'clases de CSS', simplemente debe reconocer la semántica de clase e ID como grupos y elementos individuales respectivamente.

Quería contribuir porque sentí que no se había planteado un punto importante dado el ejemplo. Si alguna vez necesita hacer manipulaciones visuales a una longitud variable de elementos (en este caso está utilizando filas de tabla), entonces siempre tiene sentido reconocer que el costo de hacerlo a través de Javascript podría ser muy costoso (por ejemplo, si tiene miles de filas).

En esta situación, digamos que sabemos que la columna 2 siempre tiene el potencial de ocultarse (es una función consciente de su tabla), entonces tiene sentido diseñar un estilo CSS para manejar este caso de uso.

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

Luego, en lugar de usar JS para atravesar el DOM para encontrar N elementos, simplemente necesitamos alternar una clase en una (nuestra tabla).

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

Al asignar un ID a la tabla, esto sería aún más rápido e incluso podría referirse a la columna utilizando el :nth-childselector que reduciría aún más su marcado, pero no puedo comentar sobre la eficiencia. ¡Otra razón para hacer esto es que odio el estilo en línea, y haré todo lo posible para erradicarlo!

Ian Clark
fuente
1
+1 para "grupos y elementos individuales" y para el uso eficiente de la estructura del documento
deltab
5

No tendrá ningún efecto si aplica una clase en un elemento HTML, y esa clase no está definida en CSS. Es una práctica común y, como dijo Aamir afridi, si está utilizando clases con el único propósito de js, es una buena práctica ponerles el prefijo js-.

No solo es válido para calsses, sino también para el atributo id de elementos html.

Altaf Hussain
fuente
4

No hay ningún problema en usar clases para solo buscar elementos. Solía ​​dar a tales nombres de clase el sys-prefijo (por ejemplo, nombraré su clase sys-target) para distinguirlos de las clases utilizadas para el estilo. Esta fue una convención utilizada por algunos desarrolladores de microsoft en el pasado. También noté una práctica creciente de usar el js-prefijo para este propósito.

Si no se siente cómodo con el uso de clases para fines distintos del estilo, le recomiendo usar el complemento jQuery de Role.js que le permite lograr el mismo propósito usando el roleatributo, por lo tanto, puede escribir su marcado como <td role="target">y consultarlo usando $("@target"). La página del proyecto tiene una buena descripción y ejemplos. Utilizo este complemento para grandes proyectos porque realmente me gusta mantener las clases solo con fines de estilo.

Ashraf Sabry
fuente
3

Consulte el motor de validación jQuery . Incluso allí también usamos clases inexistentes para agregar reglas de validación en los atributos HTML . Por lo tanto, no hay nada de malo en usar clases que en realidad no se declaran en una hoja de estilo.

dhruvin
fuente