JSFiddle - React, Tailwind, and code Playground

by ZooeyLai

HTML

<div class="wrap">
        <button class="btn btn-primary" id="loadBtn">Load Products</button>

        <hr>
        
        <ul id="productList" class="collection"></ul>
    </div>

CSS

:root{
        --primary: #4f46e5;
        --secondary:#2563eb;
        --secondary100: #dbeafe;
        --gray800: #333;
        --white: #fff;
        --background:#e4e4e4;
        --warning100 :#ffedd5;
        --warning : #ea580c;
        --danger100 :#fee2e2;
        --danger : #dc2626;
        --success : #059669;
        --success100: #ecfdf5;
    }    
    *,
    *::after,
    *::before {
        padding: 0px;
        margin: 0px;
        font-family: inherit;
        box-sizing: border-box;
        line-height: 1.6;
    }
    html,
    body {
        height: 100vh;
    }

    body {
        font-family: sans-serif;
        font-size: 16px;
        display: flex;
        /* flex-direction: column;
        align-items: center;
        justify-content: center; */
        background-color: aliceblue;
    }
    .wrap{
        margin: 0 auto;
    }
    .btn,button{
        padding: 0.5rem 1rem;
        border: 2px solid transparent;
        border-radius: 0.25rem;
        background-color: var(--gray);
        color: #475569;
        cursor: pointer;
    }
    .btn-primary{
        background-color: var(--primary);
        color: var(--white);
    }
    .btn-primary:hover{
        background-color: #3730a3;
    }
    .btn-outline-primary{
        border-color: var(--primary);
        color: var(--primary);
        background-color: transparent;
    }
    ul,li{
        list-style: none;
    }
    .collection{
        display: grid;
        gap: 2rem;
        grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    }
    .product-card{
        grid-column: span 1;
        /* grid-row: span 2; */
    }
    .product-item__image{
        padding: 2rem;
        max-width: 100%;
        width: 100%;
        aspect-ratio: 1 / 1;
        object-fit: cover;
        border-radius: 0.875rem;
    }
    .product-item__caption{
        display: flex;
        flex-direction: column;   
    }
    .product-item__title{
        margin: 0.5rem 0;
        display:...

JavaScript

let loadBtn = document.querySelector('#loadBtn');
        
        loadBtn.onclick = () =>{
            fetch('https://fakestoreapi.com/products?limit=20')
            .then(res=>res.json())
            .then(
                json=> {
                    //console.log(json);
                    for (const product of json) {
                        let productList = document.querySelector('#productList');
                        //新增元件
                        let li = document.createElement('li');
                        let item = document.createElement('div');
                        let image = document.createElement('img');
                        let caption = document.createElement('div');
                        let title = document.createElement('h3');
                        let price = document.createElement('span');
                        let detailBtn = document.createElement('button');

                        //將創建的元件新增至li底下,並賦予className
                        productList.append(li);
                        li.classList.add('product-card');
                        li.append(item);
                        item.classList.add('product-item');
                        image.classList.add('product-item__image');
                        caption.classList.add('product-item__caption');
                        title.classList.add('product-item__title');
                        price.classList.add('product-item__price');
                        detailBtn.classList.add('btn', 'btn-outline-primary');
                        item.append(image);
                        item.append(caption);
                        caption.append(title);
                        caption.append(price);
                        caption.append(detailBtn);
                        // 綁定資料
                        image.src = product.image;
                        title.textContent = product.title;
                        price.textContent = '$ ' + product.price;
                       ...