Un puñadico de links

Tools

https://iconsvg.xyz
Otra coleccion de iconos en svg, lo interesante es que se puede personalizar el trazo y otros factores, y te pone el codigo svg resultante facilitando mucho ponerlo inline.

https://codepen.io/sosuke/pen/Pjoqqp

Este es muy bueno y util, una calculadora de colores con filtros css, le indicas un color y te devuelve los css filter necesarios para conseguirlo a partir de una imagen (o elemento) negro

https://9elements.github.io/fancy-border-radius/
Un editor de border radius de 8 puntos, esta caracteristica no es muy conocida y tiene su juego

Learn

https://cssbattle.dev/

Un sitio donde se propone una imagen y hay que replicarla con la menor cantidad posible de css y html. Cuando digo “menor” es que hasta el ultimo bit cuenta.

https://parametric.press/issue-01/unraveling-the-jpeg/
Muy curioso, explica como funciona la compresion jpg y permite alterar las tripas de un archivo .jpg para ver el resultado en la imagen de forma instantanea

https://medium.com/s/story/technical-debt-is-like-tetris-168f64d8b700
Una explicacion muy interesante de la deuda tecnica a partir del juego tetris. Y como en el tetris, la partida contra la deuda técnica no acaba nunca

UX/UI

https://refactoringui.com/previews/building-your-color-palette/
Es muy facil elegir una paleta de colores chula e igual de facil cagarla aplicandola. Consejos practicos sobre como hacerlo:

Autosave en JS para formularios

Ya sabeis, estais rellenando un formulario en una de esas webs de la administración con una pegatina que indica que es compatible con Netscape y se ve mejor con Windows XP, le dais a enviar, o se cuelga, o se pasa cualquier cosa y se pierden todos los datos introducidos. Eso no nos puede pasar a nosotros

Vamos a hacer un script para guardar todos los datos introducidos ante cualquier eventualidad. Para marcar que campos queremos almacenar, añadiremos el atributo “data-memo” a cada elemento del formulario

Empezamos linkando un evento “onbeforeunload” que se ejecutará cuando la pagina vaya a descargarse, por navegar a otro sitio o cerrar el navegador.

window.addEventListener('beforeunload', function() {
     save()
 });

Definimos la funcion save, creamos un objeto donde guardar la informacion, y hacemos un query por una parte a los campos que no sean checkbox ni radio (o sea, los select, text, etc. de los que guardaremos su id y valor en el objeto memo.fields) y por otro lado, los input radio y checkbox (de los que guardaremos los id de los que estén marcados en un simple array memo.clicks ). Despues, almacenamos todos los datos en un local storage

function save() {
    var memo = {fields: {},clicks: []};
    document.querySelectorAll("[data-memo]:not([type='checkbox']):not([type='radio'])").forEach(function(item) {
        memo.fields[item.id] = item.value;
    });

    document.querySelectorAll("[data-memo][type='checkbox']:checked,[data-memo][type='radio']:checked").forEach(function(item) {
        memo.clicks.push(item.id)
    });
    localStorage.setItem("memo", JSON.stringify(memo));
}

Si todo va bien, en la pestaña “aplicación” del inspector de Chrome veremos el objeto “stringficado”.

Ahora haremos la función load() para cargar los datos, linkandola a un evento “DOMContentLoaded” del document para que se ejecute lo antes posible.

document.addEventListener("DOMContentLoaded", function() {
     load()
 });

En esta función leeremos y parsearemos el objeto memo y volcamos sus contenidos en los ids correspondientes leídos en el objeto memo.fields, y cambiamos el checked de los elementos citados en el array memo.clicks.

Vamos a aprovechar para utilizar esta misma función (que setea los elementos) para la opción de borrarlos. De esta forma, si le pasamos un parámetro reseteara el elemento, si no hay parámetro, pondrá el valor almacenado en memo. Así, si nos interesa, podemos poner un botón “limpiar” con una llamada la función “load(1)”. En realidad, podemos poner cualquier parametro, lo importante es que exista.
Discriminamos si existe “f” o no con una expresion ternaria.

function load(f) {
    var memo = JSON.parse(localStorage.getItem("memo"));
    for (x in memo.fields) {
        document.getElementById(x).value = (f ? "" : memo.fields[x])
    }
    for (x in memo.clicks) {
        document.getElementById(memo.clicks[x]).checked = f ? false : true;
    }
}

function clean() {
    load(1)
}

