Seleccionar rango de fechas en CSS
El selector de rango de fechas permite a los usuarios seleccionar un rango de tiempo entre una fecha de inicio y una fecha de finalización, lo cual es útil para reservar viajes, ordenar información por bloques de fechas, seleccionar períodos de tiempo y planificar horarios.

Voy a mostrarles un ejemplo en el que, aunque JavaScript está involucrado, la mayor parte del trabajo se maneja mediante la sintaxis “n del selector” de CSS. :nth-child Los selectores facilitan la creación de selecciones de rango.
Sintaxis “n del selector”
esta gramática :nth-child selector Primero filtre los elementos según el selector dado en todos los elementos secundarios y luego selecciónelos en orden de conteo.
<p>The reclamation of land...</p>
<p>The first reclamations can be traced...</p>
<p class="accent">By 1996, a total of...</p>
<p>Much reclamation has taken...</p>
<p class="accent">Hong Kong legislators...</p>
.accent {
color: red;
}
.accent:nth-child(2) {
font-weight: bold; /* does not work */
}
:nth-child(2 of .accent){
text-decoration: underline;
}
hay dos .accentpárrafo -ed red Texto. Cuando intentamos centrarnos en el segundo párrafo acentuado, .accent:nth-child(2) No se puede seleccionar porque está intentando encontrar .accent Los elementos son segundo hijo de los padres.
Sin embargo, :nth-child(2 of .accent) Selecciona y diseña exitosamente el segundo párrafo acentuado porque solo busca donde el segundo elemento **.accent** elemento Y no el segundo de todos los niños.
disposición
Pasando a nuestro ejemplo principal, ordenemos el diseño del mes. Todo lo que necesitas son unas pocas líneas de CSS.
<ul id="calendar">
<li class="day">Mon</li>
<li class="day">Tue</li>
<!-- up to Sat -->
<li class="date">01<input type="checkbox" value="01"></li>
<li class="date">02<input type="checkbox" value="02"></li>
<!-- up to 31 -->
</ul>
#calendar {
display: grid;
grid-template-columns: repeat(7, 1fr); /* 7 for no. of days in a week */
}
Selecciona solo dos fechas
Ahora necesitamos usar JavaScript porque no podemos seleccionar/deseleccionar controles en CSS. Pero incluso aquí, la sintaxis “n del selector” es muy útil.
Cuando seleccionamos dos fechas para crear un rango, al hacer clic en la tercera fecha se actualizará el rango y se eliminará una de las fechas anteriores.
Puede configurar la lógica de cambio de escala del alcance como desee. Estoy usando este enfoque: si tercero La fecha es anterior o posterior a la Regresar finalmente fecha, se convierte nuevo regreso Fecha, no se seleccionan fechas anteriores. Si la tercera fecha es anterior a la última fecha de salida, esa fecha se convertirá en la nueva fecha de salida y se cancelará la selección de la fecha de salida anterior.
const CAL = document.getElementById('calendar');
const DT = Array.from(CAL.getElementsByClassName('date'));
CAL.addEventListener('change', e => {
if (!CAL.querySelector(':checked')) return;
/* When there are two checked boxes, calendar gets 'isRangeSelected' class */
CAL.className = CAL.querySelector(':nth-child(2 of :has(:checked))') ? 'isRangeSelected':'';
/* When there are three checked boxes */
if (CAL.querySelector(':nth-child(3 of :has(:checked))')) {
switch (DT.indexOf(e.target.parentElement)) {
/* If the newly checked date is first among the checked ones,
the second checked is unchecked. Onward date moved earlier. */
case DT.indexOf(CAL.querySelector(':nth-child(1 of :has(:checked))')):
CAL.querySelector(':nth-child(2 of :has(:checked)) input').checked = 0;
break;
/* If the newly checked date is second among the checked ones,
the third checked is unchecked. Return date moved earlier. */
case DT.indexOf(CAL.querySelector(':nth-child(2 of :has(:checked))')):
CAL.querySelector(':nth-child(3 of :has(:checked)) input').checked = 0;
break;
/* If the newly checked date is third among the checked ones,
the second checked is unchecked. Return date moved later. */
case DT.indexOf(CAL.querySelector(':nth-child(3 of :has(:checked))')):
CAL.querySelector(':nth-child(2 of :has(:checked)) input').checked = 0;
break;
}
}
});
Primero, obtenemos el índice de la fecha de verificación actual (DT.indexOf(e.target.parentElement)), luego vemos si esto es lo mismo que la primera verificación de todas las comprobaciones (:nth-child(1 of :has(:checked))), segundo(:nth-child(2 of :has(:checked))), o el tercero (:nth-child(3 of :has(:checked))). Debido a esto, desmarcamos la casilla para editar el rango de fechas.
Notarás que al usar la sintaxis “n del selector”, apuntar :checked La posición del cuadro que queremos entre todos los cuadros seleccionados. Aún más simple: en lugar de indexar a través de una lista de fechas de verificación en JavaScript, podemos seleccionarla directamente.
Diseñar la colección es incluso más fácil que eso.
Establecer estilo de rango
/* When two dates are selected */
.isRangeSelected {
/* Dates following the first but not the second of selected */
:nth-child(1 of :has(:checked)) ~ :not(:nth-child(2 of :has(:checked)) ~ .date) {
/* Range color */
background-color: rgb(228 239 253);
}
}
Al seleccionar dos fechas, la primera (1 of :has(:checked)) y el segundo (2 of :has(:checked)) está coloreado en azul claro para establecer un rango visual para ese bloque de días del mes.

El color se declara dentro del selector compuesto que selecciona la fecha (.date) en la primera fecha de control (:nth-child(1 of :has(:checked))), pero no todos los cheques para la segunda fecha (:not(:nth-child(2 of :has(:checked))).
Aquí está el ejemplo completo: