Make money with Oziconnect referral program

Previously, it was difficult to achieve smooth transitions while navigating the web. Compatibility, performance, and accessibility seemed unattainable because we had to juggle SPA, JavaScript, and CSS. Thankfully, the new native browser API view transitions and Astro implementation have made this process easier. Astro handles the heavy lifting, reduces CSS and JavaScript overhead, and provides true navigation through multi-page applications (MPAs).

This guide will walk you through building a basic shop so you can use this technique to navigate smoothly between pages.

If you’re interested in learning how to build an entire website using Astro, we recommend the following: Astro 3.0 course Written by James Q. This is a practical course that teaches you how to build websites using Astro 3.0, an all-in-one framework for the modern web. Codrops readers receive a special 10% discount:

Start

Clone a GitHub repository

If you want to get started quickly, check out our Github repository.

step by step

First, create an Astro project using the installer. If you run into any issues or have questions, our Astro installation guide has all the answers.

# Using NPM
npm create astro@latest
# Using Yarn
yarn create astro
# Using PNPM
pnpm create astro@latest

During installation, the installer will prompt you for several settings.please choose empty Use project options as a starting point.

Understand folder structure

  • component: This folder contains various components such as buttons, cards, etc.
  • Layout: Now save your shared page layout.
  • page: This folder contains pages and navigation is based on file-based routing. For more information, please see the Astro Routing Guide.

Astro supports various UI frameworks such as React, Vue, and Svelte. This demo uses Astro syntax to create components. These files have a .astro extension and combine HTML, CSS, and JS.

TailwindCSS integration

This project uses TailwindCSS for styling. Include this using the Astro CLI.

# Using NPM
npx astro add tailwind
# Using Yarn
yarn astro add tailwind
# Using PNPM
pnpm astro add tailwind

Product data

This example uses a data set for products containing sports shoes and shirts, but feel free to use whatever data you want.

These images are already optimized for the web, so put them in the /publics folder. By default, Astro does not optimize images in public folders. If you want Astro to optimize them, you need to put them in the /src folder or configure them. Learn more about Astro image optimization

Add icon library

This example uses astro-icon as the page icon.

# Using NPM
npm i astro-icon
# Using Yarn
yarn add astro-icon
# Using PNPM
pnpm add astro-icon

Running the project

# Using NPM
npm run dev
# Using Yarn
yarn dev
# Using PNPM
pnpm dev

A blank page will appear.

layout and design

First, create a layout for the entire page.Found below src/layouts/Layout.astro

By default, Astro renders pages statically at build time, so you’ll see three dashes at the top of the page. This separates the JavaScript that is executed at build time (or when requesting SSR, etc.) from the rest. page.

---
import  ViewTransitions  from "astro:transitions";
interface Props 
  title: string;
  description?: string;


const 
  title,
  description = "A simple Shop built in Astro using View Transitions and TailwindCSS",
 = Astro.props;
---

<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="description" content=description />

    <meta name="viewport" content="width=device-width" />
    <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
    <meta name="generator" content=Astro.generator />
    <title>title - Astro Transitions Shop</title>
    <ViewTransitions />
  </head>
  <body>
    <main
      class="relative max-w-6xl min-h-screen mx-auto py-6 lg:pt-10 px-4 pb-20"
    >
      <slot />
    </main>

    <style is:global>
      :root 
      
      body 
        background-color: theme(colors.gray.50);
      
      .animate-in 
        animation: animate-in 0.5s ease-in-out;
      
      /* Firefox */
      * 
        scrollbar-width: auto;
        scrollbar-color: #c7c7c7 #ededed;
      

      /* Chrome, Edge, and Safari */
      *::-webkit-scrollbar 
        width: 15px;
      

      *::-webkit-scrollbar-track 
        background: #ededed;
      

      *::-webkit-scrollbar-thumb 
        background-color: #c7c7c7;
        border-radius: 5px;
        border: 2px solid #ffffff;
      
      @keyframes animate-in 
        0% 
          opacity: 0;
          transform: translateY(1rem);
        
        100% 
          opacity: 1;
          transform: translateY(0);
        
      
    </style>
  </body>
</html>

To use view transitions, components within <頭> Section of the layout you want to use. Once done, you’ll see a fade effect applied to your navigation.

The layout expects the following title and explanation Get properties from child elements. However, you can set any properties you want, such as metadata props.

has also been introduced. <メイン> A tag that centers the page’s content.of <スロット /> The tag is where Astro inserts the layout’s child components, similar to React’s “children” prop.

At the bottom, <スタイル:グローバル> Use tags to declare global styles shared by this layout. In this example, we defined a style for the browser scrollbar and a simple keyframe animation for the title when transitioning to the product page.

home page

Next, let’s create a homepage consisting of a header and product list.It can be found at src/pages/index.astro.

---
import Layout from "../layouts/Layout.astro";
import  products  from "../data";
import ProductCard from "../components/ProductCard.astro";
---

