Saltar al contenido

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript... y lo que venga ;)

17 años online

el blog de José M. Aguilar

Inicio El autor Contactar

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web
ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript...

¡Microsoft MVP!
Mostrando entradas con la etiqueta estándares. Mostrar todas las entradas
Mostrando entradas con la etiqueta estándares. Mostrar todas las entradas
martes, 10 de julio de 2018
ASP.NET Core MVCLos que lleváis tiempo programando APIs HTTP, ya sea con ASP.NET Core o con otras tecnologías, seguro que en muchas ocasiones habéis tenido que decidir cómo retornar al cliente, de forma más o menos normalizada, los errores producidos en el lado servidor.

Lo habitual es echar mano de los status code de HTTP para indicar problemas en el proceso de una petición; de hecho, este protocolo dispone de un rico conjunto de códigos que en principio parecen cubrir todas nuestras necesidades.

Pero no siempre es así. Por ejemplo, si tenemos un servicio que permite a los clientes de una empresa formalizar un pedido a través de un API y una llamada a este servicio retorna un error HTTP 403 (forbidden), claramente estamos indicando que el solicitante no tiene permisos para hacer un pedido. Sin embargo, no tenemos una forma clara de indicar cuál es la causa de esta prohibición (¿quizás las credenciales no son correctas? ¿o quizás el cliente no tiene crédito en la empresa? ¿o puede ser que el administrador lo haya denegado expresamente?)

Para aportar más detalles sobre el problema, normalmente necesitaremos retornar en el cuerpo de la respuesta información extra usando estructuras o formatos personalizados, probablemente distintos de una aplicación a otra, y documentarlos apropiadamente para que los clientes puedan entenderlos. Y aquí es donde entra en juego el estándar “Problem details”.
martes, 2 de septiembre de 2008
BanderasUtilizando apropiadamente (X)HTML y hojas de estilo CSS, se pueden conseguir un montón de efectos interesantes para nuestras webs, como la inclusión de imágenes de fondo en cuadros de texto de formularios que vimos hace algún tiempo. Hoy vamos a ver lo fácil que resulta destacar enlaces (links) a páginas en idiomas distintos al nuestro de forma muy gráfica, colocando a su lado una banderilla que indique la lengua de destino, sin apenas introducir código adicional.

Para lograrlo, necesitamos solucionar dos problemas. El primero es cómo indicar en los enlaces (dentro de la etiqueta <a> de nuestro código X/HTML) el idioma de la página a la que saltará el usuario; el segundo problema es el describir en la hoja de estilos (CSS) estos enlaces, de forma que se representen con la banderita correspondiente. Ambos tienen fácil solución gracias a los estándares de la W3C.

Hace ya bastantes años, el estándar HTML definió el atributo hreflang en los hipervínculos con objeto de indicar el idioma del recurso apuntado por el atributo href. En otras palabras, si estamos apuntando a una página debería contener el idioma de la misma, justo lo que necesitamos:
 <a href="http://www.csszengarden.com" hreflang="en">CSS Zen Garden</a>
 
Por otra parte, el estándar CSS 2.1 define un gran número de selectores que podemos utilizar para identificar los elementos de nuestra página a los que queremos aplicar las reglas de estilo especificadas. El que nos interesa para lograr nuestro objetivo es el llamado selector de atributos, que aplicado a una etiqueta permite filtrar los elementos que presenten un valor concreto asociado a un atributo de la misma.

Así, en el siguiente código, que debemos incluir en la hoja de estilos del sitio web, buscamos los enlaces cuya página de destino sea en inglés (su hreflag comience por "en"), introduciendo el efecto deseado:
a[hreflang="en"]
{
padding-right: 19px;
background-image: url(img/bandera_ing.jpg);
background-position: right center;
background-repeat: no-repeat;
}
 
Observad que el padding-right deja un espacio a la derecha del enlace con la anchura suficiente como para que se pueda ver la imagen de fondo, la banderilla, que aparecerá allí gracias a su alineación horizontal a la derecha definida con el background-position.

Y, ahora sí, podemos recomendar visitas a páginas en inglés como CSS Zen Garden con fundamento.

Ah, un último detalle. Aunque hoy en día los navegadores tienden cada vez más a respetar los estándares, es posible que encontréis alguno con el que no funcione bien esta técnica principalmente por no soportar el selector de atributos (por ejemplo IE6 y anteriores, afortunadamente cada vez menos usados).

