posición: sticky funciona en algunos navegadores móviles, de modo que se puede hacer un menú de la barra de desplazamiento con la página, pero luego se adhieren a la parte superior de la ventanilla cada vez que el usuario se desplaza pasado.

Pero lo que si desea cambiar el estilo de su pegajosa barra de menú ligeramente, siempre es actualmente ‘pegando’? por ejemplo, puede que desee de la barra para tener las esquinas redondeadas siempre que el desplazamiento con la página, pero, a continuación, tan pronto como se pega a la parte superior de la ventana, usted quiere deshacerse de la parte superior de las esquinas redondeadas, y añadir un poco de sombra debajo de ella.

Hay algún tipo de pseudoselector (por ejemplo,::stuck) a los elementos de destino que han position: sticky y actualmente están pegando? O hacer los fabricantes de los navegadores tienen nada parecido a esto en la tubería? Si no, ¿dónde estaría yo la pido?

NB. javascript soluciones no son buenos para esto, porque en el móvil normalmente sólo se consigue de una sola scroll evento cuando el usuario suelta el dedo, así que JS no se puede saber el momento exacto en el que el desplazamiento de umbral fue aprobada.

InformationsquelleAutor callum | 2014-08-14

4 Comentarios

  1. 75

    Actualmente no hay un selector que se propone para los elementos que actualmente están «atorados». El Ubicados en una posición de Diseño de módulo de donde position: sticky se define no mencionar cualquier selector de cualquiera.

    Función de las solicitudes de CSS puede ser enviado a la www-estilo de la lista de correo. Yo creo que una :stuck pseudo-clase tiene más sentido que una ::stuck pseudo-elemento, ya que usted está buscando para atender a los elementos en sí mismos mientras están en ese estado. De hecho, un :stuck pseudo-clase se discutió hace algún tiempo; la principal complicación, se encontró, es que las plagas sólo acerca de cualquier propuesta de selector de que los intentos para que coincida con base en un dictado o se calcula estilo: dependencias circulares.

    En el caso de un :stuck pseudo-clase, el caso más simple de la circularidad ocurriría con el siguiente CSS:

    :stuck { position: static; /* Or anything other than sticky/fixed */ }
    :not(:stuck) { position: sticky; /* Or fixed */ }

    Y podría haber muchos más casos de borde que serían difíciles de abordar.

    Mientras que es generalmente acordado que tener selectores que coinciden con base en ciertos diseño de los estados sería agradable, por desgracia, las principales limitaciones que existen que hacen que estos no trivial de implementar. No me contengo la respiración por un puro CSS solución a este problema en cualquier momento pronto.

    • Desafortunadamente @BoltClock que es correcto, de no ser nativo de un largo, largo tiempo. Ejemplo hacks alrededor de estos pueden ser encontrados en: el correo de yahoo (desplácese a un correo del contenido, tienen un buen truco) y el panel de control de google (utiliza absoluta sombra elemento).
    • Eso es una vergüenza. Yo estaba buscando una solución a este problema. ¿No sería bastante fácil, simplemente introduce una regla que dice position propiedades en un :stuck selector debe ser ignorado? (una regla para los fabricantes de los navegadores quiero decir, similares a las reglas acerca de cómo left tiene prioridad sobre right etc))
    • No es sólo la posición… imaginar un :stuck que cambia el top valor de 0 a 300px, a continuación, desplácese hacia abajo 150px… en caso de que se cumpla o no? O pensar acerca de un elemento con position: sticky y bottom: 0 donde el :stuck tal vez los cambios font-size y por lo tanto los elementos de tamaño (por lo tanto cambiar el momento en que debe palo)…
    • Consulte github.com/w3c/csswg-drafts/issues/1660 donde la propuesta es tener JS eventos para saber cuando algo se queda pegado/unstuck. Que no debe tener los problemas que un pseudo-selector presenta.
    • Yo estoy a favor de eso.
    • Creo que la misma circular problemas puede ser hecho con muchos de los ya existentes pseudo-clases (por ejemplo, a :hover cambio de ancho y :no(:hover) cambiar de nuevo). Me encantaría :pegado pseudo-clase y creo que el desarrollador debe ser responsable por no tener la circular problemas en su código.
    • Lisý: Sí, el razonamiento dado por los fabricantes de los navegadores es que no quieren cometer el mismo error. Estoy de acuerdo en que el autor debe ser responsable, pero los vendedores aún tienen para protegerse de autor errores.
    • Bueno… realmente no entiendo esto como error, es como decir while ciclo está mal diseñado porque permite bucle sin fin 🙂 Pero gracias por aclarar esto 😉
    • Las soluciones con JS por ahora de esto?
    • Aquí hay un post en el blog con un hack que se puede utilizar en el ínterin: developers.google.com/web/updates/2017/09/sticky-headers
    • Yo aconsejo vivamente contra el hack anterior. El apoyo mundial para IntersectionObserver es baja. Si usted no tiene anidada de desplazamiento, es mejor que use getClientBoundingRect() y desplácese a la escucha.
    • si ie4 podría apoyar :hover{display:none;} estoy seguro de que los navegadores modernos no explotar con :stuck{position:static;}
    • Has visto qué :hover{display:none;} parece? En la mayoría de los navegadores de los elementos que acaban de parpadeo en y fuera de la existencia tan rápido como su pantalla se pueden actualizar. Y el resto del diseño se ve afectado como es el caso. No creo que los navegadores quiero presentar a más situaciones como esa.
    • Sí, se ve buggy. La posibilidad de crear un cochecito de comportamiento con una elaborada técnica no es una razón para deshabilitar un (muy necesario) característica de todos juntos. Por ejemplo, ser capaz de entrar en <div> (en lugar de <li>) dentro de <ul> no es una razón para descartar las listas de todos juntos, ¿no?
    • Mal marcado y cíclico de las dependencias en las CSS son dos clases diferentes de problemas completamente.
    • Es sólo una parábola. Aquí otra – debemos cancelar bucles en JS porque uno puede hacer bucle sin fin? El elemento de parpadeo como un loco cuando se hace :stuck{position:static} – que así sea. No debería de suceder de todos modos, la gente sólo quiere el :pegado a establecer box-shadow o el cambio de algún elemento, mediante la comprobación de .is(':stuck') en scroll evento.
    • El bucle infinito de ejemplo que tanto @oriadam y MarekLisý han mencionado parece una buena comparación para mí. No entiendo por qué la CSS debe impedir que los desarrolladores escribir código malo. ¿Hay alguna razón técnica que lo hace imposible o excesivamente costoso de implementar esta característica? El hecho de que los desarrolladores cometen errores con los que sin duda, no puede ser la razón.
    • puede :stuck simplemente ignorar posicional propiedades? en su mayoría sólo se utiliza para añadir un puto sombra de todos modos…

  2. 4

    En algunos casos, un simple IntersectionObserver puede hacer el truco, si la situación lo permite, para que se pegue a un píxel o dos fuera de su contenedor raíz, más que correctamente alineadas contra. De esa manera cuando se encuentra justo más allá del borde, el observador incendios y estamos fuera de funcionamiento.

    const observer = new IntersectionObserver( 
      ([e]) => e.target.toggleAttribute('stuck', e.intersectionRatio < 1),
      {threshold: [1]}
    );
    
    observer.observe(document.querySelector('nav'));

    Pegar el elemento que acaba de salir de su contenedor con top: -2px, y como objetivo, a través de la stuck atributo…

    nav {
      background: magenta;
      height: 80px;
      position: sticky;
      top: -2px;
    }
    nav[stuck] {
      box-shadow: 0 0 16px black;
    }

    Ejemplo aquí: https://codepen.io/anon/pen/vqyQEK

  3. 2

    No es realmente un fan de usar js hacks para el estilo de cosas (es decir getBoudingClientRect, desplácese a la escucha, cambiar el tamaño de la escucha), pero esto es lo que actualmente estoy resolver el problema. Esta solución va a tener problemas con las páginas que tienen minimizable/maximizable contenido (<datos>), o anidada de desplazamiento, o en realidad cualquier curva de bolas de ningún tipo. Que siendo dicho, es una solución simple para cuando el problema es más sencillo así.

    let lowestKnownOffset: number = -1;
    window.addEventListener("resize", () => lowestKnownOffset = -1);
    
    const $Title = document.getElementById("Title");
    let requestedFrame: number;
    window.addEventListener("scroll", (event) => {
        if (requestedFrame) { return; }
        requestedFrame = requestAnimationFrame(() => {
            //if it's sticky to top, the offset will bottom out at its natural page offset
            if (lowestKnownOffset === -1) { lowestKnownOffset = $Title.offsetTop; }
            lowestKnownOffset = Math.min(lowestKnownOffset, $Title.offsetTop);
            //this condition assumes that $Title is the only sticky element and it sticks at top: 0px
            //if there are multiple elements, this can be updated to choose whichever one it furthest down on the page as the sticky one
            if (window.scrollY >= lowestKnownOffset) {
                $Title.classList.add("--stuck");
            } else {
                $Title.classList.remove("--stuck");
            }
            requestedFrame = undefined;
        });
    })
  4. 1

    Alguien en el blog de los Desarrolladores de Google afirma haber encontrado un performativo basado en JavaScript solución con un IntersectionObserver.

    Código correspondiente bit de aquí:

    /**
     * Sets up an intersection observer to notify when elements with the class
     * `.sticky_sentinel--top` become visible/invisible at the top of the container.
     * @param {!Element} container
     */
    function observeHeaders(container) {
      const observer = new IntersectionObserver((records, observer) => {
        for (const record of records) {
          const targetInfo = record.boundingClientRect;
          const stickyTarget = record.target.parentElement.querySelector('.sticky');
          const rootBoundsInfo = record.rootBounds;
    
          //Started sticking.
          if (targetInfo.bottom < rootBoundsInfo.top) {
            fireEvent(true, stickyTarget);
          }
    
          //Stopped sticking.
          if (targetInfo.bottom >= rootBoundsInfo.top &&
              targetInfo.bottom < rootBoundsInfo.bottom) {
           fireEvent(false, stickyTarget);
          }
        }
      }, {threshold: [0], root: container});
    
      //Add the top sentinels to each section and attach an observer.
      const sentinels = addSentinels(container, 'sticky_sentinel--top');
      sentinels.forEach(el => observer.observe(el));
    }

    No he replicado a mí mismo, pero tal vez ayude a alguien se tropieza con esta pregunta.

Dejar respuesta

Please enter your comment!
Please enter your name here