<Layout title="Shop">
  <div class="flex gap-3 items-end">
    <h1 class="text-4xl font-bold">Astro Shop</h1>
  </div>
  <h3 class="text-xl text-gray-500">
    Take a look in our products, feel free to buy some
  </h3>
  <div class="flex flex-wrap justify-center sm:justify-normal gap-4 py-8">
    products.map((product) => <ProductCard product />)
  </div>
</Layout>

What we import is <レイアウト> Assign a title to the previously created component. We are also extracting products from previously created product data. <プロダクトカード /> This is the next component to create.

product card

Product cards are components designed to display our products in a list. Used Tailwind to apply common styles to ensure product images, titles, descriptions, and prices display correctly.

Astro shop card example

Found below src/components/ProductCard.astro.

---
import type  Product  from "../data";

interface Props 
  product: Product;


const  product  = Astro.props;
---

<a href=`/product/$product.slug` class="block">
  <article
    class="group bg-flex flex-col sm:w-60 w-72 bg-white shadow-sm rounded-lg overflow-hidden hover:shadow-xl hover:shadow-gray-100 transition-all"
  >
    <div class="sm:w-60 w-72 h-60 overflow-hidden">
      <img
        src=product.cover
        alt=product.name
        class="object-cover object-center w-full grayscale-[0.1] group-hover:grayscale-0 h-full rounded-md group-hover:scale-105 transition-all"
      />
    </div>
    <div class="p-4">
      <h3
        class="font-semibold truncate"
      >
        product.name
      </h3>
      <p
        class="text-gray-600 text-sm truncate"
      >
        product.description
      </p>
      <div class="text-right mt-4">
        <span class="font-semibold">$product.price</span>
      </div>
    </div>
  </article>
</a>

ProductCard is product props and rendering <記事> within This is a tag for navigation. In Astro, navigation is tag with href Attribute pointing to the desired page.

Product page

The product page is a dynamic page named . [slug] This corresponds to the product’s slug defined in the product data.

Astro shop product page

The product page can be found at: src/page/product/[slug]/index.astro.

---
import  type Product, products  from "../../../data";
import Layout from "../../../layouts/Layout.astro";
import ProductCard from "../../../components/ProductCard.astro";
import Icon from "astro-icon";
const  slug  = Astro.params;

export function getStaticPaths() 
  return [
    ...products.map((product) => (
      params: 
        slug: product.slug,
      ,
    )),
  ];


const product = products.find((product) => product.slug === slug) as Product;
---

<Layout
  title=product.name
  description=product.description
>
  <div class="max-w-5xl mx-auto relative">
    <a
      href="/"
      class="absolute xl:-left-14 top-8 xl:-top-1 xl:bg-none bg-gradient-to-br from-gray-100 rounded p-2 z-10"
      ><Icon name="mdi:chevron-left" class="h-6 w-6" /></a
    >
    <div class="flex gap-2 pb-2 items-center text-gray-500">
      <a class="after:content-['/'] after:pl-2 capitalize" href="/">home</a>
      <span class="after:content-['/'] after:pl-2 capitalize"
        >product.category</span
      >
      <span>product.name</span>
    </div>
    <div class="flex flex-col md:flex-row sm sm:gap-8">
      <div class="max-w-[450px] w-full h-full max-h-[450px]">
        <img
          src=product.cover
          alt=product.name
          class="w-full h-full object-cover rounded-xl shadow-2xl shadow-gray-200 border-b"
        />
      </div>
      <article class="py-4 flex justify-between flex-col">
        <div>
          <h1 class="text-3xl sm:text-5xl font-bold animate-in">
            product.name
          </h1>
          <p
            class="max-w-sm py-4 text-lg"
          >
            product.description
          </p>
        </div>
        <div class="pt-2 sm:pt-8 text-right">
          <div class="text-3xl font-semibold">
            $product.price
          </div>
          <div class="text-xs text-gray-500">* This is a fictional price</div>
          <button
            type="button"
            class="mt-4 px-5 py-2 bg-gray-900 hover:bg-gray-800 text-white font-semibold rounded-full"
            >Add to cart</button
          >
        </div>
      </article>
    </div>
    <div class="py-6 md:py-20 max-w-3xl">
      Lorem ipsum dolor sit, amet consectetur adipisicing elit. Incidunt magnam
      quia, explicabo dolor velit aut omnis natus consequatur possimus fuga illo
      commodi asperiores dignissimos. Consequuntur nam quae commodi quas, magni
    </div>
    <h4 class="font-bold text-lg">Similar products</h4>
    <div class="flex flex-wrap justify-center sm:justify-normal gap-4">
      
        products
          .filter((p) => p.category === product.category && p.id !== product.id)
          .map((pr) => <ProductCard product=pr />)
      
    </div>
  </div>
</Layout>

On this page, slug Gets the prop from the navigation Params and exports a function named. getStaticPaths. Astro uses this feature to generate static pages (SSG) for his website and create pages for all his products. /products/[slug] Format such as /product/haryo-setyadi-shirt.