Publicado en: www.variablenotfound.com.
domingo, 17 de febrero de 2008
Encuentro en Apuntes de un Loco que hace un par de días Microsoft publicó las especificaciones de varios de sus formatos de archivo binario de Microsoft Office, así como otros de soporte, en el contexto del compromiso de apertura de especificaciones que mantiene desde algo más de un año.

Podemos encontrar (en inglés, por supuesto) la descripción detallada de los siguientes formatos de archivo:


Una iniciativa interesante derivada de esto ha sido la creación en SourceForge del proyecto "Office Binary Translador to Open XML", que pretende crear herramientas de conversión automática a este estándar ECMA. Supongo que en breve esta información se usará también para realizar conversiones fiables hacia y desde otros formatos, como los utilizados en otras suites ofimáticas como Open Office (Open Document).

Se trata sin duda de una buena noticia para facilitar la interoperabilidad entre aplicaciones.

Publicado en: http://www.variablenotfound.com/.
domingo, 9 de diciembre de 2007
Browsershots.org es un servicio dedicado a realizar capturas de pantalla de una página web utilizando distintos navegadores y sistemas operativos, y gratis... siempre que no tengas mucha prisa.

El invento utiliza un sistema en el que las solicitudes de captura de pantalla se distribuyen entre "factorías", máquinas de los propios usuarios de la comunidad, que prestan parte del ancho banda y capacidad de sus equipos para realizar estas tareas. De hecho, hay unas sencillas instrucciones para crear una nueva factoría de capturas de pantalla y apoyar así el proyecto.

Para enviar la solicitud de captura es necesario indicar la URL a comprobar, así como los navegadores y características de la captura, combinando entre los siguientes elementos:
  • Navegadores:
    • para Linux: Epiphany 2.14, Firefox 1.5, Firefox 2.0, Galeon 2.0, Iceweasel 2.0, Konqueror 3.5, NetFront 3.2, Opera 9.24, Opera 9.5
    • para Windows: Firefox 1.5, Firefox 2.0, MSIE 5.5, MSIE 6.0, MSIE 7.0, Opera 9.24, Safari 3.0.
    • para Mac OS: Firefox 2.0, Safari 1.3, Safari 2.0, Safari 3.0
  • Anchos de pantalla: 640, 800, 1024, 1280, 1400 y 1600 pixels.
  • Profundidad de color: 8, 16, 24 y 32 bits por pixel.
  • Javascript: deshabilitado, habilitado, v1.3, v1.5, v1.6, v1.7, v2.0
  • Java: deshabilitado o habilitado.
  • Flash: deshabilitado o habilitado.



Una vez enviado el formulario con las características deseadas, el trabajo pasará a la cola de cada una de las factorías desde se generarán las capturas de pantalla. El tiempo de espera dependerá del número de solicitudes pendientes, pero podremos conocer una estimación global y detallada desde la misma página:



Conforme las factorías van terminando su trabajo, enviarán una copia de la captura al servidor central, que publicará en la misma página web las imágenes obtenidas. Simplemente recargando la página obtendremos información actualizada del proceso y podremos ampliar las imágenes obtenidas hasta el momento pulsando sobre ellas:



Es importante destacar que la solicitud que enviamos tiene una validez de 30 minutos. Si en ese tiempo no hemos obtenido los resultados deseados, debemos extender (hay un botón para ello en la página) este tiempo, pues de lo contrario expirará. De esta forma, los señores de ScreenShots.org pueden asegurar que estamos todavía en la página y que seguimos interesados en las capturas de pantalla que hemos solicitado previamente.

Las capturas generadas son de un tamaño y calidad excelente, suficientes para detectar problemas en el diseño o las habituales incompatibilidades entre los motores de renderizado de páginas web de los navegadores.

El único problema es el tiempo que puede llegar a tardar la realización de un conjunto completo de capturas. En distintas pruebas me he encontrado con colas de más de una hora, aunque, también he de decirlo, la mayoría de las capturas se han generado en los primeros diez minutos. Además, por una módica cantidad mensual (10€/15$) puedes adquirir un mes de prioridad en el servicio, por lo que, según aseguran, obtendrás todas las pantallas en menos de 3 minutos.

Publicado en: Variable Not Found.
martes, 18 de septiembre de 2007
A raíz de los posts sobre los tipos anulables en .NET (introducción a los nullables y uso tipos anulables con enumeraciones), mi amigo Javi me hizo una pregunta que sólo un friki como él sería capaz de formular ;-): ¿cómo afecta el uso de tipos anulables a la serialización de clases?

