Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Build an Instagram-style page as a semantic profile header followed by a responsive, square-tile gallery. Keep the content in HTML, put presentation in an external stylesheet, and use CSS Grid with aspect-ratio: 1 so every thumbnail remains square as the viewport changes. The example below is a complete starting point you can adapt with your own authorized images, profile details and links.

Decide what you are building

There are two different projects that are often called an “Instagram-style page.” A static mockup recreates the visual pattern with your own HTML, CSS and image files. A live-content page displays actual Instagram posts through an embed workflow. They have different constraints.

Decision Static HTML/CSS mockup Real post embed
Content source Images and text you host or are authorized to use An Instagram post URL through an available embed method
Visual control You control the layout, spacing and typography The provider and embedding platform control part of the presentation
Eligibility Suitable for a design exercise or portfolio WordPress documentation specifies public posts for its Instagram block
Responsive work You size the gallery with your own CSS You must test the embed at narrow widths; WordPress documents a resize setting
Best use A branded profile concept or local gallery Showing an eligible, real public post

This tutorial implements the static version first. Do not imply that a visual imitation is connected to Instagram, and do not copy images or branding you do not have permission to use.

Set up a semantic HTML structure

Use a page header for the site identity, a main profile section for the account summary, and a gallery section for media. A linked tile is useful when each image has a detail page; otherwise, use a descriptive figure or article. Create an index.html file:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#1 Best Overall
Sale
HTML and CSS: Design and Build Websites
  • HTML CSS Design and Build Web Sites
  • Comes with secure packaging
  • It can be a gift option
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Maya Chen — Photo journal</title>
  <link rel="stylesheet" href="styles.css">
</head>
<body>
  <header class="site-header">
    <a class="brand" href="/">Maya Chen</a>
    <nav aria-label="Primary navigation">
      <a href="#gallery">Gallery</a>
      <a href="#about">About</a>
    </nav>
  </header>

  <main>
    <section class="profile" id="about" aria-labelledby="profile-name">
      <img class="avatar" src="images/avatar.jpg" alt="Portrait of Maya Chen">
      <div class="profile-copy">
        <div class="profile-heading">
          <h1 id="profile-name">@mayachen</h1>
          <a class="button" href="#follow">Follow</a>
        </div>
        <ul class="stats" aria-label="Profile statistics">
          <li><strong>48</strong> posts</li>
          <li><strong>12.4K</strong> followers</li>
          <li><strong>381</strong> following</li>
        </ul>
        <p>Street photography, coffee and slow travel.</p>
      </div>
    </section>

    <section id="gallery" aria-labelledby="gallery-title">
      <h2 id="gallery-title">Photo gallery</h2>
      <div class="gallery">
        <a href="posts/market.html">
          <img src="images/market.jpg" alt="Colorful produce at a covered market" loading="lazy">
        </a>
        <a href="posts/river.html">
          <img src="images/river.jpg" alt="River viewed from a stone bridge" loading="lazy">
        </a>
        <a href="posts/ceramics.html">
          <img src="images/ceramics.jpg" alt="Handmade blue ceramic cups" loading="lazy">
        </a>
      </div>
    </section>
  </main>
</body>
</html>

The external stylesheet is connected with the standard <link rel="stylesheet" href="styles.css"> pattern. Keep the profile statistics in a list because each value and label is a separate item. Replace sample names, counts and image paths with your own data; the numbers above are illustrative content, not platform measurements.

Style the profile header

Create a centered content column, a flexible profile row and a circular avatar. The header must be allowed to wrap so it remains usable on a phone.

:root {
  color-scheme: light;
  --ink: #171717;
  --muted: #6b6b6b;
  --line: #dedede;
  --surface: #fff;
  --accent: #0a66c2;
}

