¿Qué es una pseudoclase y cómo se usa?

Una pseudoclase es un selector de CSS que nos permite seleccionar el estado específico en el que se encuentra un elemento. Esto nos ayuda a reducir el uso de clases para identificar diferentes estados en los elementos requeridos y a tener una hoja de estilos de fácil mantenimiento.
Para hacer uso de una pseudoclase en nuestra hoja de estilos es necesario agregar “{clase, elemento o Id}:nombre_de_la_pseudoclase” . Abajo te muestro un ejemplo práctico de cómo hacer uso de una pseudoclase cambiando el color del texto y fondo al pasar el cursor por un botón.

Button:hover{
	color: #000000;
	background-color: #ffffff;
}

Existen múltiples pseudoclases que puedes utilizar para tus proyectos, si quieres conocer más acerca de estos te recomiendo visitar el siguiente enlace que contiene la documentación de estos.

https://developer.mozilla.org/es/docs/Web/CSS/Pseudo-classes


¿Qué es un pseudoelemento y cómo se usa?

Un pseudoelemento es una propiedad que nos permite aplicar estilos a una parte específica de un elemento y/o agregar sub-elementos a este.
Para aplicar estilos a un pseudoelemento la declaración en tus hojas de estilos debe ser la siguiente “{clase, elemento o Id}::nombre_del_pseudoelemento”. A continuación te muestro cómo hacer la declaración de este en código, con el que cambiaremos el color del texto del placeholder.

input:focus::placeholder {
	color: #b8b8b8;
}

Puedes consultar el listado de pseudoelementos y toda la documentación de estos en el siguiente enlace:

https://developer.mozilla.org/es/docs/Web/CSS/Pseudoelementos


Para mostrarte de manera concreta el funcionamiento de estos 2 tipos de elementos trabajaremos en un ejemplo práctico (SASS) para obtener una animación como la siguiente:

Paso 1:

El primer paso es definir nuestro elemento con las etiquetas de HTML correspondientes. En este caso vamos a declarar un div con la clase form-input que será el elemento padre que contenga el campo de texto y la etiqueta que tendrá una transición de posición animada.

<div class="form-input">
    <input type="text"  placeholder="Ej. mail@test.com">
    <label>Mail</label>
</div>

Paso 2:

Para dar estilo a nuestro elemento comenzamos con la declaración de nuestras variables de los colores que ocuparemos en nuestro elemento.

$border: #a7a7a7;
$gray: #575757;
$white: #ffffff;
$black20: #cccccc;
$black40: #999999;
$disabled: #f2f2f2;
$primaryLight: #4a9af5;
$black: #000000;
$textDisabled: #b8b8b8;

Paso 3:

Para mantener el código un poco más estructurado y limpio declararemos 2 mixins que nos ayudarán con el posicionamiento de la etiqueta label que ocuparemos en el ejemplo:

@mixin translateY24(){
    -webkit-transform: translateY(-32px);
    -moz-transform: translateY(-32px);
    -o-transform: translateY(-32px);
    -ms-transform: translateY(-32px);
    transform: translateY(-32px);
}
@mixin translateY50(){
    -webkit-transform: translateY(-50%);
    -moz-transform: translateY(-50%);
    -o-transform: translateY(-50%);
    -ms-transform: translateY(-50%);
    transform: translateY(-50%);
}

Paso 4:

Comenzaremos con los estilos del elemento con la clase “.form-input”. Al ser este div el contenedor de los demás elementos, solo definiremos algunos estilos generales como margins, paddings, position, etc..

.form-input{
    position: relative;
    line-height: 14px;
    padding: 8px;
    display: inline-block;
    width: 100%;
    margin-top: 24px;
    max-width: 300px;
}

Paso 5:

Ahora que ya tenemos definidos los estilos del contenedor agregaremos estilos a la etiqueta “label” que será la que tenga una animación de movimiento. A dicha etiqueta le agregamos estilos para color de texto, posicionamiento. Es importante que incorporemos el estilo de transición para que la animación que trabajaremos más adelante se pueda visualizar.

& > label{
    color: $gray;
    background: $white;
    font-size: 14px;
    position: absolute;
    z-index: 2;
    left: 18px;
    top: 32px;
    padding: 0 2px;
    pointer-events: none;
    -webkit-transition: -webkit-all 100ms ease;
    -moz-transition: -moz-all 100ms ease;
    -o-transition: -o-all 100ms ease;
    -ms-transition: -ms-all 100ms ease;
    transition: all 100ms ease;
    @include translateY50();
}

Paso 6:

Una vez que tenemos los estilos de contenedor padre y el label podemos continuar  con los estilos del campo de texto. Y es aquí en donde usaremos las pseudoclases y los pseudoelementos.

¿Listo? ¡Comencemos!

Para trabajar con el campo de texto primero debemos de definir los estilos generales de este. En este caso le agregaremos un borde, una curvatura en las esquinas, márgenes interiores (padding) y estilos para el contenido del campo.

& > input{
    border: 1px solid $border;
    border-radius: 4px;
    color: $black40;
    font-size: 16px;
    outline: none;
    padding: 14px 12px;
    position: relative;
    width: 100%;
}

Con el siguiente bloque de estilos se realizará una validación del campo de texto. Con las pseudoclases valid e invalid validaremos el campo desde la hoja de estilos y así asignaremos una posición a la etiqueta ‘label’ dependiendo del resultado.

&:invalid + label {
    @include translateY50();
}
&:valid + label{
    @include translateY24();
}

Ahora pasaremos a asignar estilos cuando el campo este desactivado. Haremos uso de la pseudoclase “disabled”, está hará la asignación de los estilos solamente cuando el campo tenga el atributo disabled. Con esto haremos que los bordes sean grises y al mismo tiempo la etiqueta “label” cambiará de posición.

&:disabled{
    background: $disabled !important;
    border-color: $black20 !important;
    cursor: not-allowed;
    & + label{
        background: $white;
        @include translateY24();
    }
}

Como siguiente paso volveremos a realizar una validación del campo desde la hoja de estilos. En el bloque de texto mostrado a continuación, se asigna la posición a la etiqueta “label” dependiente de si el placeholder se está mostrando o no. Esto se logra haciendo uso de las pseudoclases “placeholder-shown” y “not”.

&:not(:placeholder-shown) + label{
    @include translateY24();
}
&:placeholder-shown + label{
    @include translateY50();
}

Haremos uso del pseudelemento ‘placeholder’ para ocultar el texto, asignando un color transparente. Esto impedirá que se vea el contenido de la etiqueta ‘label’ con este.

&::placeholder {
    color: transparent;
}

Como último paso haremos los estilos que adoptará el elemento cuando el campo de texto tenga el focus del cursor. En este fragmento de código cambiaremos el color del borde para darle un estado de “activo”, moveremos la etiqueta “label” a la parte superior y mostraremos el placeholder cambiando el color de texto.

&:focus {
    border-color: $primaryLight !important;
    color: $black !important;
    & + label {
        color: $primaryLight;
        @include translateY24();
    }
    &::placeholder{
        color: $textDisabled;
    }
}

Con estos pasos obtendremos como resultado una animación en el campo de texto como la que se mostró al inicio. A continuación te muestro el ejemplo práctico en jsfiddle para que puedas entender y modificar los estilos a tu manera.