Zach’s ugly mug (his face)

Zach Leatherman

The Font Loading Checklist

August 30, 2018 #5 Popular

When I look back at the last four years that I’ve spent learning everything I could about web fonts and how web fonts load, I can distill it all down to a small checklist of ideals that I continue to chase. Our goal as web developers is to maximize the experience and raise user expectations to the level of what the web is capable of delivering, but also to manage our performance budgets to ensure that we are fulfilling the promise of the web—it’s ubiquity. This checklist should help you deliver on those two often competing ideals.

The Font Loading Checklist

(Start a Web Font load)

Web fonts don’t start downloading until they’re found to be used in content, so it’s often late in the page load. We need to tell the browser to start downloading our high priority web fonts sooner.

(Behavior while a Web Font is loading)

This means absolutely no invisible text. This is known as the flash of invisible text, or FOIT. We can use flash of unstyled text (FOUT) strategies to prioritize system fonts during web font load.

(Reduce Web Font load time)

Guess what: Smaller file downloads finish sooner.

  • Strategy: Use WOFF2 formats (compression built in)
  • Strategy: Subset your fonts, if language and licensing requirements allow.

Check out Glyphhanger to help with both of these strategies.

(Behavior after a Web Font has loaded)

Each independent @font-face block has its own loading life-cycle. Its own FOIT, its own FOUT, its own repaint and reflow. When using two or more web fonts for a single family, its important to group the repaints together to reduce reflow of text on your page.

Zach’s ugly mug (his face)

Zach is a Web Craftsperson with the award winning Filament Group. He’s currently fixated on web fonts and static site generators. His public speaking résumé includes talks in eight different countries at events like Beyond Tellerrand, Smashing Conference, CSSConf, and The White House. He also helps herd NEJS CONF and the NebraskaJS meetup. Read more about Zach »

