Selección y CSS

La habilidad de resaltar texto y otros objetos se formó entre los usuarios de computadoras hace muchos años. Destacamos el contenido de las páginas web por varias razones. Tal vez necesite copiar el texto y citarlo en alguna parte, tal vez, es simplemente más fácil para alguien leer el texto, resaltando sus fragmentos. En dispositivos móviles, sin embargo, destaca algo más difícil. Por ejemplo, me molesta. No me gusta resaltar el contenido de las páginas web en el teléfono. Esta operación parece ser de alguna manera "incorrecta". En este artículo, hablaré sobre todo lo que necesita saber sobre las selecciones de estilo con CSS. En particular, hablaremos sobre el pseudo-elemento y la propiedad.



::selectionuser-select. Este artículo tiene como objetivo mostrar a todos los que quieren que CSS trabaje con selecciones y cómo usar diferentes métodos para trabajar con selecciones.

Los basicos


En MDN, puede aprender que un pseudo-elemento le ::selectionpermite aplicar estilos a partes de un documento que ha sido seleccionado por el usuario (por ejemplo, usando el mouse).

Para usarlo es ::selectionsuficiente usar la siguiente construcción:

p::selection {
   color: #fff;
   background-color: #000
}



Texto seleccionado.

Aquí hay un ejemplo con el que puede experimentar.

Propiedades admitidas :: selección


Vale la pena señalar que el pseudo-elemento ::selectionsolo admite propiedades color, backgroundy text-shadow.

Personaliza tus propios efectos de selección


¿Qué pasa si necesitamos que la selección se vea especial? Por ejemplo, ¿para que la selección tenga una cierta altura o algún fondo interesante? Echa un vistazo a la siguiente figura.


Un ejemplo de una selección especial de selección

Esto es posible, aunque requerirá algo de esfuerzo. Así es como se realiza la selección que se muestra arriba:

  • Se agrega un pseudo-elemento, con el mismo texto que seleccionamos. Luego, el pseudo-elemento se establece en una propiedad height: 50%y un color de fondo blanco.
  • El pseudo-elemento está ubicado sobre el texto fuente.

Si ahora selecciona el texto, el pseudo-elemento se superpondrá verticalmente al 50% del texto. Esto nos permite simular el efecto que necesitamos.

p {
  position: relative;
  color: #fff;
}

p:after {
  content: attr(data-content);
  position: absolute;
  color: #000;
  top: 0;
  left: 0;
  width: 100%;
  height: 50%;
  background-color: #fff;
}

p::selection {
  background: rgba(76, 125, 225, 0.18);
}

Aprendí sobre esta técnica aquí .

Otra opción para esta selección se presenta a continuación. Aquí, en lugar de una selección sólida, implementé la selección como un gradiente CSS. El punto aquí es usar un degradado blanco con una altura del 50% y llenar el elemento una vez con la imagen de fondo usando el valor no-repeatal establecer la propiedad background.

