Crafting a Responsive Product Showcase with HTML, CSS, and Open Props


By Faraz -

Learn how to create a stunning and responsive product showcase using HTML, CSS, and the Open Props Framework.

Crafting a Responsive Product Showcase with HTML, CSS, and Open Props.jpg

Table of Contents

  1. Project Introduction
  2. HTML Code
  3. CSS Code
  4. Preview
  5. Conclusion

Welcome to our comprehensive guide on crafting a responsive product showcase! In today's digital age, where users access websites on a multitude of devices, ensuring a seamless and visually appealing experience is paramount. This tutorial will walk you through the step-by-step process of building a captivating product showcase using HTML, CSS, and the powerful Open Props Framework.

Whether you're a seasoned developer looking to enhance your skills or a newcomer eager to dive into the world of web development, this guide is tailored for you. Let's embark on this journey together, creating a product showcase that not only meets but exceeds the expectations of modern web users. Get ready to elevate your web design game and embrace the power of responsive, user-centric development. Let's begin!

What is Open Props Framework?

Open Props is an open-source, low-level CSS framework that provides a design system and structure for CSS. It's built entirely on CSS variables, which makes it highly customizable and adaptable to any design system.

Source Code

Step 1 (HTML Code):

Start by creating the basic structure of your product showcase using HTML. Define the essential elements such as headers, images, and product descriptions to provide a solid foundation for your responsive design.

Let's break down the code:

1. <!DOCTYPE html>: Declares the document type and version of HTML, which is HTML5 in this case.

2. <html lang="en">: Defines the root HTML element with the language attribute set to English.

3. <head>: Contains meta-information about the document, such as character set, viewport settings, title, and external stylesheet link.

  • <meta charset="UTF-8">: Specifies the character encoding as UTF-8.
  • <meta http-equiv="X-UA-Compatible" content="IE=edge">: Sets the document mode and compatibility for Internet Explorer.
  • <meta name="viewport" content="width=device-width, initial-scale=1.0">: Defines the viewport properties for responsive design.
  • <title>Product Showcase</title>: Sets the title of the webpage.
  • <link rel="stylesheet" href="styles.css">: Links an external CSS stylesheet named "styles.css" to style the webpage.

4. <body class="block-center-center">: Contains the content of the webpage with a specific class applied to the body element, which will be used for styling.

5. <section class="Product inline-center-center gap-4">: Represents a section with a class "Product" and specific styling classes for centering and creating a gap.

6. <a href="#" class="Visual block-center-center">: Defines a hyperlink with a placeholder "#" as the href and specific styling classes. This is used for a visual element or image gallery.

7. <form action="" class="Form block-start-start gap-4">: Introduces a form with an empty action attribute and styling classes. It includes various form elements for ordering a product.

  • <h3>CHEETAH GLAM HOODIE</h3>: Displays the product name as a heading.
  • <div class="Price">$80.00</div>: Shows the price of the product.
  • <fieldset class="TagList inline-wrap gap-2">: Contains a legend and a list of radio buttons for selecting the product size.
  • Radio button options for different sizes (S, M, L, XL, 2XL, 3XL).
  • <fieldset id="quantity-list" class="QtField inline-center-center gap-2">: Provides a label and a dropdown menu for selecting the quantity of the product.
  • <select> element with options for quantities from 1 to 10.
  • Various buttons and small text for pre-ordering and indicating the shipping date.
  • <p>JUMBO SCREENPRINTED GRAPHIC</p>: Describes a feature of the product using a paragraph.

8. The closing tags </form> and </section> end the form and section elements, respectively.

9. The closing tags </body> and </html> close the body and HTML elements, respectively.

Step 2 (CSS Code):

Add style and visual appeal to the product showcase using CSS. Integrate the Open Props Framework to streamline the styling process and achieve a cohesive design across different screen sizes.

Let's break down the code:

1. @import Statements:

  • The code starts with several @import statements. These are used to include external CSS files or modules into the current stylesheet.
  • open-props is imported as a layer of design.system.
  • normalize.dark.min.css from open-props is imported as a layer of base.normalize.
  • Fonts from Google Fonts are imported.
  • utilities.css from layout-craft is imported as a layer of design.utilities.

2. @layer Statements:

  • The @layer statements are used to define named layers for organizing CSS rules.
  • base.normalize-overrides layer is defining some global CSS variables for colors, font, and other properties. It also applies some styling to the body element.
  • base.components layer contains various component styles like .Product, .Form, .TagList, .Visual, and .Button. It also defines a keyframe animation named flip.

3. Component Styles:

  • Product: Specifies padding and responsive grid behavior for a component with the class .Product. It adjusts the layout based on the screen width.
  • Form: Styles for form elements, including a nested .Price class.
  • TagList: Defines styles for a tag list, including tag toggles with label and input elements. It utilizes CSS variables for sizing and styling.
  • Visual: Styles for a visual component, including background gradient, border-radius, aspect ratio, and animations. It uses the conic-gradient for the background and a keyframe animation named flip.
  • Button: Styles for a generic button, setting font size, weight, padding, and border radius. It includes styles for a valid form state with a primary button.

