How to make a landing page with Astro, HTML, CSS
Tags: astro
Published: 2022-09-17 05:40:02

---
title: How to make a landing page with Astro, HTML, CSS
published: true
date: 
tags: astro
canonical_url: https://eternaldev.com/blog/how-to-make-a-landing-page-with-astro-html-css
cover_image: https://www.eternaldev.com/static/42e696dc0fbf679b821378e2f3b01369/aa1b3/astrolandingpageposter.webp
---

## What is Astro

Astro is a meta-framework for building websites with your favorite frontend frameworks like Svelte, React, Preact and others. The key selling point of Astro is the way it approaches the static site generation in which it ships zero javascript to the browser.

It can do more than just static site generators using the [island architecture](https://docs.astro.build/en/concepts/islands/) which means that you can have SEO-friendly content when needed and also have interactive elements to spice up your webpage.

If the above two sentences are full of just jargon that you are not able to follow, don’t worry. Astro is great for most of the websites which is not updated on an hourly basis. It is specifically good if you want to build landing pages/product pages that need to be indexed by search engines.

We will look into the specifics as we start building the application

## What are we building

We are going to build a simple landing page for a product that contains a Hero component at the top and a list of features below that.

[![FarmlandDribbbleMain.png](https://eternaldev.com/static/e8db7dce570af7fbcdc14a40f87f9842/29007/farmlanddribbblemain.png "FarmlandDribbbleMain.png")](/static/e8db7dce570af7fbcdc14a40f87f9842/29007/farmlanddribbblemain.png)

## Prerequisites

1. You will need a basic understanding of HTML and CSS
2. You will need to have Node js installed in your system

## Initialize the Astro project

You can start with an Astro project using the following command. It gives a series of prompts that will guide you into creating your project

```
npm create astro@latest
```

[![AstroInit1.png](https://eternaldev.com/static/a74f7a3fe9c6913d3d8700a113eaf3a0/6a6e9/astroinit1.png "AstroInit1.png")](/static/a74f7a3fe9c6913d3d8700a113eaf3a0/6a6e9/astroinit1.png)

1. Where would you like to create your new project? - Provide the path of the folder and the project name - astro-landingpage

[![AstroInit2.png](https://eternaldev.com/static/f1f79c3b22f450b81ae4734b3b8a4959/1e088/astroinit2.png "AstroInit2.png")](/static/f1f79c3b22f450b81ae4734b3b8a4959/1e088/astroinit2.png)

2. Which template would you like to use? › Just the basics

[![AstroInit3.png](https://eternaldev.com/static/9aee394ec949a20fae8a8e86fc3592b7/d48f1/astroinit3.png "AstroInit3.png")](/static/9aee394ec949a20fae8a8e86fc3592b7/d48f1/astroinit3.png)

The rest of the questions are straight forward and answer them with the below options

3. Would you like to install npm dependencies? (recommended) … yes

4. Would you like to initialize a new git repository? (optional) … yes

5. How would you like to setup TypeScript? › Strict (recommended)

Now the Astro project is ready to get started. You can see in the package.json file we have just one dev dependencies like below

```json
{
  "name": "@example/basics",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "dev": "astro dev",
    "start": "astro dev",
    "build": "astro build",
    "preview": "astro preview",
    "astro": "astro"
  },
  "devDependencies": {
    "astro": "^1.1.1"
  }
}
```

Since it is under devDependencies, `astro` is not shipped with the build which means that we get only the static HTML needed for our application.

We also have a few scripts in the `package.json` file which correspond to the following

1. `dev` - Running the development server locally
2. `start` - Same as the Dev script
3. `build` - Building the project. This will generate `dist` folder which contains the build for running the website
4. `preview` - Used to preview the build in the `dist` folder locally.
5. `astro` - Can be used to run other Astro commands

## Astro Project structure

Astro has an opinionated folder structure for your project which means that there are specific folders that you need to know about to get your job done easily.

### Directories and Files

- `src/*` - Main source code
- `public/*` - Assets (Images, icons, etc)
- `astro.config.mjs` - Config file for Astro

Learn more about the project structure in the below official link

[https://docs.astro.build/en/core-concepts/project-structure/](https://docs.astro.build/en/core-concepts/project-structure/)

## Building the layout

Layouts are part of Astro which makes it easy for the developer to reuse some of the structure which is needed for most applications. If you have a Navbar, Header, and Footer component on all your pages, you can use Layout to add that component and use that layout on all the pages.

So when you want to change something in your layout, all the pages which use that layout are automatically changed.

So let’s define our layout for this application. This is going to be simple for this design since we can have the Footer in the layout and the rest of the content will be on the page.

[![AstroLayoutTemplate.png](https://eternaldev.com/static/24b8e9cdbde193c6f25c06aeb8507d8a/985a9/astrolayouttemplate.png "AstroLayoutTemplate.png")](/static/24b8e9cdbde193c6f25c06aeb8507d8a/985a9/astrolayouttemplate.png)

Let’s build that in code. I am going to reuse the already present `Layout.astro` files in the `layouts` folder. You can choose to create a new file if you like.

```html
---
export interface Props {
	title: string;
}

const { title } = Astro.props;
---

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<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}</title>
	</head>
	<body>
		<slot />
		<Footer/>
	</body>
</html>
```

`<slot>` tag will be replaced by the actual HTML of your page when you are using this layout file.You can learn more about layout in the following link

[https://docs.astro.build/en/core-concepts/layouts/](https://docs.astro.build/en/core-concepts/layouts/)

## Building the Footer component with Astro

Let’s create a new file called `Footer.astro` and we can add simple footer details on that component. We will not go into detail about the HTML component used but you can see the overview of the file below.

```html
<div class="footer">
    <div class="footer-col">
        <b>Site Map</b>
        <br/>
        <a href="/home">Home</a>
        <a href="/about">About</a>
        <a href="/pricing">Pricing</a>
    </div>
    <div class="footer-col">
        <b>Address</b>
        <br/>
        485 Essex Court<br/>
        South Burlington<br/>
        Mobile No:	802-505-1847
    </div>
    <div class="footer-col">
        <b>Social</b>
        <br/>
        <a href="/">Facebook</a>
        <a href="/">Twitter</a>
        <a href="/">Instagram</a>
        <a href="/">Reddit</a>
    </div>
</div>

<style>

    .footer{
        display: flex;
        flex-direction: row;
        justify-content: space-evenly;
        gap: 50px;
        padding: 4rem 2rem;
        background-color: #F9EBC4;
    }

    .footer-col {
        display: flex;
        flex-direction: column;
    }
</style>
```

We have a simple three-div structure and using [flexbox](https://www.w3schools.com/css/css3_flexbox.asp), we can align them as three columns using the CSS in the `<style>` tag

The CSS in the `<style>` tag is scoped locally which means that it won’t affect the other components. This is a neat feature that requires some external packages and solutions in other frameworks. It works out of the box in Astro

The result will look like below image. Since we are yet to remove the content of `index.astro` default file, you will get the default page with the footer

[![AstroLandingpageFooter.png](https://eternaldev.com/static/5037c1950a05be1b3ae0ba2f12e9572b/cb9f4/astrolandingpagefooter.png "AstroLandingpageFooter.png")](/static/5037c1950a05be1b3ae0ba2f12e9572b/cb9f4/astrolandingpagefooter.png)

## Building the Content page

Let’s start by building the content page now. Clear all the contents of `index.astro` file

### Updating the font family

Based on the design, we are going to use this font family from [Google Fonts - Rowdies](https://fonts.google.com/specimen/Rowdies).

You can add the link to the font in the `Layout.astro` file

```html
<html lang="en">
	<head>
		...
		<link rel="preconnect" href="https://fonts.googleapis.com">
		<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
		<link href="https://fonts.googleapis.com/css2?family=Rowdies:wght@300;700&display=swap" rel="stylesheet">
	</head>

	
</html>
<style>
	....
	html {
		font-family: 'Rowdies', cursive;
	}

</style>
```

You can these snippets directly from the Google Fonts website. We are adding the `<link>` tag to the `<head>` to download the font from the Google fonts. Then we add the `font-family` to the `html` in order to set the font for the whole page.

[![Googlefont List](https://eternaldev.com/static/af4a877a0e205b271ded111a8429e9ba/5fad2/googlefonts_snipper.png "Googlefont List")](/static/af4a877a0e205b271ded111a8429e9ba/5fad2/googlefonts_snipper.png)

### Building the Header in Astro

Let’s create the header of the design in Astro file. Create a new folder inside the component called `landingpage` and add the home page components to that folder

So create a file name `herosection.astro` inside `src/components/landingpage`

```html
<div class="hero-section">
    <div>
        <h1>Managed Farmland</h1>
        <p>Start owning your farmland and leave the hard part to us</p>
        <button>Start Now</button>
    </div>
    <img src="hero-image.svg" width="400px"/>
</div>

<style>
    .hero-section {
        margin: 1rem;
        padding: 4rem;
        border-radius: 2rem;
        background-color:#F9EBC4;
        display: flex;
        flex-direction: row;
        gap: 2rem;
    }

    .hero-section div {
        flex: 1
    }

    .hero-section div p {
        margin: 2rem 0px;
    }
</style>
```

There are a couple of things to note in this component

1. Adding an image to Astro - You can add the images you want to display into the `public` folder and you can access the file directly in the `<img/>` tag.
2. We want to add a global style to the button and so you can use the `:global()` syntax to add CSS styles that will be applied globally

We have added the global style for the header in this `Layout.astro` file

```css
:global(button) {
		background: #A7CF5D;
		border: 3px solid #000000;
		border-radius: 8px;
		font-size: large;
		padding: 0.75rem 1rem;
		font-weight: bold;
		text-transform: uppercase;
	}
```

### Updating the Landing page

After creating the Hero section component, we need to update the main `index.astro` file to add the new component

```html
---
import HeroSection from '../components/landingpage/HeroSection.astro';
import Layout from '../layouts/Layout.astro';
---

<Layout title="Managed Farmland">
	<main>
		<HeroSection/>
	</main>
</Layout>

<style>

	:global(h1) {
		margin: 2rem 0;
	}

	main {
		max-width: 1440px;
		margin:auto
	}
</style>
```

### Result of the Hero section

[![AstroLandingPageHeroSection.png](https://eternaldev.com/static/1f48a8dd16a6da318f22ad717639405a/9e818/astrolandingpageherosection.png "AstroLandingPageHeroSection.png")](/static/1f48a8dd16a6da318f22ad717639405a/9e818/astrolandingpageherosection.png)

### Why Us Section

We have an interesting section after the Hero section about some of the details of the product. We can divide that into two equal halves horizontally using `flex`

We can then divide the left section into a `grid` of 4 items and place the items in order with an icon.

Let’s look at the code on how to do that

```html
<div class="section-wrapper">
    <div class="features">
        <span><img src="favicon.svg" width="16" height="16"/>Water Management</span>
        <span><img src="favicon.svg" width="16" height="16"/>Farm Security</span>
        <span><img src="favicon.svg" width="16" height="16"/>Planting and Harvest</span>
        <span><img src="favicon.svg" width="16" height="16"/>Low Maintainence</span>
    </div>
    <div>
        <h2>Why should you buy ?</h2>
        <p>Awesome adventure and benefits if you buy this land from us and we promise you will not be disappointed</p>
    </div>
</div>

<style>
    .section-wrapper {
        display: flex;
        flex-direction: row;
        padding: 2rem;
        gap: 20px
    }
    .section-wrapper div {
        flex: 1
    }

    .features {
        display: grid;
        grid-template: "1fr 1fr";
        padding: 2rem;
    }
</style>
```

**Things to note**

1. We are saving all the `div` inside the `.section-wrapper` class to have a flex value set to 1. So there are two divs and both will get the value of 1 which makes the divs equal size
2. grid-template: “1fr 1fr” stands for dividing the grid into two equal fractions. So the grid is set to have two columns of equal size and depending on the number of items, it decides on the number of rows of the grid.

[![AstroLandingWhySection.png](https://eternaldev.com/static/b90b227eebba1c64579eb2a649a805ef/b1001/astrolandingwhysection.png "AstroLandingWhySection.png")](/static/b90b227eebba1c64579eb2a649a805ef/b1001/astrolandingwhysection.png)

### Features Section

We have another section after the Why Us section with more details.

We can then divide this section into a `grid` of 4 items and place the items similar to the previous section. We can also add a fancy background gradient for this div to make it look like the design

Let’s look at the code on how to do that

```html
<div class="features-wrapper">
    <div class="box">
        <h2>Location</h2>
        <p>Located at the best of places the nature can offer and it is a ideal place to do agriculture with plenty of water sources nearby</p>
    </div>

    <div class="box">
        <h2>Method</h2>
        <p>We are using natural methods for the planting trees and agricultural techniques which combine both modern and traditional</p>
    </div>

    <div class="box">
        <h2>Technology</h2>
        <p>Integrating technology into the agriculture mix will let you examine each and every tree whereever you are located</p>
    </div>

    <div class="box">
        <h2>Weekend Resort</h2>
        <p>You can enjoy our resort with your family with free credit for our land owners</p>
    </div>
</div>

<style>
    .features-wrapper {
        display: grid;
        grid-template: "1fr 1fr";
        padding: 2rem;
    }

    .box {
        margin: 2rem;
        background: linear-gradient(124.28deg, #F9EBC4 59.55%, #A7CF5D 91.58%);
        border-radius: 20px;
        padding: 1rem;

    }
</style>
```

[![AstroLandingFeatureSection.png](https://eternaldev.com/static/479f82c69e6451543adc7935037d1016/f2364/astrolandingfeaturesection.png "AstroLandingFeatureSection.png")](/static/479f82c69e6451543adc7935037d1016/f2364/astrolandingfeaturesection.png)

### About Us Section

Create a new component inside the `landingpage` folder of component and name it `AboutUsSection.astro`

You can add the following content

```html
<div>
    <h2>About Us</h2>
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Impedit repudiandae maxime tempora modi culpa provident necessitatibus distinctio, esse libero aliquid magnam cumque earum, totam soluta amet ex reiciendis voluptate! Veniam.</p>
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Impedit repudiandae maxime tempora modi culpa provident necessitatibus distinctio, esse libero aliquid magnam cumque earum, totam soluta amet ex reiciendis voluptate! Veniam.</p>
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Impedit repudiandae maxime tempora modi culpa provident necessitatibus distinctio, esse libero aliquid magnam cumque earum, totam soluta amet ex reiciendis voluptate! Veniam.</p>
</div>

<style>
    div {
        padding: 2rem;
        margin: 2rem 0px;
        background-color:#F9EBC4;
    }
</style>
```

[![AstroLandingPageAboutUs.png](https://eternaldev.com/static/624a00a8884d26298a3e9e6d692f204a/3f919/astrolandingpageaboutus.png "AstroLandingPageAboutUs.png")](/static/624a00a8884d26298a3e9e6d692f204a/3f919/astrolandingpageaboutus.png)

### Project Section

Create a new component inside the `landingpage` folder of component and name it `Projects.astro`

```html
<div class="projects">
    <div class="project-item">
        <div>
            <h2>Farm Land 1</h2>
            <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Soluta, eos. Repellat magnam maiores maxime in voluptate neque, ipsum modi sint recusandae ducimus explicabo. Perspiciatis aut dolor quaerat soluta tempore ullam! Lorem ipsum dolor sit amet consectetur adipisicing elit. Unde corporis eaque soluta commodi doloremque dolores ratione perspiciatis nobis, fugiat quis temporibus officia qui, voluptatibus voluptatem harum? A corporis animi debitis!</p>
            <button>Buy Now</button>
        </div>
        <div>
            <img src="hero-image.svg"/>
        </div>
    </div>

    <div class="project-item">
        <div>
            <h2>Farm Land 2</h2>
            <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Soluta, eos. Repellat magnam maiores maxime in voluptate neque, ipsum modi sint recusandae ducimus explicabo. Perspiciatis aut dolor quaerat soluta tempore ullam! Lorem ipsum dolor sit amet consectetur adipisicing elit. Unde corporis eaque soluta commodi doloremque dolores ratione perspiciatis nobis, fugiat quis temporibus officia qui, voluptatibus voluptatem harum? A corporis animi debitis!</p>
            <button>Buy Now</button>
        </div>
        <div>
            <img src="hero-image.svg"/>
        </div>
    </div>
</div>

<style>

    .projects {
        padding: 2rem;
        margin: 0 2rem;
    }

    .project-item {
        display: flex;
        flex-direction: row;
        align-items: center;
    }

    .project-item div {
        flex: 1;
        padding: 2rem;
    }

</style>
```

[![AstroLandingPageProjects.png](https://eternaldev.com/static/007728053fb7cc0e2dc74865f9aa0d16/68638/astrolandingpageprojects.png "AstroLandingPageProjects.png")](/static/007728053fb7cc0e2dc74865f9aa0d16/68638/astrolandingpageprojects.png)

## Conclusion

That’s all for today. We have done a full walkthrough of the code needed to get the landing page working in Astro. Join us on Discord if you have other questions

Discord - [https://discord.gg/AUjrcK6eep](https://discord.gg/AUjrcK6eep)