h1:after {
  content: attr(data-content);
  position: absolute;
  color: #000;
  top: 0;
  left: 0;
  width: 100%;
  background: linear-gradient(#fff, #fff) top/100% 50% no-repeat;
}

La siguiente figura ilustra esta técnica.


Implementación de resaltado de degradado

Con suerte, pude explicar claramente esta idea. Aquí hay un ejemplo de trabajo.

Selección animada


Trabajando en el ejemplo anterior, hice la siguiente pregunta: "¿Es realista animar la selección?". Por ejemplo, en el proceso de selección de texto, la altura de la selección es del 50%. Y cuando el puntero del mouse se mueve hacia un lado, la altura de la selección aumenta al 80%. ¿Cómo hacerlo? Pero así:

p {
    transition: background 0.3s ease-out;
}

p:hover:after {
  background-size: 100% 80%;
}



Texto en el proceso de selección.


Texto después de completar la selección

Aquí hay un video que muestra la selección animada.

Texto multilínea


La técnica de ajuste de selección anterior, desafortunadamente, no es adecuada para texto de varias líneas. Sin embargo, para implementar algo similar para dicho texto, debe recurrir a las capacidades de JavaScript y poner cada palabra en un elemento en línea (en minúsculas), por ejemplo, en <span>. Después de que cada palabra aparezca en su propio elemento <span>, se debe agregar un pseudo-elemento a cada uno de estos elementos. Y después de eso, el efecto descrito anteriormente se puede aplicar al texto multilínea.

Aquí hay un script para poner cada palabra en un <span>contenedor:

let paragraph = document.querySelector(".text");
const words = paragraph.textContent.split(" ");

paragraph.innerHTML = "";

words.forEach(function (word) {
  let wordItem = document.createElement("span");
  wordItem.setAttribute("data-word", word);
  wordItem.innerHTML = word + " ";
  paragraph.appendChild(wordItem);
});

Después de eso, los elementos <span>deben ser estilizados. Luego, a cada uno de ellos debe agregar un pseudo-elemento:

span {
    position: relative;
    font-size: 1.25rem;
    line-height: 1.4;
  }

  span::after {
    content: attr(data-word);
    position: absolute;
    left: 0;
    right: 0;
    top: -0.28em;
    height: 75%;
    padding-top: 0.14em;
    background: #fff;
    pointer-events: none;
  }

  span::selection {
    background: rgba(#4C7DE1, 0.18);
  }

Si observa este diseño en la práctica, resulta que funciona, pero no exactamente como podría esperar. A continuación se muestra un ejemplo de resaltado de texto de varias líneas. Puede notar que la selección parece irregular.


Selección

no homogénea Diría que una selección de varias líneas de este tipo no es muy buena y que no debería usarse a escala global. Quizás debería usarse solo, por ejemplo, para organizar la selección de un párrafo en particular.

Aquí, con tal selección, puedes experimentar.

Uso creativo :: selección y sombra de texto


Dado que una de las propiedades que admite el pseudo-elemento ::selectiones text-shadowque podemos tratar de lograr algunos efectos interesantes usando varias sombras del texto. Estamos explorando las posibilidades que esta idea abre ante nosotros.

▍ Destacar con largas sombras



El texto seleccionado proyecta largas sombras.

Aquí se explica cómo implementar este efecto:

p::selection {
    color: #444444;
    background: #ffffff;
    text-shadow: 1px 0px 1px #cccccc, 0px 1px 1px #eeeeee, 2px 1px 1px #cccccc, 1px 2px 1px #eeeeee, 3px 2px 1px #cccccc, 2px 3px 1px #eeeeee, 4px 3px 1px #cccccc, 3px 4px 1px #eeeeee, 5px 4px 1px #cccccc, 4px 5px 1px #eeeeee, 6px 5px 1px #cccccc, 5px 6px 1px #eeeeee, 7px 6px 1px #cccccc;
}

▍ Efecto de texto de esquema



El texto seleccionado se convierte en contorno

Esta idea que encontré en este artículo. Estamos hablando del hecho de que al usar la propiedadtext-shadowpuede simular el efecto del texto del esquema.

p::selection {
    color: #fff;
    text-shadow
        -1px -1px 0 #000,  
        1px -1px 0 #000,
        -1px 1px 0 #000,
        1px 1px 0 #000;
}

▍ efecto de desenfoque



El texto seleccionado se ve borroso.

Otro efecto interesante que se puede aplicar al texto seleccionado es desenfocar el texto. La conclusión es usar la propiedad al configurar el color del textocolor: transparent. Las sombras establecidas con la ayudatext-shadowno desaparecerán en ningún lado, lo que dará el efecto deseado.

p::selection {
  color: transparent;
  text-shadow: 0 0 3px #fff;
}

Estoy seguro de que usted mismo podrá encontrar muchos más ejemplos de text-shadowselecciones de estilo. Esta propiedad nos brinda posibilidades ilimitadas.

▍ Textos de sombra y rendimiento


No se recomienda utilizar estilos demasiado complejos al personalizar text-shadow. El hecho es que el entusiasmo excesivo por esta propiedad conduce a problemas de rendimiento. Aquí hay un video que muestra un ejemplo de tales problemas.


Uso de estilos muy sofisticados para personalizar la selección de texto

El efecto de neón presentado aquí es muy complejo. Tenga en cuenta que cuando se selecciona este texto, hay un retraso notable entre el momento en que se selecciona el texto y el momento en que se aplica la estilización. Además, preste atención al hecho de que lo que no debe aparecer en la parte superior e izquierda. Por lo tanto, le pido que lo use context-shadowcuidado.

¿Se destacan los elementos de forma?


Una breve respuesta a la pregunta en el título de esta sección sonará "sí". Me parece que esto está mal: selecciona la página, pero resulta que el contenido dentro de los campos de entrada también está resaltado. Así es como se ve.


Se resalta el contenido dentro de los campos de entrada

, aquí también se puede seleccionar el texto dentro del botón. En la sección dedicada auser-select, hablaremos sobre si permitir o no a los usuarios resaltar las formas de los elementos.

Aquí hay un ejemplo.

Investigar la propiedad seleccionada por el usuario


La propiedad user-selectnos permite establecer la capacidad de seleccionar texto específico por parte del usuario. Esta propiedad puede ser útil para deshabilitar la capacidad de seleccionar texto, que puede ser útil para limitar la capacidad del usuario para seleccionar materiales ubicados uno al lado del otro. Aquí hay un estándar que describe user-select.

Esta propiedad puede tomar los siguientes valores: none, auto, text, contain, all.

Casos de uso seleccionados por el usuario


▍Texto e icono


Si el elemento tiene texto y un icono, en forma de símbolo o icono tomado de alguna fuente, este icono se resaltará cuando se seleccione el texto. Considere el ejemplo que se muestra en la siguiente figura.


Botón con texto e icono

Aquí está el código para este botón:

<button>Our Services<span aria-hidden="true">▼</span></button>

Cuando selecciona este elemento, se parece al que se muestra a continuación.


Botón dedicado

Esto es completamente innecesario. Tenga en cuenta que el marcado utiliza un atributoaria-hiddenque oculta el icono de los lectores de pantalla. Para resolver el problema de resaltar lo que no necesita resaltar, podemos usar el siguiente estilo:

button span[aria-hidden="true"] {
    user-select: none;
}

Esto le permite prohibir la selección del icono. Y, al mismo tiempo, vinculamos la prohibición de selección al atributo aria-hidden. Como resultado, todo lo que no debería destacarse, muy probablemente, no debería ser visible para los lectores de pantalla.

▍ Banderas


Este comportamiento de las banderas me molesta cuando, al establecer o desmarcar una bandera, selecciono accidentalmente el texto de su descripción. Así es como se ve.


El texto de la descripción del indicador se selecciona aleatoriamente. Puede

resolver este problema al diseñar el elemento de la<label>siguiente manera:

label {
    user-select: none;
}

▍ Resalta todo el texto


El valor allque puede tomar una propiedad le user-selectpermite lograr un efecto interesante. Si el elemento padre tiene esta propiedad con dicho valor, entonces todo el texto contenido en dicho elemento puede seleccionarse con un solo clic. Esto puede ser útil para trabajar con contenido de texto, que debe resaltarse en su totalidad. Por ejemplo, para resaltar fragmentos de código disponibles en una página:

.embed-code {
    user-select: all;
}

Un fragmento de texto diseñado en ese estilo se puede seleccionar con un solo clic.

aplicaciones web


El usuario debe percibir la aplicación web como una aplicación real. ¿Es posible seleccionar texto de botón en aplicaciones normales? No, no puedes. Es importante que las aplicaciones web reflejen las características familiares de las aplicaciones normales, incluso si están diseñadas con HTML y CSS.

Considere algunos ejemplos de la vida.

▍Slack


En Slack, puede resaltar etiquetas y campos de entrada. Sin embargo, los textos de los botones no están resaltados.


Los títulos de los botones no están resaltados.

Aquí hay otro ejemplo.


Se resalta la firma en la barra de título de la ventana modal

. No se puede resaltar la fecha del chat.


La fecha no se puede asignar

En general, me parece extraño que en la aplicación pueda seleccionar algunos textos que, al parecer, no deberían admitir la selección. Hay lugares en la interfaz de Slack donde se usauser-select: none, pero hay menos lugares de los que cabría esperar. Por ejemplo, para mí, como usuario, no hay ningún beneficio en resaltar el título de una ventana modal.

▍Notion


El enfoque para la selección de elementos implementados en Notion, me gusta más. Esta aplicación web es más como una aplicación real, en lugar de un sitio web, cualquier parte de la cual se puede resaltar.


Lo que no debe destacarse no se destaca.

Ni un solo fragmento de texto se resalta en esta imagen. Esto es exactamente lo que puede esperar de una aplicación.

No use la selección global deshabilitar


No se recomienda deshabilitar la selección globalmente. Cuando utilice la selección de deshabilitación, intente deshabilitarla solo para elementos para los que no tiene sentido. Para hacer esto, puede crear una clase auxiliar. Por ejemplo, esto:

.disable-selection {
    -webkit-user-select:text;
    -moz-user-select:text;
    -ms-user-select:text;
    user-select:text;
}

Mal patrón


Hay un patrón UX que realmente no me gusta. Consiste en mostrar una advertencia al intentar resaltar texto. Esto molesta y hace que el usuario sienta que está tratando de controlar su interacción con el sitio. Un ejemplo de este patrón se muestra a continuación.


Desactive el resaltado con la visualización de notificaciones

. No haga esto.

Destacar en dispositivos móviles


Hay una propiedad -webkit-touch-calloutpara iOS Safari que debería desactivar la visualización de la información sobre herramientas estándar que se muestra cuando se selecciona texto. Intenté usar esta propiedad, pero no funciona.

p {
    -webkit-touch-callout: none;
}

Los estilos ::selectiontampoco funcionan.

Y la propiedad user-select: nonefunciona como se esperaba.

Traté de encontrar un ejemplo real que ilustrara este problema. Copié un texto de Wikipedia. Al mismo tiempo, el texto que era completamente innecesario para mí fue copiado (listen). Esto es molesto.


Junto con el texto útil, se copia y (escucha)

En lugar de permitir que el usuario copie esta "escucha", sería mejor agregar un estilo a este elementouser-select: none. Como resultado, al copiar texto que contiene este elemento, no se copiará.

Resumen


Aquí observamos métodos para personalizar el resaltado de elementos de páginas web usando CSS. Puede interesarle mirar este material.

¡Queridos lectores! ¿Cómo se configura la selección de texto en sus proyectos?


All Articles