Components (registry)Layout
Article with Table of Contents
Documento largo con indice lateral sticky generado desde sus headings: legales, documentacion y articulos de fondo. El cuerpo lo aporta el consumidor dentro de [data-toc-content].
Contrato del layout
Un layout transporta anatomia, no pintura: se rellena por slots y depende del CSS de los componentes que lista. Instalarlo sin ellos lo deja sin estilos.
- Slots
{{toc_levels}}{{toc_offset}}{{eyebrow}}{{heading}}{{updated}}{{toc_label}}- Componentes requeridos
section-headertocprose
Anatomía CSS
<div class="layoutArticleToc"> </div>
CSS mínimo funcional
Autocontenido: sin imports ni tokens. Para previews y prototipos — en producción se consume el CSS del DS.
/* Layout: article-toc — solo la rejilla del documento.
El lateral lo gobierna .container; la medida de lectura, prose (--prose-measure);
el ritmo vertical de la cabecera, section-header. */
.l-article-toc__grid {
display: grid;
/* minmax(0, 1fr), no 1fr: el minimo automatico de una columna es el contenido
de su item, y una tabla ancha dentro del documento ensancharia la rejilla mas
que el viewport, arrastrando la pagina entera a scroll horizontal. */
grid-template-columns: minmax(0, 1fr);
gap: 40px;
/* start, no stretch: si el aside se estira a la altura del documento, sticky
no tiene recorrido y el indice deja de seguir el scroll. */
align-items: start;
}
.l-article-toc__sidebar,
.l-article-toc__body {
min-width: 0;
}
.l-article-toc__updated {
margin-block-start: 0;
}
@media (min-width: 992px) {
.l-article-toc__grid {
/* La columna del cuerpo se capa a la medida de lectura y la rejilla se
centra: con 1fr, en pantallas anchas el sobrante caia entero a la
derecha del prose y el documento se veia cargado hacia el rail.
El knob --prose-measure debe fijarse en la seccion (no en el prose)
para que rejilla y cabecera lo hereden juntos. */
grid-template-columns: 15rem minmax(0, 68ch);
justify-content: center;
gap: 64px;
}
/* La cabecera comparte caja con la rejilla centrada: sin esto el titulo
quedaria anclado al borde del container mientras el documento flota. */
.l-article-toc__header {
width: 100%;
max-width: calc(15rem + 64px + 68ch);
margin-inline: auto;
}
.l-article-toc__sidebar {
position: sticky;
/* El offset del sticky y el data-toc-offset del behavior describen la misma
barra del host: si se cambia uno, se cambia el otro. */
top: 40px;
}
}
@media (max-width: 991px) {
/* Sin columna lateral el indice va arriba, y un documento de 36 secciones
seria un muro antes del primer parrafo: se acota y scrollea el propio
indice. Alternativa para el consumidor que prefiera colapsarlo: envolver
el nav en <details class="toc toc--collapsible">. */
.l-article-toc__sidebar {
max-height: 40vh;
overflow-y: auto;
}
.l-article-toc__body {
--prose-measure: none;
}
}
Codigo fuente
layouts/article-toc.css
/* Layout: article-toc — solo la rejilla del documento. El lateral lo gobierna .container; la medida de lectura, prose (--prose-measure); el ritmo vertical de la cabecera, section-header. */ .l-article-toc__grid { display: grid; /* minmax(0, 1fr), no 1fr: el minimo automatico de una columna es el contenido de su item, y una tabla ancha dentro del documento ensancharia la rejilla mas que el viewport, arrastrando la pagina entera a scroll horizontal. */ grid-template-columns: minmax(0, 1fr); gap: var(--spacing-10); /* start, no stretch: si el aside se estira a la altura del documento, sticky no tiene recorrido y el indice deja de seguir el scroll. */ align-items: start; } .l-article-toc__sidebar, .l-article-toc__body { min-width: 0; } .l-article-toc__updated { margin-block-start: 0; } @media (min-width: 992px) { .l-article-toc__grid { /* La columna del cuerpo se capa a la medida de lectura y la rejilla se centra: con 1fr, en pantallas anchas el sobrante caia entero a la derecha del prose y el documento se veia cargado hacia el rail. El knob --prose-measure debe fijarse en la seccion (no en el prose) para que rejilla y cabecera lo hereden juntos. */ grid-template-columns: 15rem minmax(0, var(--prose-measure, 68ch)); justify-content: center; gap: var(--spacing-16); } /* La cabecera comparte caja con la rejilla centrada: sin esto el titulo quedaria anclado al borde del container mientras el documento flota. */ .l-article-toc__header { width: 100%; max-width: calc(15rem + var(--spacing-16) + var(--prose-measure, 68ch)); margin-inline: auto; } .l-article-toc__sidebar { position: sticky; /* El offset del sticky y el data-toc-offset del behavior describen la misma barra del host: si se cambia uno, se cambia el otro. */ top: var(--spacing-10); } } @media (max-width: 991px) { /* Sin columna lateral el indice va arriba, y un documento de 36 secciones seria un muro antes del primer parrafo: se acota y scrollea el propio indice. Alternativa para el consumidor que prefiera colapsarlo: envolver el nav en <details class="toc toc--collapsible">. */ .l-article-toc__sidebar { max-height: 40vh; overflow-y: auto; } .l-article-toc__body { --prose-measure: none; } }