Aunque sospechaba la respuesta, he hecho un par de pruebas a través de las cuales, ahora sí, puedo asegurar que no afectan en nada, es decir, el sistema controla perfectamente la forma en que se serializan y deserializan este tipo de valores.

El comportamiento es el siguiente: cuando el tipo anulable contiene un valor no nulo, la serialización la delega en el tipo subyacente. Si es un int?, se realizará la serialización por defecto para el int. Usando un serializador XML, un ejemplo de salida sería:


<?xml version="1.0" encoding="utf-16"?>
<int>10</int>

 

En cambio, cuando se trata de serializar el valor null, el sistema genera una etiqueta que indica este hecho, de la misma forma que lo haría si estuviéramos haciéndolo para un tipo referencia. Un ejemplo de salida XML sería:


<?xml version="1.0" encoding="utf-16"?>
<int xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xsi:nil="true" />

 

En fin, que hoy hemos aprendido una cosa más. Y que no falte. :-)
martes, 4 de septiembre de 2007
Esto de que cada navegador utilice su propio dialecto derivado del CSS para indicar atributos, como la transparencia u opacidad de los elementos de una página, tiene su gracia... o mejor pensado, no tiene ninguna gracia.

Menos mal que en CSS-Tricks nos enseñan cómo definirla para que funcionen con prácticamente todos los browsers del universo conocido:
.transparente
{
filter:alpha(opacity=50);
-moz-opacity:0.5;
-khtml-opacity: 0.5;
opacity: 0.5;
}


De esta forma, para hacer que un bloque div (por ejemplo) se convierta en semitransparente (al 50% según el ejemplo anterior), sólo habría que poner:

<div class='transparente'>
... lo que sea
</div>


Obviamente, el nivel de opacidad puede modificarse al valor deseado, siendo el 100% el máximo (totalmente opaco) y 0% el mínimo (totalmente transparente). Ojo, que en la primera línea (filter:alpha...) se usa el rango 0-100 y en las restantes este valor dividido entre cien, es decir, en un rango del 0 al 1.

Eso sí, supongo que los validadores CSS igual se quejan un poco. ;-)
domingo, 8 de julio de 2007
Uno, que es inocente por naturaleza, asume que utilizar AJAX, acrónimo cuyas siglas corresponden con Asynchronous Javascript And XML, implica el uso de Javascript, comunicación asíncrona con el servidor y XML como formato de intercambio de información.

Lo primero es absolutamente cierto. Javascript es la base actual de AJAX; sin duda es el lenguaje de moda para la programación de funcionalidades avanzadas en cliente, está relativamente bien soportado por los navegadores modernos (o al menos son bien conocidas las particularidades de cada browser) y ofrece una potencia más que suficiente para lo que habitualmente pretendemos utilizarlo.

Lo segundo, la comunicación asíncrona con el servidor, es sólo relativamente cierto. Además de ser posible y útil la comuncación síncrona, hoy en día el término AJAX se utiliza con demasiada frecuencia; basta hacer una web tenga algún script para asegurar que estamos usando esa tecnología punta. Y no, señores, que los menús dinámicos ya se hacían con DHTML hace muuchos muuuchos años.

Sin embargo, hay librerías y frameworks AJAX que, entre otras características, incluyen funciones con efectos visuales realmente espectaculares, y esto cala muy rápidamente en los usuarios y desarrolladores al ser realmente sencillos de integrar y utilizar. De hecho, es fácil encontrar aplicaciones que utilizan de forma masiva estos componentes y no utilizan intercambio de datos alguno con el servidor.

Y por último, la gran decepción: no tiene por qué usarse XML. Lo que parecía tan obvio (de hecho, en un nuevo alarde de ignorancia y osadía lo aseguré en el post Llamar a servicios web con ASP.NET AJAX paso a paso), no es así la mayoría de las veces, y me explico.

XML, a pesar de su estandarización, interoperabilidad y claridad de lectura es lento a la hora de ser procesado. Si habéis probado a manejar un documento complejo usando XMLDOM o similares, habréis comprobado lo engorroso y lento que resulta recorrer o crear la estructura y acceder a sus elementos. Y claro, si se utiliza este lenguaje para comunicar cliente con servidor se supone que esta complejidad se produce en ambos extremos del intercambio de datos, lo cual no resulta agradable ni a la hora de desarrollarlo ni una vez puesto en explotación, puesto que se pretende que este intercambio sea rápido.

