View in English

  • Global Nav Open Menu Global Nav Close Menu
  • Apple Developer
Search
Cancel
  • Apple Developer
  • News
  • Discover
  • Design
  • Develop
  • Distribute
  • Support
  • Account
Only search within “”

Quick Links

5 Quick Links

Videos

Abrir menú Cerrar menú
  • Colecciones
  • Temas
  • Todos los videos
  • Información

Volver a WWDC25

  • Información
  • Resumen
  • Transcripción
  • Código
  • Novedades de Safari y WebKit

    Descubre cómo las últimas tecnologías web de Safari y WebKit pueden ayudarte a crear experiencias increíbles. Destacaremos distintas funcionalidades de CSS y su funcionamiento, incluida la animación basada en desplazamiento, las transiciones de vista entre documentos y el posicionamiento de anclaje. También exploraremos la compatibilidad con contenido multimedia nuevo en audio, video, imágenes e íconos.

    Capítulos

    • 0:00 - Introducción
    • 1:46 - Animación
    • 19:01 - Diseño
    • 29:05 - Efectos visuales
    • 38:22 - Medios de comunicación

    Recursos

    • Can I use
    • Safari Technology Preview
    • Submit feedback
    • Web Speech API - Web APIs | MDN
    • WebKit Open Source Project
    • WebKit.org – Bug tracking for WebKit open source project
      • Video HD
      • Video SD

    Videos relacionados

    WWDC25

    • Conoce WebKit para SwiftUI
    • Desbloquear la informática con GPU usando WebGPU
    • Más información sobre el Declarative Web Push
    • Novedades de la web espacial
    • Verificar documentos de identidad en la web
  • Buscar este video…

    Hola, soy Saron Yitbarek, evangelista de tecnologías web en el equipo de Safari y WebKit. Desde la WWDC del año pasado, trabajamos para ofrecerte nuevas tecnologías web, algunas que solicitaste y otras que te encantarán. Nos preocupamos por ti y por la web, y queremos empoderarte como diseñador o desarrollador web, para que sea más fácil hacer realidad tus ideas. El objetivo es simple: ayudarte a crear una experiencia confiable, compatible y que priorice la privacidad de tus usuarios. Es por eso que hoy quiero anunciar la nueva tecnología web que llegará a Safari este año. Hay muchas funcionalidades interesantes. Dedicamos tiempo y atención a mejorar la interoperabilidad y a llenar los vacíos en las funcionalidades pasadas. En esta sesión, te enseñaré algunas de mis funcionalidades favoritas y te mostraré algunas de las áreas que hemos mejorado. Las funcionalidades se dividirán en cuatro categorías. En animación, te enseñaré a usar animaciones de desplazamiento y transiciones entre vistas de documentos. Diseño tiene que ver con el mundo del posicionamiento de anclaje. En efectos visuales, abarcaremos el background-clip, la nueva función de forma y el text-wrap: pretty. Seguiré todo ese CSS con medios, donde explicaré el soporte de íconos SVG, imágenes y mejoras en los formatos de medios existentes. Empecemos con animación. La animación mejora las experiencias en línea que creas, agregando algo de emoción y un toque de fantasía a la página. Te mostraré un ejemplo de lo que quiero decir. Digamos que estoy rediseñando el sitio web de mi empresa de educación en línea, A-School of Code. Quiero que sea práctico y algo divertido. Con las últimas funcionalidades, puedo lograrlo usando solo CSS. Déjame mostrarte cómo podría lucir mi sitio final. Aquí está el sitio de una escuela en línea que promete enseñarte habilidades técnicas. Muestro la lista de temas que abarcamos en esta linda tabla, los nombres de las empresas que contrataron a mis increíbles estudiantes, leer reseñas sobre los cursos y el plan de estudios y, finalmente, ves dos opciones de programas que puedes elegir. Hay algunas cosas que mejoran este sitio. Una que tal vez llamó tu atención es la animación. Estas son animaciones de desplazamiento, ahora disponibles en Safari 19. Las animaciones CSS son parte de la web desde que Apple las introdujo a WebKit en 2007. Vincular esa animación al comportamiento del usuario requiere JavaScript. JavaScript es un lenguaje poderoso que hace mucho por la web, pero prescindir de su uso, ayudará a tus usuarios a obtener un mejor rendimiento y duración de la batería. Esta animación permite omitir el uso de JavaScript y vincular tu animación al desplazamiento usando solo CSS. Veamos cómo funciona todo. Para comprender este tipo de animaciones, hay un concepto clave que debes conocer: líneas de tiempo. La línea por defecto para la web está basada en el tiempo. Es decir que la animación avanza con el tiempo.

    A medida que pasan los segundos, la animación de mi barra se mueve con ellos. Pero la animación basada en desplazamiento necesita dos líneas de tiempo. La primera es la de desplazamiento. En mi sitio web, usé la línea de tiempo scroll() para crear la barra de progreso abajo de la página. Este es un ejemplo artificial. Probablemente no necesitarías una barra como esta porque ya tienes barras de desplazamiento. Pero es una forma sencilla de mostrar la animación de desplazamiento en acción. Veamos cómo crearla. Antes de trabajar en mi barra, necesito considerar algo importante: la accesibilidad. Este tipo de animación introduce movimiento en mi sitio web y algunos pueden preferir menos movimiento: esto se indica en la configuración de accesibilidad. Quiero respetar eso para no causar incomodidad accidentalmente. Sentirse incómodo con el movimiento es común y tiene que ver con varios factores: experiencia, genética, fatiga y, en algunos casos, trastornos vestibulares. Los síntomas pueden incluir náuseas, mareos, dolores de cabeza y otras molestias físicas.

    Como desarrolladores, hay distintos tipos de movimiento que agregamos a nuestros sitios web y apps que podrían provocar este tipo de molestias: escalar objetos grandes, acercar o alejar, movimiento de objetos a diferentes velocidades, técnicas que simulan efectos tridimensionales o movimiento periférico, como un movimiento constante fuera del área de enfoque prevista del usuario. Esta lista no lo cubre todo, pero es un buen punto de partida de cosas a considerar. ¿Tu sitio tiene estos efectos? En mi caso, mi animación es una barra de progreso simple, un tipo de movimiento bastante seguro, pequeño y común en la web. Así que no creo que deba preocuparme por provocar malestares con esta animación en particular. Pero cada vez que agreguemos movimiento a la página, debemos detenernos y considerar qué impacto tendrá en las personas. Veamos la barra de desplazamiento. Comenzaré con CSS. Agregaré la barra de desplazamiento como un pseudoelemento en mi pie de página. Empezará en la esquina inferior izquierda y permanecerá en la parte inferior a medida que me desplace.

    Después, crearé la animación con fotogramas clave usando el CSS que conocemos y amamos. Así, mi navegador escalará la barra de progreso para que aumente en mi eje X, creando el efecto de una barra que crece de izquierda a derecha. Apenas estoy sentando las bases de mi animación basada en desplazamiento. Necesito algo más para completar esas bases: agregar animación a mi barra de progreso. Puedo hacerlo aquí. Ahora, el desplazamiento. Quiero que la barra crezca de izquierda a derecha solo al desplazarme. Para hacerlo, debo darle a mi barra una nueva línea de tiempo de animación. Voy a agregar una scroll() a mi CSS, reemplazando la línea predeterminada. Ten en cuenta que para que esto funcione, la línea de tiempo de animación va después de la propiedad. Y así, conecté mi animación a mi línea de tiempo y creé una barra de progreso solo con unas líneas de CSS. No se necesita JavaScript. Veamos un ejemplo más práctico. Quiero una animación que no se base solo en el desplazamiento, sino en cuándo aparecen los elementos. Veamos este ejemplo. Los bloques giran antes de crear la tabla. Sucede cuando me desplazo, pero existe otro factor. La animación solo ocurre dentro del cuadro azul. Comienza abajo, cuando los bloques entraron en la ventana gráfica, y dejan de girar a la mitad de la pantalla, en la parte superior de mi cuadro azul. Para tener en cuenta la ventana gráfica, se necesita la línea de tiempo view(). Revisemos algunos códigos para ver cómo funciona.

    Comenzaré con html. Esta es mi lista de temas con algunas clases que usaré en mi CSS. Después, convertiré mi lista en bloques amarillos para que combinen con mi sitio web usando estilos CSS básicos. Ya que tengo mi base, puedo empezar con mi animación de desplazamiento. Lo primero es decidir qué animación quiero adjuntar al desplazamiento. Para mi sitio web, tengo tres animaciones que ocurren a la vez y necesito aplicar estas animaciones a cada bloque. La primera hace que suban y se ensamblen desde la izquierda. La segunda hace que suban y se ensamblen desde el centro. Y la tercera hace que suban desde la derecha.

    El código no es nada nuevo todavía. Sigue siendo una animación CSS clásica.

    Ahora, voy a incorporar las animaciones de desplazamiento. Pero primero, voy a detenerme y pensar en la accesibilidad de la animación. Si lo pienso, girar es uno de los desencadenantes más comunes. Pero eso se refiere más bien a un efecto que podría causar desorientación. Dado que solo son pocos elementos y es una animación pequeña, no creo que corra el riesgo de resultar inaccesible, por lo que puedo volver a mi código. Ahora voy a agregar mi código de animación a mi CSS, aplicando la animación izquierda a mis bloques izquierdos, la central a los de en medio y la derecha a mis bloques derechos. Como quiero que los elementos conserven sus estilos de animación, también agregaré animation-fill-mode: both. Y ahora finalmente llego a la parte del código del desplazamiento. Hay dos líneas de código que necesito para que funcione. La primera es mi nueva línea view(). La agregaré aquí. Y la segunda, que se llama animation-range. El rango de animación le dice a mi navegador dónde comenzar y finalizar la animación según su línea. Elegí la línea view(), por lo que mi rango reflejará dónde están mis elementos en la ventana gráfica. Por defecto, el valor va del 0 al 100%. Esto establece el inicio en 0%, el momento en el que el elemento ingresa por primera vez a la ventana gráfica, y finaliza en 100%, que es cuando el elemento sale completamente. Veamos mi animación en acción con estos valores por defecto. Está bastante cerca de lo que quiero, pero no del todo. Cuando uso animaciones de desplazamiento, especialmente para un sitio web donde muestro información, debemos recordar la experiencia de usuario. Las animaciones son divertidas y pueden hacer que mi sitio destaque, pero aún debe ser legible. La animación no debe interferir con la funcionalidad. En este caso, significa que debo tener en cuenta cuánto dura mi animación. No quiero que dure el 100%, porque eso significa que los bloques se moverán todo el tiempo, lo que dificultará su lectura.

    Me gustaría una animación corta, algo que llame la atención, luego quiero que los bloques se queden en su lugar para que se puedan leer. A la mitad de la página parece un buen lugar para intentarlo. Así podría ser divertido y al mismo tiempo darles a mis usuarios suficiente tiempo para leer. Entonces voy a cambiar mi rango a 0% y 50%. Así la animación terminará cuando los elementos estén a la mitad de la página, lo que limitará el tiempo de movimiento. Y si me desplazo hacia arriba, los bloques comenzarán a desmoronarse en el punto del 50% y se disolverán completamente en el 0%. El rango permite controlar más cosas, como dónde se encuentra el 0%. Para ver cuáles son tus opciones y cómo funcionan, consulta los diferentes valores, juega y explora. Estas nuevas líneas de tiempo son avanzadas y, combinadas con la animación, pueden crear experiencias increíbles para tus usuarios. Esa es la animación de desplazamiento en WebKit. La siguiente animación que me entusiasma mostrarles ocupa toda la página. Son transiciones de vista entre documentos, incluidas en diciembre en Safari 18.2. Son una extensión de las transiciones de vista, agregadas en Safari 18.0. Las transiciones de vista entre documentos permiten crear transiciones fluidas, pasando de algo como esto a algo más uniforme, como este desvanecido, sin necesidad de JavaScript. Para este efecto solo necesitas una línea de CSS. Cuando haces clic en ese elemento sin una transición, el navegador remodela la página, borrándola y cargando una nueva. Lo bueno de las transiciones es que, como se toman instantáneas antes y después del cambio de página y se crea una transición entre ellas, la experiencia resulta agradable y fluida. Me encanta cómo se ve. Así es como funciona. En tu archivo CSS, agrega la regla @view-transition y configura la propiedad como automática. Eso es todo. Pero antes de enviarlo, necesitamos hacer algo más. Dado que agregamos movimiento, debemos detenernos a considerar si existe algún problema de accesibilidad. La animación de desvanecido es bastante sutil y se considera una de las más seguras para las personas que requieren un movimiento reducido. Todo está listo para el envío. Digamos que, en lugar del desvanecido, prefiero un deslizamiento. Al hacer clic en un elemento, quiero que la página actual se deslice hacia afuera y entre la nueva. Te mostraré lo que quiero decir, pero debo advertirte que si eres sensible al movimiento, esto puede incomodarte. Te avisaré cuando termine.

    Estoy creando un efecto de deslizamiento y me gusta cómo se ve: es una mejora con respecto al desvanecido. Pero primero, pensemos en qué impacto tendrá en mis usuarios. La animación ha concluido.

    ¿Es este efecto el tipo de animación que podría provocar molestias por el movimiento? Si hablamos de animaciones, es muy grande. No solo se mueve una palabra o elemento, se mueven dos páginas. Como no sé si esta animación es segura, y dado que no es fundamental para la experiencia, es mejor colocarla en una consulta de medios de movimiento reducido. Hagámoslo ahora.

    Esta es mi consulta de medios. Le dice al navegador que ejecute mi transición si no se prefieren movimientos reducidos. Ahora debo codificar mi efecto deslizante. Usaré animaciones CSS para crear fotogramas clave que describan lo que deben hacer las páginas. Quiero que una página salga y la otra entre con efectos deslizantes.

    Ahora, para usar estas animaciones, debo tener un objetivo. Por defecto, navigation: auto movió todo lo de la página. Pero en realidad no quiero que todo en mi página cambie. No quiero que la barra se mueva. Y tampoco quiero que el pie de página se mueva. Entonces voy a asignar todo lo que quiero mover a un ID, uno en cada página. Se llamará “school-info”. Necesito asignar un nombre de transición para usarlo más adelante. Al implementar transiciones de vista, obtenemos un montón de pseudoelementos. Voy a usar dos de ellos.

    View-transition-old y view-transition-new. View-transition-old representa una instantánea del sitio antes de que ocurra la transición y view-transition-new representa una instantánea después. Para usarlos, necesito otorgar un argumento. Aquí es donde uso mi view-transition-name “main-body” y lo otorgo a ambas, ya que abarca la parte de la página que quiero que se mueva. Luego, pondré el nombre de mis fotogramas clave en animation-name. Eso es todo. Veamos cómo luce. Si eres sensible al movimiento, aparta la mirada por un segundo.

    Genial. El navegador no se mueve mientras el resto cambia con un clic.

    Animación completa. Lo que me gusta de las transiciones de vista entre documentos es que son una mejora. No son obligatorias y no cambian la funcionalidad de mi sitio web. Es una buena adición si el navegador lo admite y el usuario lo desea, y no hay problema si no lo hace. Al implementar este tipo de transiciones en tu app o sitio web, ten en cuenta que las páginas entre las que estás realizando la transición deben tener el mismo origen. Podrás pasar de example.com a example.com/cohorts sin problemas. Pero no de example.com a un subdominio diferente. Esto garantiza la seguridad y privacidad del usuario. No querrás que una página maliciosa manipule animaciones dirigidas a tu sitio web. Ahora veamos lo nuevo en diseño: el posicionamiento de anclaje, nuevo en Safari próximamente. Este, cuando se construye a partir de la API de ventana emergente existente, es un módulo CSS que facilita la creación de información sobre herramientas y el posicionamiento exacto de menús, así como su respuesta adecuada a los cambios en la ventana gráfica. Veamos cómo. Quiero una experiencia fluida para mis usuarios. Quiero que vean su foto de perfil en el navegador al iniciar sesión. Cuando hagan clic en su foto, deberá aparecer un menú, una funcionalidad común en apps web. Empezaré a desarrollar esto con html.

    Está es mi HTML de la barra de navegación con la foto de perfil. Y aquí está el menú que quiero mostrar cuando haga clic en la foto. Agregaré algo de estilo y veré cómo queda. Quitemos el resto de la página del camino. Estamos progresando: tengo un navegador lindo y un menú atractivo. No quiero que mi menú siempre esté visible. El menú debe aparecer cuando haga clic en el ícono del perfil y desaparecer cuando vuelva a hacer clic en él. Y no quiero que aparezca en esa esquina izquierda, quiero que esté anclado a mi foto de perfil. Para resolverlo, primero necesito usar la API de ventana emergente. Empezaré por agregar el atributo popover a lo que quiero que aparezca, en este caso, mi menú de perfil. Luego, le daré un ID. A continuación, necesito algo que pueda seleccionar, así que voy a asignar un botón a mi imagen. Tengo que asegurarme de que este botón y su menú sean accesibles para quienes usan tecnologías de asistencia. Entonces voy a agregar el atributo aria-haspopup para indicar que, al hacer clic, este botón mostrará al usuario un menú. Por último, debo establecer un atributo popovertarget en el mismo valor que el ID del elemento popover. ¡Excelente! Ahora, si hago clic en mi foto, aparece mi ventana emergente, y si hago clic fuera de ella, desaparece. Pero aparece en la esquina izquierda de mi página y quiero que esté anclado a la foto de perfil, justo debajo. Aquí presentaré el posicionamiento de anclaje.

    Este permite anclar un elemento y posicionar ese elemento en función de dónde se encuentre ese anclaje. Así es como funciona. Comenzaré por decidir mi ancla y darle un nombre a través de la propiedad anchor-name. En este caso, mi ancla es mi botón de perfil, es decir que la posición del menú depende de la del botón. Así que voy a nombrar mi ancla profile-button. Este debe iniciar con dos guiones, pues es una cadena arbitraria definida por el usuario. Ahora, necesito ir a mi menú y conectarlo al ancla que acabo de nombrar. En el posicionamiento de ancla, mi menú se conoce como mi objetivo y necesito darle cierta información. Primero voy a conectarlo a mi ancla estableciendo la propiedad position-anchor al nombre de mi ancla, que es —profile-button. Escribiré —profile-button aquí. Por último, tengo que decirle al menú dónde se va a posicionar. Hay dos maneras de hacerlo. La primera es el área de posición. Exploremos qué es esto.

    Mi ancla se encuentra en el medio de nueve cuadrados. Tengo tres columnas: izquierda, centro y derecha. Y tengo tres filas: arriba, centro y abajo. Para colocar mi objetivo arriba y a la derecha de mi ancla, debo establecerlo así en el área de posición, lo que describe de forma intuitiva dónde quiero mi menú en relación con mi ancla. Y si lo quiero debajo de la foto de perfil, está abajo y al centro de mi cuadrícula, así que escribiremos: bottom center.

    Esto se verá así. Hm, bastante cerca. Pero no es lo que estoy buscando. Está abajo como quería, pero como el menú es más ancho que mi botón de perfil, no cabe en mi cuadrícula. Lo que quiero es alinear el lado izquierdo del menú con el lado izquierdo de mi foto de perfil. Para ello usaremos un valor diferente para position-area: bottom span-right. Eso hará que comience donde comienza esa cuadrícula central, pero que se extienda hacia la derecha.

    Y así, mi menú y mi foto de perfil quedan lindos y alineados. Se ve genial en esta pantalla, pero ¿qué sucede en otros dispositivos cuando la ventana es más estrecha? Para averiguarlo, puedo ir al modo de diseño responsivo en Safari. Puedo activarlo yendo a Configuración, luego a Avanzado y marcando Mostrar funciones para desarrolladores web. Aparecerá la opción “Desarrollar”, donde verás que arroja algo. Es una funcionalidad solicitada: ajustes preestablecidos de la ventana gráfica. Ahora, puedes seleccionar uno de varios tamaños de ventana gráfica para acelerar tus pruebas y desarrollo. Me encanta poder cambiar la configuración de la ventana gráfica con solo un clic, esto facilita probar los modos vertical y horizontal. Quiero que mi menú responda a los cambios de la ventana gráfica sin JavaScript. Mi menú está alineado a la izquierda. Al estrecharse el ancho, quiero que se mueva y se alinee con el lado derecho de mi botón de perfil. La magia del posicionamiento de anclaje es que permite manejar fácilmente esta situación. Usa una propiedad llamada position-try y hace prácticamente lo que dice. Permite establecer posiciones para probar si no tiene espacio. Como quiero que mi menú se extienda hacia la izquierda, establezco posición-try en alcance inferior derecho. Pero position-try también permite un valor diferente. En lugar de indicar dónde quiero que esté mi menú, puedo establecer un valor relativo a mi área de posición. Uno de ellos es “flip-inline”. Este indica que, sin importar la posición original del elemento, solo gíralo en la dirección en línea. Y puedes girar en la dirección del bloque con “flip-block”. Es una forma más intuitiva de describir lo que deseas que suceda. Veámoslo en acción. En mi modo adaptable, veo que en el iPad de 13 pulgadas, mi menú está alineado a la izquierda. Pero al cambiar la orientación, se activa position-try y el menú se alinea a la derecha, lo que me da un menú adaptable: lo que busco.

    Me enorgullece que el equipo de WebKit propusiera el área de posición y trabajara con los entes normativos para ofrecer una forma intuitiva de trabajar con el posicionamiento. Pero hay otro enfoque del posicionamiento de anclaje que quiero mostrarles, la función anchor(), una herramienta bastante poderosa. Con la función anchor(), en lugar de colocar tu elemento en una cuadrícula, estás alineando los lados de tu elemento con los lados de tu ancla. Primero debo asegurarme de establecer la posición en absoluta. Después, miraré arriba de mi menú. Usaré anchor(bottom) para alinearlo con la parte inferior de mi ancla. Después, miraré a la izquierda de mi menú. Voy a establecer ese valor en anchor(left) para que se alinee con el lado izquierdo.

    Ese fue un ejemplo bastante simple, pero ¿qué pasa si quiero alinear el menú con la foto de esta forma? Necesito tener en cuenta ese espacio. Podría usar position-area y agregar un margen izquierdo, o usar la función anchor() y agregar la función calc(), así. Aquí, estoy combinando mi función de anclaje con la función de cálculo y la unidad em, eso deslizará mi menú. En la mayoría de los casos, position-area es una manera excelente e intuitiva de abordar el posicionamiento y, para hacer algo más complejo, como animar de una posición a otra o usar múltiples anclas, recurre a la función anchor(). Sin importar lo que elijas, el posicionamiento de anclaje facilita la creación de un posicionamiento adaptable solo con CSS. Por último, exploraremos algunas formas nuevas de crear excelentes efectos visuales. El primero lleva los bordes a otro nivel. Hace casi 15 años, Apple lanzó background-clip: text que permite tomar texto y, en lugar de rellenarlo con un color, puedes rellenarlo con un degradado o una imagen. Como este degradado de amarillo a naranja. Mi logotipo es sencillo. Son solo palabras con una fuente básica, así que solo usaré texto en vez de una imagen. Así puedo darle estilo con CSS. Mi logo es un elemento h1 y diseñé mis h1 en blanco, así inicio con texto blanco. Para agregar este efecto, establezco mi imagen de fondo en ese sutil degradado de amarillo a naranja que va hacia la parte inferior derecha. Y obtengo este degradado en mi texto. Luego, estableceré mi propiedad background-clip en texto. Eso regresa el texto blanco. No es lo que quiero. Hay algo más que necesito hacer. Necesito anular mi estilo h1 y hacer que el color del logotipo sea transparente, para que desaparezca y, cuando lo hago, mi degradado emerge. Pero no solo puedes usar degradados: también puedes usar imágenes. Como esta imagen de fondo de hojas de otoño. Background-clip: text introdujo nuevas capacidades visuales al texto y ahora hacemos lo mismo con los bordes. Te mostraré cómo funciona. Mis botones tienen un borde blanco grueso, pero para mi botón principal quiero hacer algo diferente. Quiero usar mi valor background-clip para agregar algo de brillo y darle a mi borde un degradado. Primero agregaré ese sutil degradado de amarillo a naranja que usé antes como imagen de fondo y obtengo un degradado en el fondo de mi botón. Después, agregaré mi nuevo background-clip con el valor border-area y vuelvo a tener un fondo negro y un borde blanco. Tengo el mismo problema que con el texto: el color del borde cambió, pero está oculto detrás del borde blanco del estilo de mi botón. Necesito volver mi borde transparente para que aparezca el degradado. Lo agregaré aquí y veré qué pasa… Interesante. Se ve el degradado, pero hay un nuevo problema. Parece que el degradado se repite. Ocupa el ancho de mi botón, pero solo llega hasta el interior de mis bordes, luego reinicia el degradado en los bordes. Para solucionar esto, necesito extender el fondo hasta el exterior del borde. Puedo hacerlo configurando background-origin en borde del cuadro. Eso se ve genial.

    También puedes usar una abreviatura que no requiera declarar la imagen de fondo. Listo, un degradado lindo que usa mi background-clip y el valor del área del borde. Puedes hacer muchas cosas con un borde. Entre seleccionar imágenes y elegir degradados, puedes hacer cosas como este círculo de progreso, esta señal de advertencia y esta hermosa fotografía de doble borde. Y este es background-clip: border-area, más opciones para ayudarte a embellecer tu contenido y hacer que tus sitios y apps web destaquen. Para ver demostraciones y más detalles sobre background-clip, consulta nuestra publicación en webkit.org. Las mejoras en los efectos visuales no se limitan al borde, incluyen formas versátiles de creación en CSS. Ahora, me complace explicar todo lo de la función shape(), ahora compatible con Safari 18.4. Las formas se usan de diferentes maneras en nuestras apps y sitios web, y yo las uso para mi sitio web A School of Code. En mi sección de testimonios, me gusta usar estas flechas curvas como fondo para mis reseñas. Son formas CSS configuradas en mi clip-path, como un elemento estético. Antes de la función shape(), usaba path para que esto sucediera. La función path es una herramienta poderosa y versátil que permite usar todo tipo de puntos y curvas para dibujar varias formas. ¿Pero qué sucede cuando cambia el ancho de mi ventana gráfica? Para ilustrarlo, voy a aislar las tres flechas y mostrarte cómo responden. A medida que cambio el tamaño, notarás que la punta y la curva se cortan. No se redimensionan con mi ventana. Quiero algo más adaptable. Pero este es el problema, no quiero que cada línea y cada curva en mi forma cambien con mi ventana. Solo quiero que cambien algunas partes. Quiero que la curva mantenga su forma y que la punta mantenga su ángulo, pero que la longitud y la altura escalen según la ventana. Si uso mi función shape(), a medida que la ventana de mi demostración se hace más pequeña, el ancho de mis formas también lo hacen. Eso quiero. Pero el ángulo de la punta y la forma de la curva se mantienen estables e invariables a medida que se vuelven más estrechas. Esto es lo que me encanta de la función shape(): te brinda este tipo de control granular, permitiéndote elegir qué permanece estático y qué responde a los cambios. Déjame mostrarte cómo se ve ese código. Como ves, estoy usando diferentes unidades, como la altura de consulta del contenedor y porcentajes. shape() puede tomar todas las unidades CSS. Incluso uso la función calc. Poder crear valores adaptables y usar varias unidades me permite controlar diferentes partes de mi forma, lo que me brinda la capacidad de respuesta exacta que estoy buscando. Gracias a shape(), podemos crear formas más flexibles y con mayor capacidad de respuesta. Pero no solo estamos facilitando el uso de shapes(). También mejoramos el texto, con nuevas funcionalidades tipográficas como text-wrap: pretty, disponible en Safari 19.

    Si miras este texto, está bien, pero hay algunas cosas que lo hacen un poco más difícil de leer y menos agradable a la vista. La primera son las líneas cortas con solo una palabra al final de sus párrafos. Distrae visualmente y hace que el espacio entre los párrafos parezca más grande de lo que es.

    La segunda es la silabación. No hay nada malo con la silabación, pero queremos usarla con moderación. No queremos tres oraciones con guion seguidas. La tercera es la forma general que se crea al margen de los párrafos. Los márgenes deben tener aproximadamente la misma longitud. Este tiene irregularidades y llama la atención visualmente.

    Los efectos del text-wrap: pretty son sutiles, pero intencionales.

    Aquí, las palabras aisladas, los guiones y los márgenes feos desaparecieron.

    Así es como funciona. Sin text-wrap: pretty, el navegador maximiza cada línea, usando todo el espacio hasta el final. Pero al agregar text-wrap:pretty, le dices que apunte a un área diferente, en algún lugar cerca de esa línea verde: esa es nuestra longitud de línea ideal. Pero hay cierto margen de maniobra, representado por el área entre mis líneas púrpura y roja. Todo lo que hay allí es válido. También se asegurará de que la última línea no sea tan corta e intentará no separar palabras con guion, optando por moverlas a la siguiente línea. El código es simple. Aplica text-wrap:pretty a cualquier elemento: párrafos, titulares y más, especialmente si ves algunas líneas finales cortas, un montón de guiones o un margen feo, y observa cómo afecta tu texto. Lo bueno de text-wrap:pretty es que también es una mejora. Agrégalo a tu texto y, si el navegador lo admite, hará más agradable tu texto. Y si el navegador del usuario no lo admite, o si decide ajustar solo las últimas líneas, el usuario aún tendrá una buena experiencia. No hay pena sin delito.

    Ya vimos muchas funcionalidades de CSS, la mayoría sobre diseño. Ahora veamos los medios. El primero es pequeño, pero poderoso. Te escuchamos y nos emociona ofrecer íconos SVG, que llegarán a Safari próximamente. Los íconos SVG hacen más que servir como faviconos. Se pueden ver en marcadores, en toda la página de inicio de Safari, cuando se agregan al dock y más. El uso de SVG como favicono en navegadores modernos permite a Safari generar íconos mejor adaptados al contexto. El archivo suele ser menos pesado que el de los png que se usan en los faviconos. Hay otro tipo de medios estáticos que me entusiasma anunciar. Llegan a WebKit y Safari: imágenes HDR. HDR, o de alto rango dinámico, hace que tus medios sean más vibrantes que las típicas fotos y videos SDR que acostumbramos ver en la web. Admitimos videos HDR durante los últimos cinco años, desde Safari 14.0, y ahora agregamos imágenes. Para ilustrar las diferencias entre HDR y SDR, te mostraré una simulación de los dos. La imagen de la izquierda es una SDR (rango dinámico estándar) y puede venir en muchos formatos diferentes. No puedo mostrarte cómo se ve el HDR en este video, así que creé la imagen de la derecha que simula algunas de las diferencias. Los tonos son más profundos, la gama más amplia y los colores más brillantes. Ver estas diferencias en una imagen HDR real es sorprendente. Existen algunas razones técnicas para esas diferencias, una es la cantidad de datos que contiene cada imagen. SDR es de 8 bits y HDR es de 10 a 16. Esos bits adicionales le dan al HDR más datos para mostrar. SDR suele vivir en el espacio de color sRGB, mientras que HDR usa espacios más amplios como P3. Y los formatos también son diferentes. SDR está disponible en varios formatos, como JPEG, mientras que HDR está disponible en esos formatos, más HEIC y AVIF. Pero mostrar HDR en el mundo real requiere cierta reflexión e intención. Al fin y al cabo, muchos de los medios no serán HDR por un tiempo. Así que debemos considerar cómo mostrar imágenes HDR y SDR en paralelo, y cómo se verán. Debido al rango dinámico, las imágenes HDR suelen verse mucho más brillantes que las SDR. ¿Ves cómo se destaca el pájaro azul? En el contexto de resultados de búsqueda o galerías, esto puede distraer al usuario y crear una mala experiencia. Como desarrolladores, queremos darte más control para administrar esta discrepancia. Para ello, hay una propiedad CSS, llamada: dynamic-range-limit. Por defecto, el valor de dynamic-range-limit es “sin límite”. Permite que las imágenes y los videos HDR se vean tal como son, incluso si son más brillantes que lo demás. O puedes usar el dynamic-range-limit: estándar para que el navegador renderice imágenes o videos HDR como si fueran SDR. Otra opción es dynamic-range-limit: restringido. El navegador usa el rango dinámico adicional de la imagen HDR para que se vea fantástica, pero que lo haga de una manera que no destaque. Esto permite ver cómodamente contenido SDR y HDR en conjunto. La versión beta de Safari 19 aún no admite el valor “restringido”, pero mantente al tanto. Y si usas una imagen HDR y el navegador no la admite, no pasa nada. El navegador asignará los contenidos HDR al rango SDR, así que no necesitas alternativas. Puedes usar la mejor imagen disponible y el navegador se encargará del resto. Esto significa que ya puedes incorporar fotos y videos más dinámicos a tus sitios y apps web, creando imágenes más ricas y hermosas para tus usuarios. Otros tipos de medios, como audio y video, pueden ayudar a darle vida a tus sitios y apps web, por eso aumentamos la admisión de más formatos de medios. En los últimos años, implementamos lo necesario para admitir una mayor variedad de códecs y contenedores. Fuimos los primeros en admitir JPEG XL y HEIC en la web, y en Safari 19, agregamos Ogg Opus y Ogg Vorbis a la lista de medios que admitimos. Con soporte para 15 formatos, brindamos aún más opciones sobre lo que puedes incluir en tu sitio o app web. Nuestro trabajo es garantizar que más combinaciones complejas de códecs y contenedores funcionen en las API de la web. En Safari 18.4, cerramos la brecha al incluir soporte para WebM en la API MediaRecorder. Esta API para grabar medios permite integrar grabación de videos o podcasts en tiempo real en tus apps web. Ahora, estas apps pueden crear archivos WebM usando el códec de audio Opus y VP8 y VP9 para video en Safari y WKWebView. Además, trabajamos para que la web espacial sea compatible con más medios. Agregamos la renderización estereoscópica de modelos 3D, junto con tu otro contenido web, permitiendo a las personas interactuar con el modelo. También puedes incluir videos envolventes en tu página web que Safari entiende y puede reproducir correctamente sin herramientas adicionales. Para conocer más, consulta la sesión sobre la web espacial. Abarcaremos la incorporación de modelos 3D, la presentación de medios espaciales y la vista previa de una nueva funcionalidad que permite agregar un entorno tridimensional al sitio web. Esto es lo más destacado en materia de compatibilidad con medios del año pasado. En esta sesión, nos centramos en CSS y medios. Pero hay más sesiones que analizan otras funcionalidades que lanzamos. Tenemos una sesión que presenta los conceptos de WebGPU, brinda un resumen del lenguaje de sombreado Wig Sil y menciona cómo obtener un rendimiento óptimo del dispositivo. También tenemos una sesión sobre Declarative Web Push, que abarca cómo usarlo sin necesidad de un trabajador de servicio, cómo es más eficiente y transparente, y cómo mantener la compatibilidad con versiones anteriores. Y hay mucho más. Hemos incorporado nuevas funcionalidades en varias versiones de Safari. Incluyendo algunas de las más solicitadas… CSS para ayudarte a pulir tu tipografía y admitir todos los idiomas del mundo… Y otras que ayudan a proteger la privacidad del usuario. Consulta las notas de la versión en webkit.org. También puedes actualizarte a la tecnología web más reciente con artículos sobre lo nuevo en Safari. Envía informes de errores y solicitudes de funcionalidades en bugs.webkit.org, el rastreador de problemas de WebKit.

    Si tienes problemas con la interfaz de Safari o algo relacionado con iOS, iPadOS y macOS, envía un informe a feedbackassistant.apple.com. Asegúrate de tener la última información sobre lo que es compatible con Safari. Caniuse.com es un gran recurso para eso. Descarga Safari Technology Preview para estar al día con lo que está por venir. Se actualiza cada dos semanas, así que contiene las incorporaciones más recientes a WebKit. Trabajamos arduamente para ofrecerte funcionalidades que te ayuden a tener experiencias increíbles en la web. Esperamos que estos lanzamientos hagan que tu trabajo sea más fácil y emocionante. Cuando uses estas funcionalidades, dinos qué piensas. Feliz codificación.

    • 6:18 - Progress bar code scroll() example

      footer::after {
        content: "";
        height: 1em;
        width: 100%;
        background: var(--yellow);
        left: 0;
        bottom: 0;
        position: fixed;
        transform-origin: top left;
        animation: progress-scale linear;
        animation-timeline: scroll();
      }
      
      @keyframes progress-scale {
        from { transform: scaleX(0); }
        to { transform: scaleX(1); }
      }
    • 8:36 - html an css of text blocks showcasing different code topics

      <section class="topics">
        <h3>What you can learn:</h3>
        <ul class="topics">
           <li class="topic-item">Web Development</li>
           <li class="topic-item">Computer Science</li>
           <li class="topic-item">Data Science</li>
           <!-- additional HTML... -->
        </ul>
      </section>
      
      .topic-item {
        background: var(--yellow);  
        border: 1px solid var(--gray);
        /* additional CSS... */  
      }
    • 9:12 - text blocks twisting from the left - animation

      @keyframes in-from-left {
        from {
          opacity: 0;
          transform: scale(.8) rotate(-90deg)   
                     translateY(15vh);
        }
      }
    • 9:18 - text blocks twisting from the middle - animation

      @keyframes in-from-middle {
        from {
          opacity: 0;
          transform: scale(.8)   
                     translateY(15vh);
        }
    • 9:24 - text blocks twisting from the right - animation

      @keyframes in-from-right {
        from {
          opacity: 0;
          transform: scale(.8) rotate(90deg)   
                     translateY(15vh);
        }
      }
    • 10:07 - view() timeline example with timeline and range

      .topic-item {
        animation-fill-mode: both;
        animation-timeline: view();
        animation-range:
        &:nth-child(3n + 1) { animation-name: in-from-left; }
        &:nth-child(3n + 2) { animation-name: in-from-middle; }
        &:nth-child(3n + 3) { animation-name: in-from-right; }
      }
    • 12:20 - animation range 50%

      .topic-item {
        animation-fill-mode: both;
        animation-timeline: view();
        animation-range: 0% 50%;
        &:nth-child(3n + 1) { animation-name: in-from-left; }
        &:nth-child(3n + 2) { animation-name: in-from-middle; }
        &:nth-child(3n + 3) { animation-name: in-from-right; }
      }
    • 14:20 - simple cross document view transition code

      @view-transition {
          navigation: auto;
      }
    • 16:00 - adding media query for reduced motion

      @view-transition { navigation: auto; }
      
      @media not (prefers-reduced-motion) {
        @keyframes slide-in {
          from { translate: 100vw 0; }
        }
        @keyframes slide-out {
          to { translate: -100vw 0; }
        }
      }
    • 16:22 - adding ids to html for cross document view transition

      <body>
        <nav>
          <!-- additional HTML... -->
        </nav>
      
          <section class="hero">
            <div class="hero-image">
            <!-- additional HTML... -->
        </main>
        <footer>
          <!-- additional HTML... -->
        </footer>
      <body>
    • 16:58 - slide effect for cross document view transition

      @view-transition { navigation: auto; }
      
      @media not (prefers-reduced-motion) {
        #school-info {
          view-transition-name: main-body;
        }
        ::view-transition-old(main-body) {
      
        }
        ::view-transition-new(main-body) {
      
        }
        @keyframes slide-in {
          from { translate:e100vw 0; }
      	}
      }
    • 19:48 - nav bar and profile menu

      <nav>
        <h1 class="logo">A-School of Code</h1>
        <ul>
          <li>Courses</li>
          <li>Cohorts</li>
          <li class="profile">
            <img src="https://example.com/saron.jpeg" alt="woman speaking"/>
          </li>
        </ul>
      </nav>
      
      <ul class="profile-menu">
        <li>Account</li>
        <li>Settings</li>
        <li>Profile</li>
        <li>Billing</li>
      </ul>
    • 20:37 - adding popover attributes

      <ul class="profile-menu" id="profile-menu" popover>
        <li>Account</li>
        <li>Settings</li>
        <li>Profile</li>
        <li>Billing</li>
      </ul>
    • 20:51 - adding aria to popover target

      <nav>
        <div class="wrapper">
          <h1 class="logo">A-School of Code</h1>
          <ul>
            <li>Courses</li>
            <li>Cohorts</li>
            <li class="profile">
              <button class="profile-button" aria-haspopup="true" popovertarget="profile-menu">                                                 >
                <img src="https://example.com/saron.jpg" alt="woman speaking"/>
              </button>
            </li>
          </ul>
        </div>
      </nav>
    • 21:58 - establishing the anchor

      .profile-button {
        anchor-name: --profile-button;
      }
      
      .profile-menu {
        position-anchor: --profile-button;
      }
    • 23:25 - setting the target to top right

      .profile-menu {
        position-anchor: --profile-button;
        position-area: top right;
      }
    • 23:39 - setting the target to bottom center

      .profile-menu {
        position-anchor: --profile-button;
        position-area: bottom center;
      }
    • 24:16 - setting the target to span right

      .profile-menu {
        position-anchor: --profile-button;
        position-area: span-right;
      }
    • 24:17 - setting the target to span left

      .profile-menu {
        position-anchor: --profile-button;
        position-area: span-left;
      }
    • 27:30 - intro to the anchor() function

      .profile-button {
        anchor-name: --profile-button;
      }
      
      .profile-menu {
        position-anchor: --profile-button;
        position: absolute;
        top: anchor(bottom);
        left: anchor(left);
      }
    • 28:26 - using calc and units in anchor() function

      .profile-button {
        anchor-name: --profile-button;
      }
      
      .profile-menu {
        position-anchor: --profile-button;
        position: absolute;
        top: anchor(bottom);
        left: calc(anchor(left) + 1.5em);
      }
    • 29:43 - adding a text gradient

      .logo {
        background-image: linear-gradient(to 
                          bottom right in hsl, 
                          yellow, orange);
        background-clip: text;
        color: transparent;
      }
    • 31:05 - adding a gradient to border

      .primary-btn {
        background-image: linear-gradient(to 
                          bottom right in hsl, 
                          yellow, orange);
        background-clip: border-area;
        border-color: transparent;
        background-origin: border-box;
      }
    • 32:15 - shorthand for adding gradient to border

      .primary-btn {
        background: border-area linear-gradient(to bottom right in hsl, yellow, orange);
        border-color: transparent;
      }
    • 33:33 - arrow shape using path

      .review-shape {
        clip-path: path("M0 0 L 500 0 L 600 
                         100 L 500 200 L 0 
                         200 Q 100 100 0 0 z");
      }
    • 35:01 - arrow shape using shape()

      .review-shape {
        clip-path: shape(from top left,
          line to calc(100% - 50cqh) 0%,
          line to 100% 50cqh,
          line to calc(100% - 50cqh) 100%,
          line to bottom left,
          curve to top left with 50cqh 50cqh,
          close);
      }
    • 41:42 - dynamic range limit: no limit

      img {
        dynamic-range-limit: no-limit;
      }
    • 41:57 - dynamic range limit: standard

      img {
        dynamic-range-limit: standard;
      }
    • 0:00 - Introducción
    • Los equipos de Safari y WebKit han trabajado arduamente desde la última WWDC para mejorar las tecnologías web, la interoperabilidad y la experiencia del usuario. Próximamente, en Safari estarán disponibles nuevas funcionalidades en animación, diseño, efectos visuales y multimedia, como animaciones basadas en desplazamiento, posicionamiento de anclaje, compatibilidad con íconos SVG y formatos multimedia mejorados.

    • 1:46 - Animación
    • La animación es una herramienta poderosa para mejorar las experiencias en línea y lograr que los sitios web sean más atractivos y agradables. Al utilizar las últimas funcionalidades de CSS, específicamente las animaciones basadas en desplazamiento ahora disponibles en Safari 19, puedes mejorar un sitio web sin necesidad de usar JavaScript. Esta capacidad es importante porque mejora el rendimiento del usuario y la duración de la batería. Las animaciones basadas en desplazamiento incorporan dos nuevas líneas de tiempo: la línea de tiempo de desplazamiento y la línea de tiempo de visualización. La línea de tiempo de desplazamiento permite vincular animaciones al comportamiento de desplazamiento del usuario, lo que crea una experiencia más interactiva. Por ejemplo, una barra de progreso en la parte inferior de la página puede crecer a medida que alguien se desplaza hacia abajo, proporcionando una señal visual de su progreso. Es importante tener en cuenta la accesibilidad al implementar animaciones. Algunas personas podrían preferir menos movimiento debido a la incomodidad que ello conlleva, que puede ser provocada por diversos factores, como escalar objetos grandes, hacer zoom u objetos que se mueven a diferentes velocidades. Si tienes en cuenta estos factores desencadenantes, podrás crear animaciones que sean inclusivas y agradables para todo el mundo.

    • 19:01 - Diseño
    • Próximamente, Safari presentará un nuevo módulo CSS llamado posicionamiento de ancla, que revolucionará la forma en que los desarrolladores web crean información sobre herramientas y posicionan los menús. El posicionamiento de anclaje te permite anclar fácilmente un elemento a otro, como un menú a una foto de perfil. Esta capacidad permite un posicionamiento preciso del menú en relación con el ancla. Safari también reincorporó ajustes preestablecidos de ventana gráfica en el modo de diseño responsivo, lo que te permitirá probar los sitios web con más facilidad en distintos dispositivos y tamaños de pantalla.

    • 29:05 - Efectos visuales
    • Hay varias características CSS nuevas para mejorar los efectos visuales en sitios web y apps web. Una característica notable es la expansión de la propiedad background-clip. Originalmente utilizada para rellenar texto con degradados o imágenes, ahora puedes aplicar esta propiedad a los bordes. Sin embargo, se deben realizar algunos ajustes adicionales, como hacer transparente el color del borde y extender el origen del fondo, para lograr el efecto deseado. Puedes utilizar esta técnica para hacer que diversos elementos, como botones y círculos de progreso, sean más atractivos visualmente. Otro desarrollo interesante es la compatibilidad con la funcionalidad shape(), que permite a los diseñadores crear formas adaptables con más facilidad que antes. Te brinda control granular sobre qué partes de una forma se escalan con la ventana gráfica y cuáles permanecen estáticas, lo que garantiza que las formas mantengan su apariencia y proporciones en diferentes tamaños de pantalla. Esto es particularmente útil para crear elementos decorativos, como flechas o fondos. Además, CSS incorpora nuevas funcionalidades tipográficas, como text-wrap: pretty, disponible en Safari 19. Esta funcionalidad tiene como objetivo mejorar la legibilidad del texto al abordar problemas, como líneas cortas, separación excesiva de palabras y longitudes de línea desiguales. Ajusta el espaciado entre palabras y los saltos de línea para crear un diseño de párrafo más agradable y equilibrado. Esta es una mejora sutil que puede marcar una diferencia significativa en la experiencia general del usuario y se degrada gradualmente en los navegadores que no la admiten.

    • 38:22 - Medios de comunicación
    • Safari tiene previsto incorporar varias mejoras multimedia importantes próximamente. Entre ellas se encuentra la implementación de íconos SVG, que mejorarán la experiencia del usuario en diversas funcionalidades de Safari, como favicons, bookmarklets y la página de inicio. Los íconos SVG ofrecen una mejor escalabilidad y tamaños de archivo más pequeños en comparación con los PNG tradicionales. Además, Safari incorpora hoy compatibilidad con imágenes de alto rango dinámico (HDR) a WebKit y Safari. Las imágenes HDR hacen que el contenido web sea más vibrante y visualmente atractivo al mostrar tonos más profundos, gamas más amplias y colores más brillantes. Safari también está ampliando su compatibilidad con varios formatos multimedia, incluidos Ogg Opus y Ogg Vorbis para audio, y ha avanzado para garantizar que combinaciones complejas de códecs y contenedores funcionen en diferentes API. Estas actualizaciones te permiten integrar funcionalidades de grabación de video y podcast en tiempo real en tus apps web. Además, Safari está mejorando compatibilidad con la web espacial, lo que te permite renderizar modelos 3D estereoscópicamente e incluir videos inmersivos en páginas web. Estas mejoras tienen como objetivo hacer la web más interactiva y atractiva para todo el mundo.

Developer Footer

  • Videos
  • WWDC25
  • Novedades de Safari y WebKit
  • Open Menu Close Menu
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    Open Menu Close Menu
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • Icon Composer
    • SF Symbols
    Open Menu Close Menu
    • Accessibility
    • Accessories
    • App Store
    • Audio & Video
    • Augmented Reality
    • Business
    • Design
    • Distribution
    • Education
    • Fonts
    • Games
    • Health & Fitness
    • In-App Purchase
    • Localization
    • Maps & Location
    • Machine Learning & AI
    • Open Source
    • Security
    • Safari & Web
    Open Menu Close Menu
    • Documentation
    • Sample Code
    • Tutorials
    • Downloads
    • Forums
    • Videos
    Open Menu Close Menu
    • Support Articles
    • Contact Us
    • Bug Reporting
    • System Status
    Open Menu Close Menu
    • Apple Developer
    • App Store Connect
    • Certificates, IDs, & Profiles
    • Feedback Assistant
    Open Menu Close Menu
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program
    • News Partner Program
    • Video Partner Program
    • Security Bounty Program
    • Security Research Device Program
    Open Menu Close Menu
    • Meet with Apple
    • Apple Developer Centers
    • App Store Awards
    • Apple Design Awards
    • Apple Developer Academies
    • WWDC
    Get the Apple Developer app.
    Copyright © 2025 Apple Inc. All rights reserved.
    Terms of Use Privacy Policy Agreements and Guidelines