In the product title, .animate-in A class that animates the title when entering the page. At the bottom you get similar products based on category.

Note that this example utilizes SSG, so the page will be generated at build time. If you need to retrieve data at request time, you should use SSR. To learn more about SSG and SSR, check out Astro Docs.

Implementing view transitions

Next, implement view transitions between the pages you created. To do this, Transition: Name Attributes the elements that animate during transitions between pages. Let’s examine the layout in more detail.

  • in home pageEach product card Features image, title, explanationand price.
  • Similarly, Product page will also be displayed image, title, explanationand price For each product.

To implement a smooth transition between two pages, you must link elements on both pages using unique links. transition name. That way, Astro’s view transitions will automatically handle the animation during navigation.

Step 1: Assign transition:name to elements in the product card

Modify the element in the product card so that the transition name matches the element on the product page.

  • src/components/ProductCard.astro

Product card image

...
      <img
        src=product.cover
        alt=product.name
        transition:name=`$product.slug image` 
        class="object-cover object-center w-full grayscale-[0.1] group-hover:grayscale-0 h-full rounded-md group-hover:scale-105 transition-all"
      />
...

Product card title

...
      <h3
        class="font-semibold truncate"
        transition:name=`$product.slug title`
      >
        product.name
      </h3>
...

Product card description

...
      <p
        class="text-gray-600 text-sm truncate"
        transition:name=`$product.slug description`
      >
        product.description
      </p>
...

product card price tag

...
      <div class="text-right mt-4" transition:name=`$product.slug price`>
        <span class="font-semibold">$product.price</span>
      </div>
...

It is important to note that we are assigning a transition name that is a combination of the product slug and the element’s name.This allows each Transition names are unique within a pageThis allows Astro to seamlessly link and animate between them during navigation.

Step 2: Link transition:name to the corresponding element on the product page

Follow the same steps to associate appropriate transition names with relevant elements on this page to ensure a smooth transition experience.

  • /src/page/product/[slug]/index.astro

Product page image

...
        <img
          src=product.cover
          alt=product.name
          class="w-full h-full object-cover rounded-xl shadow-2xl shadow-gray-200 border-b"
          transition:name=`$slug image`
        />
...

Product page title

...
          <h1 class="text-3xl sm:text-5xl font-bold animate-in">
            product.name
          </h1>
          <div transition:name=`$slug title`></div>
...

transition name

adjacent to

It’s the title element, not the title itself.

Large title elements, such as , may cause unusual sliding behavior in view transitions. Assigning this to an adjacent element will ensure a smooth transition of the product card title. This workaround addresses a current limitation, which may be resolved in a future update.

Product page description

...
          <p
            class="max-w-sm py-4 text-lg"
            transition:name=`$slug description`
          >
            product.description
          </p>
...

Product page price

...
          <div class="text-3xl font-semibold" transition:name=`$slug price`>
            $product.price
          </div>
...

Use consistent transition names and refer to corresponding components for seamless transitions.

Thus, it is completed! As you navigate, you’ll see attractive sliding animations between pages.

Browser support and accessibility

View transitions still work experimental features It is not yet widely supported. For a comprehensive understanding, please check the browser compatibility table.

Astro offers: Fallback for unsupported browsers For this feature, prefers shrinking motion setting.

Astro sets fallback animations by default for unsupported browsers. If you observe unusual behavior in these environments, consider deactivating the fallback.

For more information, customize animation and Configuring fallback See the Astro View transition documentation.

Design choices for view transitions

On mobile devices, transitions often appear more subtle due to the limited screen size. Conversely, on larger screens, animations can appear exaggerated or overly intense, which can detract from the user’s experience. As this example shows, a good design approach is to simplify and expand elements. Therefore, it is important that view transitions match your design choices.

The Astro team is actively working to improve these transitions and give you more control over their animations.

performance

Another important aspect to consider is performance. While web browsers continually optimize for better performance, profiling your website is essential to identifying and addressing excessive animations.

Final considerations

The view transitions combined with Astro integration are definitely impressive. However, it should be carefully considered before deploying to a production app. The appropriateness of using view transitions depends on the nature of your application and its audience. For example, if your page has a complex UI, this feature may not be optimal. Nevertheless, view transitions have great potential to improve the user experience on numerous websites.

Full screen image slideshow animation ideas

Gradually enhanced WebGL lens refraction

Make money with Oziconnect referral program
Make money with Oziconnect referral program
Make money with Oziconnect referral program
84512

About Us

We are a leading IT agency in Lagos, Nigeria, providing IT consulting and custom software development services. We offer a wide range of IT solutions across software development, web and mobile application development, blockchain development services, digital marketing, and branding.

Contact Us

25B Lagos-Abekouta Expressway Lagos

info@ozitechgroup.com

Phone: (234) 907 155 5545

@2023 OzitechGroup – All Right Reserved.