En su lugar se suelen utilizar formatos más ligeros, fácilmente procesables y manejables tanto desde cliente como desde servidor, y aquí la estrella es JSON (JavaScript Object Notation), un formato ligero para el intercambio de información basado, como XML, en texto plano, muy estructurado, de fácil lectura, con una gran difusión y, sobre todo, muy fácil de procesar tanto desde Javascript como desde software en servidor. Una prueba de su popularidad es que el propio Yahoo! adoptó JSON como formato de intercambio de datos con sus servicios, aunque sigue permitiendo XML.

Sin embargo, como siempre que existen distintas opciones para hacer lo mismo, hay un fuerte debate sobre la conveniencia de usar XML o JSON, con continuas luchas entre uno y otro bando en las que se aportan las ventajas de utilizar una opción y las debilidades de la opuesta. Vamos, lo de siempre (Windows/Linux, Internet Explorer/Firefox, PlayStation/Xbox, Burger King/Mc Donnald's...).

Como curiosidad, decir que se ha llegado a acuñar el término AJAJ para identificar a la tecnología que combina el Javascript Asíncrono con JSON (de ahí la "J" final), pero es obvio que el término no es tan atractivo como AJAX y ha sido descartado. Además, el uso de otros formatos de intercambios podría dar lugar a extrañas variaciones de las siglas que inundarían el ya colmado espacio mental reservado para estas aberraciones. Por ejemplo, si en vez de XML usamos HTML, la tecnología debería llamarse AJAH; si la complementamos con CSS podría ser AJACH; si usamos también comunicación síncrona necesitaríamos SAJACH. Y así hasta el infinito y más allá.

Por ello, y esto sí que es importante, parece que existe finalmente un gran consenso respecto a la utilización del término Ajax (mayúsculas la inicial, minúscula el resto), de forma que deje de ser un acrónimo y se convierta en un nombre propio que identifique a la filosofía, no al conjunto de tecnologías que se usan por debajo. Esto, además, supone un giro radical en su definición: mientras que AJAX es un término centrado en la tecnología, Ajax está centrado en el usuario, en lo que ve, en lo que obtiene, en su forma de relacionarse con el sistema, relegando los aspectos tecnológicos a un segundo plano.

Por cierto, otro día dedicaré un post en exclusiva a JSON, que creo que es lo suficientemente interesante como para dedicarle un ratito.

jueves, 14 de junio de 2007
Hay veces que encuentras por internet herramientas que no tienen una utilidad demasiado grande pero resultan curiosas. Este es uno de esos casos.

Se trata de SelectOracle (algo así como Selectoráculo), una herramienta on-line que traduce cadenas de selectores, indicados según el estándar CSS 3.0, al español, inglés y, de forma aún incompleta, al alemán y búlgaro.

¿Y qué signica esto? Para que os hagáis una idea, reproduzco una serie de selectores que le he enviado y la respuesta que me ha devuelto la herramienta:

Selector: *
Traducción: Selecciona cualquier elemento.

Selector: p a
Traducción: Selecciona cualquier elemento a que es descendiente de un elemento p.

Selector: div#main > p + a[title]
Traducción: Selecciona cualquier elemento a con un atributo title que sigue inmediatamente a un elemento p que es hijo de un elemento div con un atributo id que equivale a main.

Como se puede ver, es en casos con cierta complejidad como este último donde la herramienta puede sernos de ayuda.

Una prueba más de que en internet hay de todo, sólo hace falta buscar un poco.
domingo, 10 de junio de 2007
Este post es el tercero (y último) de la serie sobre selectores CSS definidos en la versión 2.1 del estándar publicado por la W3C.

Las dos entradas anteriores puedes encontrarlas aquí: Etiquetas CSS 2.1 (I) y Etiquetas CSS 2.1 (II).

En la primera de ellas fueron incluidos selectores básicos, de uso muy frecuente y compatibles con todos los navegadores actuales; en la segunda se complicó un poco el tema, introduciendo otros menos conocidos y de aceptación desigual por parte de los browsers más difundidos.

A continuación seguimos describiendo el resto de selectores, muy interesantes todos ellos, pero hay que tener cuidado a la hora de utilizar, sobre todo si lo que se pretende es llegar al mayor número posible de usuarios, puesto que no son contemplados por todos los navegadores, especialmente los que salen de las fábricas de Microsoft.

Selector de hijos (>)

Permiten indicar los atributos de aquellos elementos que sean hijos de su padre. Digamos que es como un selector descendente (descrito en la primera entrega de la serie) pero exclusivamente aplicado al primer nivel de descendencia. Funciona en casi todos los navegadores excepto, como de costumbre, en Internet Explorer 6.

body > p
{
/* Los párrafos de primer */
color: red; /* nivel por debajo de body */
/* se pintan en rojo */
}


Subselectores de primogénitos

Permite seleccionar un elemento, siempre que éste sea el primogénito de su padre. ¿Utilidad? Mucha. Por ejemplo, permite decirle a los <li> de una lista que el primero se pinte de forma diferente a los demás sin necesidad de marcarlo con un class="primero" o similar, como se hace normalmente.

li
{
/* Los elementos de lista, */
color: red; /* siempre en rojo */
}
li:first-child
{
/* pero el primero, irá */
color: blue; /* en azul. */
}

Este subselector funciona en Firefox 1.5 o superior, IE7, Safari, Opera y Konqueror. Como casi siempre, se queda por detrás Internet Explorer 6.

Es interesante comentar que CSS nivel 3 permitirá, además, la utilización del subselector de "benjamines", :last-child, que selecciona los elementos siempre que sean el último hijo de su padre. De momento el soporte en los
navegadores es incluso menor que el anterior.

Selector de precedencia (+)

Resulta útil para seleccionar un elemento que se encuentre en el código (X)HTML codificado justo después de otro. Ojo, que cuando digo después de un elemento me refiero a seguir a un elemento completo (con su correspondiente etiqueta de apertura y cierre), no a ser descendiente suyo (que ocurriría al encontrarse tras su etiqueta de apertura); es bastante fácil confundirse en esto.

p + a
{
/* Los enlaces que sigan */
color: red; /* a un párrafo, en rojo */
}
/* No afectará a: */
/* <p>Saltar a <a href="#">enlace</a></p> */
/* Sí afectará a: */
/* <p>Saltar a </p><a href="#">enlace</a> */


Subselector de atributos ([ ])

A veces los atributos de los elementos son indicativos del formato que éstos deben tomar. Para estos casos, el subselector de atributos permite:

  • Seleccionar elementos que tengan declarado un atributo, independientemente de su valor. Esto se consigue utilizando el selector [atributo].

    img[alt]
    {
    /* Las imágenes con atributo */
    /* alt='texto', borde rojo */
    border: 4px solid red;
    }

  • Seleccionar elementos que presenten un atributo con un valor determinado. La forma de hacerlo es utilizando la expresión [atributo="valor"]:

    p[dir='rtl']
    { /* Los párrafos que se lean */
    color: red; /* de derecha a izquierda */
    } /* irán en rojo */

  • Seleccionar elementos que presenten un atributo con un valor consistente en una lista de palabras separadas por espacios y una de ellas coincide con el valor a buscar. La forma de hacerlo es utilizando la expresión [atributo~="valor"]:

    p[lang~='en']
    { /* Los párrafos en inglés */
    color: red; /* se pintan en rojo */
    } /* aunque el inglés no */
    /* sea el único idioma */
    /* Ej: lang="fr en" */


  • Seleccionar elementos que presenten un atributo con un valor consistente en una lista de palabras separadas por guiones y comiencen con el valor a buscar. La forma de hacerlo es utilizando la expresión [atributo="valor"]:

    p[lang='en']
    { /* Los párrafos en inglés */
    color: red; /* se pintan en rojo */
    } /* independientemente */
    /* de su localización */
    /* Ej: lang="en-US" */



Sé que casi no hace falta decirlo, pero de nuevo es IE6 el único que no interpreta estos interesantes subselectores.

¡Y esto es todo, amigos! Recapitulando, esta serie de tres posts recoge todos los selectores definidos por la W3C (salvo error u omisión por mi parte, claro) en su especificación CSS 2.1.

Sin embargo, como hemos podido ver, la terrible lamentable implementación del estándar en los navegadores, sobre todo Internet Explorer 6, hace que sea realmente complejo crear una web que pinte bien en todos ellos. Y por desgracia, hay que recordar que IE6 sigue siendo el navegador más utilizado del mundo; esperemos que esto cambie pronto gracias a su hermano mayor IE7, que sin ser prodigioso sí está bastante mejor situado respecto a la aceptación de CSS 2.1, y al magnífico Firefox, un auténtico fiera a la hora de respetar los estándares.
jueves, 7 de junio de 2007
En el post anterior recogía selectores CSS
básicos
, aquellos que pueden usarse con cualquier navegador sin llevarse sorpresas. En esta entrega vamos a continuar con ellos e introduciremos algunos más avanzados que no funcionan con todos los browsers pero que resulta altamente interesante conocer.


Subselectores de estado

Utilizados principalmente en los enlaces (etiquetas
<a>), permiten indicar distinta presentación dependiendo del estado en el que se encuentren los mismos. Se indican siempre acompañando al selector principal al que se aplican, seguido por dos puntos y el subselector a aplicar. Tenemos los siguientes:


  • Enlaces no visitados (a:link)

  • Enlaces visitados previamente (a:visited)

  • Enlaces activos, al pulsar sobre ellos (a:active)

  • Enlaces bajo el puntero del ratón (a:hover)

  • Enlaces con el foco activo (a:focus)



a:hover
{
/* Al pasear el ratón ... */
color: red; /* por encima, se pone rojo */
}
a:active
{
color: blue; /* Al pulsarlo, pasa a azul */
}

La verdad es que algunos de ellos no tienen sentido fuera de enlaces, pero otros sí.
De hecho, es perfectamente posible utilizar un selector p:hover e indicar los atributos a aplicar a todo el párrafo cuando se pasee el ratón por encima. Lo mismo ocurre para el foco, que podría aplicarse a elementos de tipo <input>. Sin embargo, la terrible implementación de CSS en Internet Explorer 6 no los contempla, por lo que no están demasiado difundidos estos usos. Menos mal que IE7, aunque esté lejos de ser un virtuoso, ha mejorado esta compatibilidad.


Subselector de idioma

Permite seleccionar aquellos elementos cuyo contenido está en un idioma determinado, y, eso sí, hayan sido marcados convenientemente para identificarlo con el atributo lang. Sin embargo, su dispar aceptación por los navegadores e incluso las distintas formas de expresar el idioma en una etiqueta (lang o xml:lang) hace que no sea fácil ponerlo en práctica. El siguiente ejemplo funciona en Firefox, pero no en IE6-7:

p:lang(en)
{
/* Los párrafos en inglés, */
color: red; /* siempre en rojo */
}


Subselector de primer carácter

Selecciona el primer carácter del contenido de los elementos apuntados por el selector principal. No funciona bien en IE6, pero sí en el resto de navegadores medio decentes (Firefox, Safari, Opera, Konqueror e incluso IE7).

p:first-letter
{
/* La primera letra, como */
color: red; /* siempre, en rojo */
}


Subselector de primera línea

Todo lo dicho con el anterior resulta igualmente válido, a diferencia de que los estilos indicados se aplican a la primera línea del contenido.

p:first-line
{
/* La primera línea del */
color: blue; /* párrafo, color azul, */
/* por cambiar un poco. */
}


Subselectores de contenido previo y posterior

Estos interesantísimos selectores permiten modificar el contenido de la página justo antes del elemento apuntado por el selector principal o justo después de éste. ¿Qué quiere decir esto? Pues que podemos modificar el contenido de la página desde la hoja de estilos CSS, aunque pueda poner un poco los pelos de punta. La pena es que los hermanos IE no lo reconocen :-/.

p.ojo:before
{
/* Todos los párrafos */
/* de clase "ojo" */
content: "OJO: "; /* irán precedidos por */
/* el texto "OJO:" */
}
p.ojo:after
{
/* Todos los párrafos */
/* de clase "ojo" */
content: "FIN"; /* irán seguidos de */
/* el texto "FIN" */
}


Creo que con esto tenemos suficiente por hoy.
En el próximo post seguiremos profundizando en el escalofriante mundo de los selectores avanzados... la diversión está asegurada.
domingo, 3 de junio de 2007
Hace tiempo que tenía ganas de escribir algo sobre los selectores CSS 2.1, esos grandes desconocidos, al menos para mí. Cierto es que desde hace años uso estilos para decorar páginas, pero por una razón u otra no había dedicado el tiempo suficiente para conocer todos los selectores que define el estándar, por lo que me limitaba a utilizar los más básicos. Y como supongo que no soy el único, dedicaré algunos posts a enumerarlos y comentarlos, a ver si podemos aprovechar mejor toda la potencia que esta técnica ofrece, y evitar dolores de cabeza a la hora de maquetar y decorar una página.

Como sabemos, CSS permite indicar cómo se verá el contenido de páginas web que componemos utilizando (X)HTML. Un ejemplo de declaración de estilo es la siguiente, que indica que todo lo que se encuentre entre <p> y </p> se dibuje negro y con fuente gruesa (negrilla):
p { color: black; font-weight: bold; }

Existen dos partes importantes en esta regla: qué atributos hay que aplicar (negrilla y color negro en este caso) y a qué debemos aplicárselo (al contenido de las etiquetas <p>) de la página a la que se aplique este estilo. Los selectores son precisamente el segundo grupo, la parte de la declaración que indica qué elementos del contenido se verán afectados por los atributos especificados. De ahí su nombre "selectores".

A continuación se recogen los selectores recogidos en el estándar CSS 2.1 de la W3C. Sin embargo, dado que son bastantes y voy a incluir algunos ejemplos, incluiré en este post únicamente los más habituales y utilizados. En un post posterior (valga la redundancia) añadiré el resto.

Selector universal (*)

Los atributos especificados se aplicarán a todos los elementos del documento. Sin compasión. Un ejemplo:
*
{
color: red; /* Todo en rojo */
}

Selector de elemento

Permite indicar el elemento, o etiqueta, a la que se aplicará el estilo especificado. Es el más habitual, ¿a quién no le suena lo siguiente? (ojo, cuando el mismo estilo se aplica a varios elementos se pueden separar sus selectores con comas, como en el ejemplo):
h1, h2           /* Afectará a las etiquetas h1 y h2... */
{
color: red; /* El rojo es bello */
}

Selector de clase

Permite indicar la clase CSS a la que se aplicarán los estilos indicados. La clase deberá incluirse en el código (X)HTML de forma explícita utilizando el atributo class='[clase]' de las etiquetas implicadas.

p.textoNormal /* Afectará a las etiquetas */
{ /* <p class='textoNormal' > */
color: red; /* Rojo forever */
}


.muyGrande /* Afectará a cualquier etiqueta */
{ /* con class='muyGrande' */
font-size: 10em;
}

Selector directo

Es más específico que el anterior, puesto que únicamente afecta a la etiqueta con el ID indicado, es decir, aquella en cuya declaración se haya incluido el atributo "id" (minúsculas) y se le haya asignado un valor único en la página.
p#main   /* Afectará a la etiqueta <p id='main'> */
{
color: red; /* Rojo again */
}


#main /* Es igual que la anterior, */
{ /* pues sólo hay una etiqueta */
color: red; /* con id='main' en una página */
/* correcta (X)HTML. */
}

Selector descendente

Permite aumentar la especificidad de un selector, indicando tanto la etiqueta afectada como una de sus ascesoras, o en otras palabras, un elemento donde se encuentra. La profundidad con que se puede definir es ilimitada, aunque por motivos de legibilidad no creo que sea muy conveniente alargarla en exceso. Unos ejemplos:

p a /* Afecta a todos los enlaces <a> */
{ /* incluidos en párrafos <p> */
color: red;
}


ul.menu li
{ /* Los <li> pertenecientes a */
background-color: red; /* los <ul> de clase "menu" */
} /* tendrán el fondo rojo. */


ul.menu li ul li a /* Ejemplo difícil de leer:*/
{ /* Los enlaces de un <li> */
/* pertenecientes a */
background-color: blue; /* una lista incluida en un */
/* <ul> de clase "menu" */
} /* tendrán fondo azul (uuf!). */


Es importante destacar que este selector no restringe el grado de profundidad del antecesor. Es decir, "p a { color: red; }" indica que todos los <a> que tengan un antecesor <p> se verán afectados, aunque no sean hijos directos de éste. Por ejemplo, si dentro del <p> hay un <span> y dentro de éste está el enlace <a>, también se verá afectado por la regla. En resumen, pueden ser descendientes de cualquier grado.

Bueno, vale ya por hoy. El próximo día, más.
miércoles, 30 de mayo de 2007
Hace un par de semanas Microsoft publicó la versión definitiva del complemento Internet Explorer Developer Toolbar, un plugin para IE indispensable para todos los que jugamos con XHTML y CSS y nos volvemos locos cada día intentando que los elementos aparezcan donde deben.

Las principales características de esta herramienta son:
  • Permite identificar zonas de la página paseando por encima con el ratón, permitiéndonos visualizar en todo momento de qué elemento se trata, sus atributos y las reglas de estilo CSS aplicadas a cada uno. Los elementos también pueden seleccionarse desde la estructura (DOM) de la página.

  • Activación o desactivación directa de características como estilos o scripts.

  • Asimismo, se pueden ver de forma rápida los atajos de teclado o el orden de tabulación, importante para cumplir las normas de accesibilidad.

  • Es posible indicarle que "bordee" elementos concretos, como divs, tablas, elementos posicionados u otros.

  • Permite mostrar u ocultar imágenes o propiedades de éstas como el archivo de origen (src), el tamaño o el peso.

  • Permite validar HTML, CSS, WAI y feeds RSS de forma directa.

  • Dispone de reglas para medir zonas de la página a nuestro antojo.

  • Formatea y colorea el código fuente de las páginas para facilitar su lectura.

  • Nos permite eliminar la caché del navegador, así como visualizar o eliminar las cookies asociadas a la página consultada, o incluso deshabilitar su uso.

La siguiente captura de pantalla muestra la herramienta en funcionamiento sobre Internet Explorer 6:

Internet Explorer Developer Toolbar en funcionamiento
Funciona con IE6 e IE7. En el primero se activa pulsando el icono con una flechilla que aparece en la barra de herramientas; en el segundo también, pero ojo, este icono no está visible por defecto. De momento está disponible sólo en inglés, y se puede descargar en esta dirección.

Ah, aunque supongo que ya lo conoceréis a estas alturas, el equivalente para Mozilla Firefox es la extensión Firebug, toda una maravilla, también indispensable para cualquier desarrollador web.
viernes, 25 de mayo de 2007
El pasado 22 de mayo, la IETF aprobó y publicó la propuesta del estándar DKIM en la RFC 4871. ¡Diantres, ahora que se había puesto de acuerdo mucha gente para usar SPF!

DKIM pretende controlar los mensajes haciendo que el servidor de correo del que proceden firme digitalmente los envíos. De esta forma se consigue, en primer lugar, poder verificar el dominio al que pertenece el remitente de un mensaje y, en segundo lugar, asegurar la integridad del mismo permitiendo detectar si el contenido de éste ha sido alterado durante su tiempo de tránsito por el ciberespacio.

Según proponen, para echar a andar DKIM en un servidor de mensajes SMTP, deberían generarse un par de claves, pública y privada. La primera de ellas sería publicada a través del servicio estándar DNS, mientras que la segunda sería utilizada internamente para firmar digitalmente los mensajes.

Cuando un usuario autorizado envía un correo, el servidor generaría la firma del contenido en tiempo real y la añadiría a los encabezados del mensaje. El servidor del destinatario extraería la firma del mensaje y, mediante una consulta al DNS del origen, obtendría su clave pública, con lo que podría verificar la validez de la firma.

De esta forma, en función del resultado de la comprobación, el destinatario podría aplicar políticas locales de filtrado. Por ejemplo, si el dominio origen del mensaje existe y la firma es válida, es probable que se trate de un mensaje que debe ser entregado al destinatario, pero se le podrían pasar filtros basados en contenido para una mayor seguridad. Si la firma no es correcta o no aparece, podrían tomarse medidas de descarte o marcado del mensaje.
El siguiente diagrama muestra esquemáticamente el funcionamiento de DKIM:



¿Y quién anda detrás de este invento? Pues ni más ni menos que Yahoo! (iniciadores del proyecto), Cisco, PGP y Sendmail, y según comenta su inventor, Mark Delany, también han contado con la colaboración de IBM, Earthlink, Microsoft, Spamhaus, Google, PayPal y Alt-N, entre otros.

En resumen, se trata de un nuevo intento para acabar con el envío de mensajes desde destinatarios incorrectos o servidores "no creíbles", basándose esta vez en la utilización de criptografía de clave pública. Si bien no es de por sí una tecnología que resuelva el problema al 100%, sí que podría colaborar mucho. Además, lo más probable es que la solución final sea una combinación de distintas técnicas, así que bienvenida sea.

Particularmente me convence la idea de aplicar técnicas criptográficas para asegurar el correo, así como la utilización de estándares y soluciones colaborativas consensuada entre proveedores. Sin embargo, este último aspecto es su punto más débil: necesita una adopción global para que su efectividad pueda ser razonable.

En cualquier caso, todo esto forma parte de la lógica y necesaria evolución de tecnologías que tiene que acontecer hasta que la humanidad consiga dar con la forma para la eliminación definitiva del spam, phishing, spoofing y otras lindezas virtuales.