4. Animations:

  • The flip keyframe animation is defined to create a fading in and out effect for the elements inside the .Visual component.

5. Responsive Design:

  • The code includes some media queries (@media) to make the layout responsive for screens with a width less than 900 pixels.
@import '' layer(design.system);
@import ''

@import url('[email protected]&family=Pacifico&display=swap');

@import '[email protected]/dist/utilities.css'

@layer base.normalize-overrides {
  :root {
    font-family: 'Inter', sans-serif;
    --surface-1: black;
    --surface-2: oklch(0.19 0 0);
    --text-1: white;

    --brand-1: oklch(0.65 0.24 16.93);
    --brand-2: oklch(0.77 0.1 90);

  body {
    -webkit-font-smoothing: antialiased;

@layer base.components {
  .Product {
    padding: var(--size-3);
    @media (width < 900px) {
      grid-auto-flow: row;

      .Visual {
        inline-size: min(100%, 500px);

  .Form {
    & h3 {
      max-inline-size: var(--size-content-1);
      text-wrap: balance;
    & fieldset {
      padding: 0;
      border: none;
    & small {
      max-inline-size: var(--size-content-3);

    .Price {
      font-weight: var(--font-weight-6);

  .TagList {
    --_gap: var(--size-1);

    max-inline-size: var(--size-content-2);

    & > legend {
      margin-block-end: var(--size-2);

    > .TagToggle {
      box-shadow: var(--shadow-1);

      > * {
        grid-area: 1/1;

      > label {
        padding-inline: var(--size-3);
        padding-block: var(--size-1);

        border: var(--border-size-2) solid white;
        border-radius: var(--radius-round);
        cursor: pointer;
        transition: 0.1s var(--ease-3);

      > input {
        appearance: none;
        background: none;
        border: none;
        inline-size: 100%;
        block-size: 100%;
        border-radius: var(--radius-round);

        &:checked ~ label {
          background-color: white;
          color: var(--surface-1);

        &:not(:checked):is(:focus-within, :hover) ~ label {
          background-color: white;
          color: var(--surface-1);

  .Visual {
    margin: 0;
    padding: 0;

    background: conic-gradient(
      from 90deg at 50% 0%,
      hsl(0, 0%, 2%),
      hsl(0, 0%, 8%),
      hsl(0, 0%, 2%)
    border-radius: var(--radius-3);
    inline-size: 500px;

    aspect-ratio: var(--ratio-square);

    > picture {
      transition: 0.1s ease;

    > * {
      grid-area: 1/1;

    > picture {
      animation: flip 2s step-end infinite;

    > picture:last-child {
      animation-delay: 1s;

    &:hover > picture {
      animation-play-state: paused;

  @keyframes flip {
    0% {
      opacity: 0;
      visibility: hidden;
    50% {
      opacity: 1;
      visibility: visible;
    100% {
      opacity: 0;
      visibility: hidden;

  .Button {
    font-size: var(--font-size-1);
    font-weight: var(--font-weight-6);
    padding: var(--size-2) var(--size-4);

    white-space: nowrap;
    cursor: not-allowed;

    border-radius: var(--radius-5);
    transition: background-color 0.2s ease;

  .Form:valid {
    .Button.Primary {
      background-color: var(--brand-1);
      color: var(--text-1);
      cursor: pointer;

      &:hover {
        background-color: oklch(0.72 0.24 17.52);

Final Output:

Crafting a Responsive Product Showcase with HTML, CSS, and Open Props.gif


In conclusion, this tutorial has guided you through the process of creating a responsive product showcase using HTML, CSS, and the innovative Open Props Framework. We've explored the importance of responsive design in the contemporary web environment and delved into the intricacies of crafting a seamless user experience across various devices.

By understanding the fundamentals of HTML and CSS and harnessing the capabilities of the Open Props Framework, you've gained the tools to develop a visually appealing and functional product showcase. Remember, responsive design is not just a feature; it's a necessity in a world where users access content on diverse screens.

Thank you for joining us on this tutorial. We hope it has equipped you with the knowledge and confidence to build impressive, responsive product showcases. Stay curious, stay creative, and keep pushing the boundaries of web development. Happy coding!

Code by: Arby

That’s a wrap!

I hope you enjoyed this post. Now, with these examples, you can create your own amazing page.

Did you like it? Let me know in the comments below 🔥 and you can support me by buying me a coffee.

And don’t forget to sign up to our email newsletter so you can get useful content like this sent right to your inbox!

Faraz 😊

End of the article

Subscribe to my Newsletter

Get the latest posts delivered right to your inbox

Latest Post