* { box-sizing: border-box; }
body {
  margin: 0;
  color: var(--ink);
  background: var(--surface);
  font: 16px/1.5 system-ui, sans-serif;
}
a { color: inherit; }
.site-header,
main {
  width: min(100% - 32px, 960px);
  margin-inline: auto;
}
.site-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  min-height: 64px;
  border-bottom: 1px solid var(--line);
}
.brand { font-weight: 700; text-decoration: none; }
.site-header nav { display: flex; gap: 1rem; }
.profile {
  display: flex;
  gap: clamp(1.5rem, 6vw, 5rem);
  align-items: center;
  padding: 40px 0;
  border-bottom: 1px solid var(--line);
}
.avatar {
  width: clamp(88px, 18vw, 160px);
  aspect-ratio: 1;
  border-radius: 50%;
  object-fit: cover;
}
.profile-copy { flex: 1; }
.profile-heading {
  display: flex;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
}
.profile-heading h1 { margin: 0; font-size: clamp(1.4rem, 4vw, 2rem); }
.button {
  padding: .45rem .9rem;
  border-radius: .45rem;
  background: var(--accent);
  color: white;
  text-decoration: none;
  font-weight: 650;
}
.stats {
  display: flex;
  gap: 1.25rem;
  padding: 0;
  list-style: none;
}
.stats strong { display: block; }
.stats li { color: var(--muted); text-align: center; }
.profile-copy p { max-width: 42rem; }

Build a responsive square gallery

CSS Grid is a good fit for evenly sized tiles. aspect-ratio: 1 keeps each link square even when the column width is calculated automatically. minmax(0, 1fr) prevents long content from forcing a track wider than the grid.

#gallery { padding: 28px 0 64px; }
#gallery h2 {
  margin: 0 0 12px;
  font-size: 1.15rem;
}
.gallery {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 2px;
}
.gallery a {
  display: block;
  aspect-ratio: 1;
  overflow: hidden;
  background: #eee;
}
.gallery img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform .2s ease;
}
.gallery a:hover img,
.gallery a:focus-visible img { transform: scale(1.03); }

@media (width <= 600px) {
  .site-header, main { width: min(100% - 16px, 960px); }
  .profile { align-items: flex-start; gap: 1rem; padding: 24px 0; }
  .stats { justify-content: space-between; gap: .5rem; }
  .gallery { gap: 1px; }
}

The three-column layout is a starting point, not a claim about Instagram’s private implementation. Tune the breakpoint and gap for your content, then inspect the page at an actual narrow phone width, a medium tablet width and a wide desktop width. If you prefer cards that never become too narrow, use an auto-fill pattern such as grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); it changes the number of columns as space allows, so confirm that the result still matches your intended visual rhythm.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Handle images, video and interaction

Crop without distortion

Use object-fit: cover for a consistent mosaic. It crops the excess edges rather than stretching the image. If the subject must never be cropped, use object-fit: contain and accept visible space around some images.

Use useful alternative text

Describe the meaningful subject of each image, as in “River viewed from a stone bridge.” For a purely decorative image, use an empty alt="". Do not repeat the filename or add “image of” unless that wording helps the person using a screen reader.

Add portrait video carefully

A portrait video commonly uses a 9:16 ratio. Keep the wrapper responsive and ensure controls remain reachable:

.reel {
  width: min(100%, 360px);
  aspect-ratio: 9 / 16;
  margin-inline: auto;
}
.reel video,
.reel iframe {
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}

If you use an iframe, give it a concise title, for example title="Maya Chen market walk video". Assistive-technology users can identify the frame from that label. An iframe’s internal dimensions are not automatically exposed to its parent document, so do not assume the embedded document will resize itself perfectly; test it at the widths your audience uses.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Embed real Instagram posts only when that is the requirement

A mockup uses your own markup and assets. Displaying a real post is a separate integration decision. WordPress’s Instagram embed block accepts a post URL and documents that only public posts can be embedded. Its resize control is intended to preserve the post’s aspect ratio on smaller devices. That documented workflow is not a guarantee that every custom HTML setup or every Instagram post will embed.

If you need live posts in a non-WordPress application, check the current official Instagram developer documentation for the exact eligibility, authentication and API rules before designing around it. Do not hard-code an undocumented endpoint or promise that a private post will render.

Add optional ProfilePage structured data

Structured data is metadata for search engines; it does not create the visible profile. For a real person’s profile page, Google’s ProfilePage example uses a ProfilePage object whose mainEntity is a Person. Fields can include name, alternateName, description, image and sameAs. Use it only when the page genuinely describes that person, and replace every sample value.

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "ProfilePage",
  "mainEntity": {
    "@type": "Person",
    "name": "Maya Chen",
    "alternateName": "@mayachen",
    "description": "Street photographer and travel writer.",
    "image": "https://example.com/images/avatar.jpg",
    "sameAs": ["https://example.com/maya"]
  }
}
</script>