1 Mention
  1. www.inarvis.com #

    Show original post En esta guía de CSS os enseñaremos las propiedades más útiles que deberías empezar a usar ahora mismo. A continuación explicaremos cada propiedad con un ejemplo básico para que lo puedas comprender de forma visual. Empezamos! Tabla de contenidos Pseudoelementos::before && ::after ::selection ::placeholder PseudoclasesSelección de elementos hijo Control de estado Validación de campos de texto Variables de CSSComo cambiar entre tema oscuro y claro CSS GridCómo definir la plantilla grid Ejemplo de galería Flexbox AnimacionesKeyframesCómo funcionan los keyframes Transiciones Otras propiedades interesantesComo optimizar la precarga de fuentes Selectores de atributos Clip path PseudoelementosLos pseudoelementos son una palabra clave que se añade a los selectores para realizar cambios concretos en el documento. Estos pseudoelementos, a diferencia de las pseudoclases (:), se identifican con dos puntos dobles (::).::before && ::afterAmbas propiedades nos permiten añadir contenido dentro de un elemento antes (::before) o después (::after) de cualquier otro contenido HTML. Para que cualquiera de estos pseudoelementos haga efecto, es obligatorio añadir la propiedad content. Un ejemplo sencillo podría ser el siguiente.textotextop::before { content: 'Hola '; background-color: red; color: white; } p::after { content: ' Mundo'; font-weight: bold; }Otro ejemplo práctico sería editar el estilo en testimonios o citas de autores o documentos. Para editar el estilo y forma de las comillas en las citas, se puede utilizar la propiedad quotes. If you are spending a lot of your time learning while you code — while someone is paying you — then you are doing it right. Jen Simmons If you are spending a lot of your time learning while you code — while someone is paying you — then you are doing it right. Jen Simmons blockquote { text-align: center; } blockquote::before { margin: 0 auto 40px; } blockquote::after { margin: 40px auto 0; } blockquote::before, blockquote::after { content: " "; width: 60px; height: 3px; background-color: #c9c9c9; display: block; } blockquote cite { padding-top: 20px; display: block; color: #676767; }Por último, también podemos añadir animaciones a estos elementos decorativos, así, podemos crear por ejemplo un Tooltip. Este texto desvela un secretoEste texto desvela un secretoa[data-tooltip] { position: relative; } a[data-tooltip]::after { content: attr(data-tooltip); position: absolute; left: 0; bottom: 0; background-color: #212121; padding: 10px 20px; color: white; border-radius: 8px; white-space: nowrap; transform: scale(0); transition: all ease-in 200ms; } a[data-tooltip]:hover::after { transform: scale(1); bottom: 100%; }::selectionEsta propiedad modifica el estilo del texto cuando lo seleccionamos con el ratón. Se puede utilizar en selectores o en todo el documento. Las únicas propiedades que funcionan en ::selection son: color, background-color y text-shadowSelecciona para ver cambios en el texto Selecciona para ver cambios en el fondo y texto Selecciona para ver cambios en el sombreadoSelecciona para ver cambios en el textoSelecciona para ver cambios en el fondo y textoSelecciona para ver cambios en el sombreado .selection-text::-moz-selection { color: purple; } .selection-text::selection { color: purple; } .selection-bg::-moz-selection { background-color: red; color: white; } .selection-bg::selection { background-color: red; color: white; } .selection-shadow::-moz-selection { background-color: red; color: white; } .selection-shadow::selection { text-shadow: 1px 1px #212121; } /* Si lo declaramos globalmente */ ::selection { color: white; background: #212121; }::placeholderModifica las propiedades del placeholder dentro de un campo de texto. Si solo queremos aplicar estos estilos cuando el placeholder es visible, usaríamos ::placeholder-shown. ::-webkit-input-placeholder { /* Edge */ color: purple; font-weight: bold; letter-spacing: 2px; } :-ms-input-placeholder { /* Internet Explorer 10-11 */ color: purple; font-weight: bold; letter-spacing: 2px; } ::placeholder { color: purple; font-weight: bold; letter-spacing: 2px; }PseudoclasesAl igual que con los pseudoelementos, las pseudoclases se aplican a los selectores y especifican una condición especial del elemento, como por ejemplo, al producirse un evento del ratón (hover), cambios en el historial del navegador (:visited) o según el contenido (:checked).Hay una pseudoclase llamada :root que representa el elemento raíz del documento, idéntico al selector html. La única diferencia que existe es que :root tiene más especificidad. Se suele utilizar para declarar variables de CSS.Selección de elementos hijo :first-child representa el primer hijo del contenedor padre. :last-child representa el último hijo del contenedor padre. Primer hijo Segundo hijo Último hijo Primer hijo Segundo hijo Último hijo .example-fc p:first-child { border-left: 3px solid black; padding-left: 10px; } .example-fc p:last-child { font-weight: bold; text-transform: uppercase; } :nth-child(n) representa el n-ésismo hijo de un elemento padre. En general, se suele usar para marcar de distintos colores las filas de las tablas. Podemos agregar como valor (n) un número (1, 4), una ecuación (2n, 4n + 1) o alternar entre pares e impares (even, odd). :nth-of-type(n) representa el n-ésimo hijo que sea del mismo tipo de selector dentro de un contenedor padre. :empty representa cualquier elemento que no tenga hijos. Se considera como hijo cualquier nodo o texto (espacios incluidos). Puede ser útil si queremos ocultar elementos vacíos que ocupan espacio en blanco. :not(x) representa elementos que no coinciden con el selector (etiquetas, clases, ids…) añadido en la condición. Con un ejemplo parecido al anterior podremos identificar las diferencias entre estas propiedades. Primer hijo Segundo hijo / Primero hijo Párrafo Tercer hijo / Segundo hijo Párrafo Primer hijoSegundo hijo / Primero hijo Párrafo Tercer hijo / Segundo hijo Párrafo .example-nth :not(p):not(b) { font-size: 24px; color: purple; } .example-nth :nth-child(2) { border-left: 3px solid blue; padding-left: 10px; } .example-nth p:nth-of-type(2) { border-left: 3px solid red; padding-left: 10px; } .example-nth :empty::before { content: 'Selector P vacio'; font-weight: bold; }A continuación veremos el uso que se le pueden dar a muchas de las pseudoclases orientadas a elementos de formulario, como por ejemplo, campos de texto y tipos de checkbox.Control de estadoEn este caso usamos las pseudoclases :not y :checked para comprobar el estado del checkbox, y así, tenemos opción a modificar ambos aspectos.Haga click Haga click/* Podemos usar los siguientes alias si lo queremos aplicar globalmente a todos los checkbox. #checkbox-input como [type="checkbox"] .checkbox-label como label */ /* Primero ocultamos el input */ #checkbox-input { display: none; } /* Estilos del texto, entre el :before y el :after */ #checkbox-input:not(:checked) + .checkbox-label, #checkbox-input:checked + .checkbox-label { position: relative; padding-left: 2em; cursor: pointer; } /* Damos estilo de caja a la etiqueta label usando :before */ #checkbox-input:not(:checked) + .checkbox-label::before, #checkbox-input:checked + .checkbox-label::before { content: ''; position: absolute; left: 0; top: 0; width: 1.5em; height: 1.5em; border: 2px solid #ccc; background: #fff; border-radius: 4px; cursor: pointer; } #checkbox-input:not(:checked) + .checkbox-label:hover::before { border-color: #0b76ef; } /* Después cambiamos el fondo cuando el checkbox está activo. */ #checkbox-input:checked + .checkbox-label::before { background-color: #0b76ef; border-color: #0b76ef; } /* Finalmente cambios el estilo del tick */ #checkbox-input:checked + .checkbox-label::after { content: '\2713'; position: absolute; top: 0.1em; left: .08em; font-size: 1.6em; color: white; line-height: 0.8; }Validación de campos de textoAhora veremos varias propiedades que nos pueden ayudar a validar y mejorar la experiencia de usuario en nuestros formularios. Sabiendo como funcionan y se complementan estos elementos, el límite lo pone nuestra imaginación.Ojo, en este ejemplo se ha utilizado la propiedad outline: none. No se debería eliminar esta propiedad ya que es necesaria para una buena accesibilidad. Si se decide suprimir esta opción, es muy recomendable ofrecer estilos alternativos que mantengan o mejoren la experiencia de usuario. Campo deshabilitado Rango entre 1 y 10 Campo obligatorio Campo deshabilitado Rango entre 1 y 10 Campo obligatorio .form-inputs-example { display: flex; flex-direction: column; align-items: center; padding: 20px 0; } .input-group-example { display: flex; flex-direction: column; width: 400px; padding: 15px 20px; } input { padding: 7px; order: 1; /* Gracias a flexbox podemos cambiar el de la etiqueta y el input. */ } /* Aplicados a los campos deshabilitados */ input:disabled:hover { background-color: #ddd; } /* Aplicados a los campos opcionales */ input:optional { color: green; font-size: 1.1em; } /* Aplicados a los campos obligatorios */ input:required { border-color: red; } /* Podemos usarlo de esta forma porque hemos cambiado el orden de los inputs gracias a flexbox. (lineas 9 y 17) */ input:required + label::after { content: ' *'; color: red; font-weight: bold; } .input-1, .input-2 { border-radius: 5px; border: 2px solid #ccc; } .input-2 { outline: none; } .input-2:in-range { background-color: #CCFFCC; border: 2px solid green; } .input-2:out-of-range { background-color: #FFCCCC; border: 2px solid red; } .input-2:in-range + label::after { content: '. Es válido.'; } .input-2:out-of-range + label::after { content: '. Fuera de rango!'; } .input-3 { background: transparent; box-shadow: none; border-width: 0px 0px 4px 0px; } /* Cambiamos el color del borde cuando seleccionamos el input y ocultamos el outline */ .input-3:focus { outline: none; border-color: #0b76ef; }Variables de CSSLas variables CSS contienen valores específicos para volver a ser utilizados a lo largo del documento. Estas variables se declaran con la siguiente notación –color-primario: #212121;. Y para acceder a estas, se utiliza la función var(), como por ejemplo, color: var(–color-primario);.Esta propiedad nos puede servir de gran ayuda en el caso de tener páginas muy complejas y grandes. Podríamos almacenar la paleta de colores en variables y usarlas según las necesitemos.Ahora veremos varios ejemplos valiosos que demuestran el poder de las variables de CSS.Como cambiar entre tema oscuro y claroVamos a crear una pequeña carta y un botón para alternar entre 2 temas (oscuro y claro) usando variables de CSS. Tema oscuro / claro En este ejemplo vemos como podemos cambiar los colores de toda una página mediante variables de CSS. Simplemente cambiamos el atributo global data dinámicamente con un botón que escucha los eventos mediante Javascript. Después podemos acceder a este atributo data a través de CSS así :root[data-theme=’dark’] y con esto conseguimos sobrescribir todos los colores que tengamos asignados. /* Aqui almacenamos la paleta de colores para el tema claro */ :root { --background: #EEEEEE; --color-title: #404248; --color-text: #3D3E4C; --color-text-bold: #212121; } /* Aqui almacenamos la paleta de colores para el tema oscuro */ :root[data-theme='dark'] { --background: #212121; --color-title: #29B6F6; --color-text: #AFAFAF; --color-text-bold: #FFFFFF; } .panel { background-color: var(--background); padding: 3em; border-radius: 15px; } .panel h2 { color: var(--color-title); font-weight: 600; margin: 0; } .panel p { color: var(--color-text); line-height: 1.8em; margin-top: 2em; } .panel b { color: var(--color-text-bold); } .panel-header { display: flex; justify-content: space-between; align-items: center; } .switch-container { display: flex; } .panel-body { width: 80%; } #switch[type=checkbox] { height: 0; width: 0; visibility: hidden; } .switch-label { cursor: pointer; width: 55px; height: 26px; background: grey; float: right; border-radius: 100px; position: relative; } .switch-label::after { content: ''; position: absolute; top: 3px; left: 3px; width: 20px; height: 20px; background: #fff; border-radius: 90px; transition: 0.3s; } #switch:checked + .switch-label { background: var(--color-title); } #switch:checked + .switch-label::after { left: calc(100% - 5px); transform: translateX(-100%); } .switch-label:active::after { width: 45px; } html.transition, html.transition *, html.transition *::before, html.transition *::after { transition: all 600ms !important; transition-delay: 0 !important; } Tema oscuro / claro En este ejemplo vemos como podemos cambiar los colores de toda una página mediante variables de CSS. Simplemente cambiamos el atributo global data dinámicamente con un botón que escucha los eventos mediante Javascript. Después podemos acceder a este atributo data a través de CSS así :root[data-theme='dark'] y con esto conseguimos sobrescribir todos los colores que tengamos asignados. var checkbox = document.querySelector('input[name=theme]'); // Registramos el evento 'change' del botón checkbox.addEventListener('change', function() { transition() if (this.checked) document.documentElement.setAttribute('data-theme', 'dark') else document.documentElement.setAttribute('data-theme', 'light') }) // Esta función añadirá la clase 'transition' en la raiz (html) para después eliminarla a los 600ms let transition = () => { document.documentElement.classList.add('transition'); window.setTimeout(() => { document.documentElement.classList.remove('transition') }, 600) }CSS GridGrid es la herramienta de css más potente que existe para crear cualquier tipo de diseño responsive y sin límites. Grid, al contrario que Flexbox, trabaja en un sistema de 2 dimensiones.Esto no quiere decir Flexbox y Grid sean mutuamente excluyentes, al contrario, es muy recomendable plantear tus diseños con ambas herramientas.El objetivo es estructurar los componentes de tu página con las herramientas que te ofrece Grid. Es decir, como quieres que se muestre y qué tamaño deben tener según el dispositivo.Finalmente, organizar el espacio dentro de estos componentes debería ser tarea de Flexbox.Cómo definir la plantilla gridEn este ejemplo veremos cómo podemos estructurar nuestra plantilla y que se adapte a todos los dispositivos. Header Sidebar Body Footer Primero fijamos las áreas del contenedor y las dimensiones que va a tener. Para eso utilizamos la propiedad grid-template-areas. Dentro precisamos que elementos irán en cada fila y columna. Header Sidebar Body Footer .grid-wrapper { display: grid; grid-template-areas: "header body sidebar" "header footer footer"; grid-gap: 15px; /* 15px de espaciado entre contenedores */ grid-template-rows: 250px 200px; /* Las dimensiones de cada fila */ grid-template-columns: 150px 2fr 1fr; /* Las dimensiones de cada columna */ }Para que el código de arriba funcione, necesitamos darle un nombre de área a cada contenedor. Por lo tanto, usaremos la propiedad grid-area en cada uno de estos elementos..grid-header { grid-area: header; /* Nombre de área del grid-header */ background-color: #ae52d4; } .grid-header span { transform: rotate(-90deg); } .grid-body { grid-area: body; background-color: #43a047; } .grid-sidebar { grid-area: sidebar; background-color: #ff9421; } .grid-footer { grid-area: footer; background-color: #3d3e4b; }En este punto tenemos la estructura creada y hemos dado nombre a los contenedores. Lo último que nos falta es añadir puntos de ruptura para organizar la distribución de todos los contenedores.@media (max-width: 1300px) { .grid-wrapper { grid-template-areas: "header header" "body sidebar" "footer footer"; grid-template-rows: 1fr 200px 1fr; grid-template-columns: 3fr 350px; } .grid-header span { transform: rotate(0deg); } } @media (max-width: 700px) { .grid-wrapper { grid-template-areas: "header" "body" "sidebar" "footer"; grid-template-rows: repeat(4, 1fr); /* Usamos la función repeat() para asignar el tamaño de 1fr a cada una de las 4 filas. */ grid-template-columns: 1fr; } }Una vez hecho esto, ya tenemos un diseño 100% responsive totalmente personalizado y sin tocar una sola línea de HTML.Ejemplo de galeríaGracias a CSS Grid poder crear una galería de imágenes en tiempo récord. Nos basta con 2 líneas de código para preparar nuestra galería complemente responsive. Disminuye el tamaño del navegador para apreciar los cambios. .grid-gallery { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); grid-gap: 15px; } .grid-gallery div { background-color: #ff9421; height: 150px; }El truco se encuentra en la siguiente línea:grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));Básicamente estamos diciendo lo siguiente: repeat(). Que se generen tantas columnas como elementos hijo. auto-fit. Rellena todo el espacio posible de la fila. Si pusiéramos auto-fill, estaríamos rellenando tantos elementos como puedan caber en la fila, sin expandir tanto el ancho de los objetos. minmax(). Define un rango de tamaño mayor o igual que min  y menor o igual que max. En líneas generales estamos obligando a que ocupe como mínimo 150px. La unidad 1fr representa una fracción del espacio disponible en el contenedor de la rejilla. FlexboxTenemos en nuestro blog un artículo que te explica todo lo que necesitas saber sobre flexbox.AnimacionesKEYFRAMESKeyframesUna manera para darle vida a nuestra página es mediante el uso de las animaciones. En este apartado, hablaremos de los keyframes. Lo primero de todo, os dejo el código de la animación de arriba. KEYFRAMES @keyframes background { from { background-color: #FC354C; } to { background-color: #0ABFBC; } } #animation { animation: 1.5s background infinite alternate; width: 100%; height: 350px; font-size: 3em; } .blend-text { background-color: black; border: 4px solid black; color: white; border-radius: 5px; font-weight: bold; padding: 30px; mix-blend-mode: multiply; /* Esta propiedad describe cómo el contenido de un elemento debe mezclarse con el resto */ transition: all .5s ease; /* Si definimos la transicion aquí y no en el :hover, obligamos a que la animación sea de entrada y salida. */ } .blend-text:hover { background-color: transparent; color: black; cursor: pointer; } .center { display: flex; justify-content: center; align-items: center; }Cómo funcionan los keyframesHay 2 maneras de declarar una animación mediante keyframes. Lo primero de todo hace falta que le demos un nombre a la animación, justo después de la palabra clave @keyframes.@keyframes nombre {}Ahora debemos definir cómo va a ser la animación. La primera opción y más avanzada es utilizar breakpoints que determinamos mediante porcentajes. #kf-animation { width: 200px; height: 80px; background-color: #ff9421; border-radius: 5px; } #kf-animation:hover { cursor: pointer; animation: .5s button-animation infinite linear; } #kf-animation:hover::after { content: 'Aaahh'; font-size: 1.2em; height: 100%; display: flex; justify-content: center; align-items: center; } @keyframes button-animation { 0% { transform: translateX(-5px) rotate(5deg); } 10% { transform: translateX(5px) rotate(-7deg); } 20% { transform: translateX(-5px) rotate(2deg); } 30% { transform: translateX(5px) rotate(3deg); } 40% { transform: translateX(-5px) rotate(-5deg); } 50% { transform: translateX(5px) rotate(3deg); } 60% { transform: translateX(-5px) rotate(-4deg); } 70% { transform: translateX(5px) rotate(3deg); } 80% { transform: translateX(-5px) rotate(-2deg); } 90% { transform: translateX(5px) rotate(-1deg); } 100% { transform: translateX(-5px) rotate(3deg); } }La segunda es utilizar la claves from y to. Con esto se entiende que la animación se ejecutará progresivamente desde el inicio (0%) hasta el final (100%).@keyframes button-animation { from { top: 0px; } to { top: 200px; }TransicionesBajo mi punto de vista, las transiciones son la manera más sencilla de animar los componentes de una página web. Una transición se ejecuta cuando cambia el valor de una o más propiedades en un periodo de tiempo..selector { transition: }Con esas 4 propiedades podemos definir la transición del selector. Podemos provocar estas animaciones con algunas pseudoclases, como por ejemplo, :hover, :focus, :active y más..selector { background-color: #3d3e4b; transition: background-color 0.5s ease-out; } .selector:hover { background-color: #ff9421; }Por último, debemos saber el tipo de curva de velocidad que vamos a aplicar en la animación. Tenemos a nuestra disposición muchísimas variaciones prefijadas que nos pueden servir. linear. Mantiene la misma velocidad de inicio a fin. ease. Inicio y fin lentos, transición rápida. ease-in. Inicio lento y después mantiene la velocidad. ease-out. Inicio y fin lento. Además de las versiones que ya existen, es posible personalizar tu propia curva de bézier. En el siguiente enlace te dejo como puedes crear la tuya propia. INARVIS info@inarvis.com INARVIS info@inarvis.com .example-container { width: 100%; } .flip-card { width: 275px; height: 275px; perspective: 1000px; /* Así podemos apreciar el giro de la carta. Aplica la perspectiva en el plano Z. */ } .flip-card-inner { width: 100%; height: 100%; transition: all 0.5s ease-in; transform-style: preserve-3d; /* Importante para que los hijos mantengan la posición 3D. */ box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2); } .flip-card:hover .flip-card-inner { transform: rotateY(180deg); cursor: pointer; } .flip-card-front, .flip-card-back { position: absolute; width: 100%; height: 100%; backface-visibility: hidden; } .flip-card-front { background-color: #3d3e4b; color: #ff9421; display: flex; flex-direction: column; } .flip-card-front span{ font-size: 2.5em; font-weight: bold; font-family: 'Poppins'; } .flip-card-back { background-color: #3d3e4b; color: white; transform: rotateY(180deg); }Otras propiedades interesantesExisten otras propiedades de CSS que no son tan conocidas y que son de gran utilidad.Como optimizar la precarga de fuentesTe habrás dado cuenta que en muchas páginas el texto tarda mucho tiempo en cargar del todo, y eso no es bueno para el usuario. Si tardamos demasiado en mostrar contenido, corremos el riesgo de que el usuario salga de nuestra página.Gracias a esta guía hemos podido reducir considerablemente el tiempo de muestra y carga de las fuentes. En resumen, podemos reducir los tiempos de carga siguiendo los pasos de esta lista: Debemos priorizar la descarga de fuentes cuanto antes. Esto lo podemos conseguir con el atributo rel=’preload’. Debemos usar la declaración @font-face para definir nuestras fuentes y reducir los tiempos de renderizado de las fuentes. Debemos mostrar el texto lo antes posible sin importar que nuestra fuente este cargada. Queremos evitar a toda costa que el texto sea invisible. Entonces, usando La propiedad font-display: swap dentro del font-face cumplimos con este requisito. Debemos usar un formato que permita una alta compresión para reducir los tiempos de carga. En este caso, la extensión WOFF2 es ideal. Con todo esto, el resultado final nos quedaría algo parecido a lo siguiente.@font-face { font-family: 'Poppins'; font-display: swap; /* El navegador utiliza la fuente por defecto hasta que la fuente se descargue por completo */ font-style: 'normal'; font-weight: bold; src: url(.woff2); }Selectores de atributosEstos selectores se utilizan junto a una expresión regular para filtrar elementos muy concretos. [atributo=valor] selecciona los elementos cuyo atributo coincida con el valor. [atributo~=valor] selecciona los elementos cuyo atributo al menos contenga el valor dentro de una lista de palabras separadas por espacios. [atributo|=valor] selecciona los elementos cuyo atributo tenga exactamente el valor o empiece por seguido de un guion. [atributo^=valor] selecciona aquellos elementos empiezan con el valor del atributo. [atributo$=valor] selecciona aquellos elementos terminan con el valor del atributo. [atributo*=valor] selecciona aquellos elementos contienen con el valor del atributo. Todo sobre el enlace nofollow Descubre como hacer animaciones con css [target="_blank"]::after { content: '\2197'; font-weight: bold; } [class|="second"] { list-style-type: upper-roman; } Todo sobre el enlace nofollow Descubre como hacer animaciones con css Clip pathEsta propiedad permite ocultar partes de una imagen creando formas complejas. Habitualmente se utiliza en imágenes o contenedores. .clip-examples { display: flex; justify-content: space-around; } .clip-examples div { width: 4em; height: 4em; } .clip-example-1 { background-color: red; -webkit-clip-path: circle(50.0% at 50% 50%); clip-path: circle(50.0% at 50% 50%); } .clip-example-2 { background-color: green; -webkit-clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%); clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%); } .clip-example-3 { background-color: #29B6F6; -webkit-clip-path: polygon(0% 0%, 100% 0%, 100% 75%, 75% 75%, 75% 100%, 50% 75%, 0% 75%); clip-path: polygon(0% 0%, 100% 0%, 100% 75%, 75% 75%, 75% 100%, 50% 75%, 0% 75%); }Si quieres saber más sobre esta propiedad, visita este enlace. Si te ha gustado, compártelo en las redes sociales! Twitter LinkedIn