Podemos evitar el uso del atributo data-memo (para hacer por ejemplo un snippet que nos valga para cualquier formulario ajeno, o una extension de chrome), sustituyendo el “queryselectorall” por algo así:

 ("form input:not([type='checkbox']):not([type='radio']), 
form select:not([type='checkbox']):not([type='radio']) ")

Si algun campo depende de otro, como un select de “localidad” despues del select de “provincia”, podemos usar un settimeout o un evento change asociado al primer select después del primer seteo. Es posible que tengamos que hacer .change() al primer select para activar el evento que rellene el segundo.

Lo encapsulamos todo dentro de un objeto memo_form al estilo del patron de diseño “module” y está vestida para salir de casa.
Podeis juguetear con el tema cambiando valores y refrescando en el siguiente codepen que he preparado:

See the Pen
autosave JS
by jorgeblancodeveloper (@jorgeblancodeveloper)
on CodePen.

Usando nomenclatura para aplicar estilos

Todos sabemos como usar los atributos para aplicar distintos estilos, marcar los links que van a determinado sitio, los que van a  abrir una nueva ventana/pestaña, añadir un icono a los links que apunten a un .pdf… (([href*=”wikipedia.com”], [target*=”_blank”], [href $=”.zip”]…)) Se puede leer el origen, el alt, el title, el target, los data-, etc.

Tambien podemos usarlos para marcar de manera arbitraria ciertos contenidos sin necesidad de usar clases ni JS. Por ejemplo un widget de wordpress que permita añadir enlaces, pero no marcarlos arbitrariamente,  tal vez no tienes acceso al codigo (o ni siquiera sabes php)

Puedes marcar esos links añadiendo un target “dummy” al final de la url, puede bastar un simple # vacío, normalmente será ignorado  en la web de destino (a menos que la url necesite un id target) pero nos permite aplicarles estilo con  a[href $=”#”]. En este ejemplo tambien uso content(attr(href) ) para poner como subrayado el propio href del enlace.

Pongamos que quieres o necesitas, por el motivo que sea, usar las mismas imagenes tanto en  horizontal (desktop) como en vertical (phone), y lo apañas con objet-fit:cover y object-position:center , o bien usando sus equivalentes de background-image y background-position si necesitas dar soporte a Explorer y browsers antiguos, para el caso es lo mismo.

Y te encuentras con el problema de que ciertas imágenes tienen el punto de interés desplazado a un lado y lo pierdes en móvil, o en la parte superior y se pierde en desktop. Resulta que le estas cortando la cabeza a esa modelo tan guapa de la tercera imagen de tu slide.

Podrías arreglarlo aplicándoles una clase especial a esas imágenes lo que te obligaría en la mayoría de los casos a añadir un campo nuevo en tu gestor de contenidos para aplicarla, si es que tienes la posibilidad de hacerlo, que a lo mejor ni siquiera tienes acceso por ser una libreria externa.
Tampoco puedes hacer algo como .slide li:nth-child(3) porque te dejaria de funcionar al borrar o insertar una nueva imagen, o si se aplica un random al orden de slides.
Bueno, pues no hace no hace falta usar clases especificas, puedes señalar esas imágenes utilizando su propio nombre para identificarlas utilizando el lector de atributos de CSS.
Con suerte, tu gestor de contenidos permitira añadirle un “alt text” donde podemos colocar nuestras “falsas clases” y leerlas con [alt~=”any”],.
Pero en cualquier caso, podemos añadirlas al nombre de la imagen y leerlas con
 [src*= “”]  , con este selector podemos identificar cadenas de texto inscritas en el nombre (en la ruta, en la realidad) de la imagen. En concreto, el operador * lo que hace es buscar la cadena citada en cualquier lugar del atributo, también podemos añadir más precisión usando otros operadores como ^, $, |… que buscan la cadena al inicio, al final, como cadena completa, etc. tenéis la lista completa y mas información en el link anterior. Para la mayoría de los casos con * es suficiente.

Por ejemplo  en una imagen horizontal con el punto de interés a un lado  podemos añadir los sufijos  @left  o @right (u otros) en el nombre de la imagen y al mostrarla en vertical  identificarla en el css y posicionarla en consecuencia:

img {
  object-position:center center;
}
img[src*="@right"] {
  object-position: right center;
}
img[src*="@left"] {
object-position:left center ;
}

Una solución limpia y sencilla como deben ser siempre en CSS y que no complican nuestra base de datos. La imagen de la chica que mencionabamos antes ahora acaba en @top y se muestra correctamente en desktop.

Podemos combinar propiedades con variables CSS de esta manera

.screen img{
 width:100%;
 height:100%;
 object-fit:cover;
 --originx: center;
 --originy: center;
 object-position:var(--originx) var(--originy);
}
.screen img[src *= "@r"]{
 --originx: right;
}
.screen img[src *= "@l"]{
 --originx: left;
}
.screen img[src *= "@t"]{
 --originy: top;
}
.screen img[src *= "@b"]{
 --originy: bottom;
}

Así podríamos hacer algo como imagen@l@t.jpg para localizar puntos de interés en las esquinas.
Ejemplito en codepen:

Podemos marcar imagenes “en origen” para aplicar variaciones de composicion en logos con una relacion de apecto demasiado extrema en un directorio de empresas, por ejemplo, o en definitiva cualquier ocasion donde no podamos añadir clases arbitrariamente  pero podamos editar el contenido.

No es la solucion mas bonita del mundo pero es un recurso para casos extremos.