- index.html
- style.css
- script.js
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Catalog | Glacie</title>
<link rel="stylesheet" href="gllacy/setting.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<ul class="goods">
</ul>
<script src="script.js"></script>
</body>
</html>
CSS
.goods {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
width: 580px;
margin: 20px auto;
padding: 0;
list-style: none;
}
.good {
position: relative;
display: flex;
width: 220px;
flex-direction: column;
align-items: center;
min-width: 267px;
margin-bottom: 35px;
padding: 15px 10px;
color: #ffffff;
}
.good--available::before,
.good--unavailable::before {
position: absolute;
top: 10px;
right: 10px;
z-index: 1;
display: inline-block;
padding: 5px 8px;
font-weight: bold;
font-size: 16px;
vertical-align: top;
text-align: center;
color: #ffffff;
background-image: linear-gradient(#e74a35 0%, #f26843 100%);
border: none;
border-radius: 5px;
}
.good--hit {
width: 100%;
order: -1;
background-color: rgba(255, 255, 255, 0.2);
border-radius: 5px;
box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.4);
}
.good--hit::after {
content: "";
position: absolute;
top: 5px;
left: 5px;
z-index: 1;
width: 61px;
height: 61px;
margin: auto;
background-image: url("gllacy/hit.svg");
background-repeat: no-repeat;
}
.good--unavailable {
filter: grayscale(1) opacity(0.8);
}
.good--unavailable::before {
content: "Out of stock";
}
.good--available::before {
content: "In stock";
}
.good__price {
position: absolute;
top: 180px;
left: 55%;
width: 270px;
margin: 0;
margin-bottom: 20px;
font-weight: bold;
font-size: 40px;
line-height: 40px;
text-shadow: 0.5px 0.866px 3px rgba(49, 50, 53, 1);
transform: translateX(-140px);
}
.good__description {
order: 1;
max-width: 220px;
margin: 8px 11px;
font-weight: 400;
font-size: 18px;
line-height: 22px;
text-align: center;
color: #ffffff;
text-decoration: underline;
text-decoration-color: rgba(255, 255, 255, 0.4);
}
.good__image {
padding: 10px;
background-image: url("gllacy/lollipop.svg");
background-repeat: no-repeat;
background-size: 450px;
background-position: -45px -45px;
}
.good__special-offer {
position: relative;
order: 2;
max-width: 190px;
margin: 5px 11px;
padding-left: 5px;
font-weight: 700;
font-size: 20px;
line-height: 22px;
text-align: center;
color: rgba(255, 239, 213, 1);
text-shadow: 0.5px 0.866px 3px rgba(49, 50, 53, 0.5);
}
.good__special-offer::before {
position: absolute;
content: "*";
top: 0;
left: 0;
}
JavaScript
var cardsData = [
{
inStock: true,
imgUrl: 'gllacy/choco.jpg',
text: 'Creamy coffee with chocolate chip',
price: 310,
isHit: true,
specialOffer: 'Double syrup for free!'
},
{
inStock: false,
imgUrl: 'gllacy/lemon.jpg',
text: 'Creamy lemon with caramel powder',
price: 125,
isHit: false
},
{
inStock: true,
imgUrl: 'gllacy/cowberry.jpg',
text: 'Creamy with cranberry jam',
price: 170,
isHit: false
},
{
inStock: true,
imgUrl: 'gllacy/cookie.jpg',
text: 'Creamy with cookie dough',
price: 250,
isHit: false
},
{
inStock: true,
imgUrl: 'gllacy/creme-brulee.jpg',
text: 'Creamy creme brulee',
price: 190,
isHit: false
}
];
/* Technical assignment
Meow! Do you remember the ice cream shop? You need to create product cards based on the data received from the server.
The data is an array of cardsData objects, one element corresponds to one product. Each object has the following properties:
- inStock: availability of product. If the value is true, the product is available (for such a product, the designer created the good--available class); if it’s false, the product is not available (product with the good--unavailable class).
- imgUrl: link to the product image.
- text: is product name.
- price: is price.
- isHit: defines if the product is a bestseller. If the value is true, the product is a bestseller. For such a product, class good--hit was created.
- specialOffer: a special offer, which is only available for bestsellers. Must be in a paragraph with class good__special-offer and must be the last child element in the card.
Here is an example of the layout of one card in the directory:
<ul class="goods">
<li class="good">
<h2 class="good__description">Creamy coffee with chocolate chip</h2>
<img class="good__image" src="gllacy/choco.jpg" alt="Creamy coffee with chocolate chip">
<p class="good__price">110 ₽/kg</p>
</li>
…
</ul>
Note that the text in the alt attribute of the image must be the same as the name of the product.
Create function renderCards, which will accept an input data array, call it by transferring cardsData and draw ice cream cards on the page.
*/
Console
var cardsData;
var makeElement = function (tagName, className, text) {
var element = document.createElement(tagName);
element.classList.add(className);
if (text) {
element.textContent = text;
}
return element;
};
var createCard = function (good) {
var listItem = makeElement('li', 'good');
var availabilityClass = 'good--available';
if (!good.inStock) {
availabilityClass = 'good--unavailable';
}
listItem.classList.add(availabilityClass);
var title = makeElement('h2', 'good__description', good.text);
listItem.appendChild(title);
var picture = makeElement('img', 'good__image');
picture.src = good.imgUrl;
picture.alt = good.text;
listItem.appendChild(picture);
var price = makeElement('p', 'good__price', good.price + ' ₽/kg');
listItem.appendChild(price);
if (good.isHit) {
listItem.classList.add('good--hit');
var specialOffer = makeElement('p', 'good__special-offer', good.specialOffer);
listItem.appendChild(specialOffer);
}
return listItem;
};
var renderCards = function (goods) {
var cardList = document.querySelector('.goods');
for (var i = 0; i < goods.length; i++) {
var cardItem = createCard(goods[i]);
cardList.appendChild(cardItem);
}
};
renderCards(cardsData);