Do not use fictional sample values on a real author’s page, and remember that search engines decide whether and how to display structured data.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #4
Sale
Web Design with HTML, CSS, JavaScript and jQuery Set
  • Brand: Wiley
  • Set of 2 Volumes
  • A handy two-book set that uniquely combines related technologies Highly visual format and accessible language makes these books highly effective learning tools Perfect for beginning web designers and front-end developers
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Test and troubleshoot the page

Tiles are not square

  • Confirm aspect-ratio: 1 is applied to the tile, not only the image.
  • Set both image dimensions to 100% and use object-fit: cover.
  • Check for another rule that sets a fixed image height.

The gallery overflows on phones

  • Keep minmax(0, 1fr) in each grid track.
  • Reduce the page’s horizontal padding at the mobile breakpoint.
  • Look for long, unbroken text or an intrinsic-width child inside a tile.

The avatar or images appear stretched

Give the image a square aspect ratio and object-fit: cover. A missing source file produces a broken-image state, so verify the relative path and capitalization on case-sensitive hosts.

The embedded frame is too tall or clipped

Apply an aspect-ratio wrapper, set the iframe to fill it, and include a title. If the provider’s document does not support responsive sizing, its internal layout may still impose limits; test the provider’s documented method rather than trying to override cross-origin content.

Images load slowly

Use appropriately sized files, keep loading="lazy" on below-the-fold images, and avoid sending a multi-megapixel original for a small tile. Lazy loading improves initial work but does not replace image compression or a responsive image strategy.

Keyboard focus is hard to see

Never remove the browser’s focus indicator without adding a stronger replacement. The hover rule above also targets :focus-visible, giving keyboard users a visible change when a tile is focused.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Capture a finished page without configuring a browser

When you need a preview image for a review, documentation page or social card, ScreenshotNeo can capture the rendered URL through one request. Its cleanup step accepts the cookie or consent banner like a visitor and removes more than 60 known consent platforms, newsletter popups and chat widgets; each step can be turned off. Only clean shots are billed. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads and cache hits cost nothing, and the response identifies the result with X-Page-Verdict and X-Billed headers.

Or skip the browser setup

Use the API documented at https://screenshotneo.com/docs/:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com/profile -o profile.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://example.com/profile"}, timeout=90)
open("profile.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://example.com/profile' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

ScreenshotNeo also provides an MCP server with take_screenshot, get_page_info and capture_pdf tools for Claude, Cursor and other MCP clients. You can request full-page captures, a CSS-selected element, dark mode, device presets, custom viewport and retina scale, PDF paper and margin settings, custom CSS or JavaScript, clicks, waits, blocked resource types, headers, cookies, user agents, timezone, geolocation, transparent backgrounds, resizing, chosen cache TTLs, signed links, asynchronous webhooks and bulk capture of up to 100 URLs per call. Its parameter names are compatible with those used by other screenshot APIs, which can simplify migration.

The Free plan includes 1,000 shots each month with no card. Paid plans start at $5 for 3,000 shots; every feature is on every plan, and yearly billing gives two months free. Create a free ScreenshotNeo account to capture your page.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Final implementation checklist

  • Use a real heading hierarchy: page title, profile name and gallery heading.
  • Keep layout rules in an external stylesheet and content in HTML.
  • Make every gallery tile square with CSS Grid and aspect-ratio.
  • Provide meaningful or empty alternative text deliberately.
  • Test narrow, medium and wide viewports, keyboard navigation and slow image loading.
  • Choose a static mockup or a documented public-post embed before promising live content.
  • Add ProfilePage metadata only for a genuine person’s profile.

Frequently Asked Questions

Can I make the gallery without JavaScript?

Yes. The profile and responsive tile layout in this tutorial use HTML and CSS only. Add JavaScript only for behavior such as filtering, a modal viewer or an interactive follow control.

Should every image be the same pixel size?

No. The grid determines the displayed square and object-fit controls cropping. Consistently proportioned source images can reduce unexpected composition changes, but CSS still needs to handle different files.

Is this an Instagram clone?

No. It is an Instagram-style visual pattern. A real Instagram connection, post eligibility and platform rules are separate from the HTML/CSS layout.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.