Аномалия с отступами у карточки с картинкой
На скриншоте я показал неровности стрелками. Все остальные карточки нормальные. Так же когда выполняется поиск домов, этот аномальный участок смещается в другое место, а все остальные ведут себя как положено, почему такое поведение именно у этой карточки? Как исправить?
HTML:
<div class="main-container-trading">
<div class="container-modal-row">
<div class="modal-row-text">модельный ряд lofthaus</div>
<div class="container-btn-params">
<div class="btn-params-text">Подбор дома
<div class="container-svg-icon-params">
<svg></svg>
</div>
</div>
</div>
<!-- Modal window selection house -->
<div class="container-modal-window-selection-house">
<button class="svg-icon-close-modal-window-selection-house">
<svg></svg>
</button>
<div class="modal-window-selection-house">
<div class="price-selection-house">цена, ₽</div>
<div class="container-select-prices">
<div class="input-label">
<div class="from-to">от</div>
<input class="input filter-input" type="number" placeholder="1 000 000" id="price-from">
<div class="filter-invalid-msg hidden-filter-invalid-msg">Введите цену от</div>
</div>
<div class="input-label">
<div class="from-to">до</div>
<input class="input filter-input" type="number" placeholder="15 000 000" id="price-to">
<div class="filter-invalid-msg hidden-filter-invalid-msg">Введите цену до</div>
</div>
</div>
<div class="square-selection-house">площадь, м2</div>
<div class="container-select-square">
<div class="input-label">
<div class="from-to">от</div>
<input class="input filter-input" type="number" placeholder="50" id="area-from">
<div class="filter-invalid-msg hidden-filter-invalid-msg">Введите площадь от</div>
</div>
<div class="input-label">
<div class="from-to">до</div>
<input class="input filter-input" type="number" placeholder="250" id="area-to">
<div class="filter-invalid-msg hidden-filter-invalid-msg">Введите площадь до</div>
</div>
</div>
<div class="container-btn-apply">
<div class="btn-apply">Применить</div>
</div>
<div class="container-btn-reset hidden-btn-reset">
<div class="btn-reset">Сбросить</div>
</div>
</div>
</div>
<!-- Modal window selection house -->
</div>
<section class="container-items">
<template>
<div class="item">
<img src="" alt="item-1">
<div class="item-details">
<div class="model-house"></div>
<div class="container-info">
<div class="price-house"></div>
<div class="size-house"></div>
</div>
<div class="container-buttons">
<div class="btn-more-detailed">
<div class="btn-style-more-detailed">Подробнее</div>
</div>
<div class="btn-presentation">
<div class="btn-style-presentation">Презентация
<div class="container-svg-icon-pdf">
<svg></svg>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
</section>
<div class="container-show-all-houses">
<button class="show-all-houses">+ Все дома</button>
</div>
<div class="no-results-message hidden-message">По вашему запросу дома не найдены. Попробуйте изменить параметры и повторить поиск заново.</div>
CSS:
.main-container-trading {
background-color: #6a6a6a;
padding-left: 145px;
}
.container-modal-row {
position: relative;
display: flex;
justify-content: space-between;
border-left: 1px solid #b0b0b0;
border-right: 1px solid #b0b0b0;
border-bottom: 1px solid #b0b0b0;
padding: 80px 40px 50px 150px;
margin-right: 146px;
}
.modal-row-text {
color: white;
font-size: 40px;
font-weight: 400;
font-family: sans-serif;
text-transform: uppercase;
letter-spacing: 5px;
line-height: 83px;
}
.container-btn-params {
display: flex;
align-self: center;
height: 40px;
width: 220px;
border: 1px solid #c8b197;
border-radius: 50px;
transition: all .3s ease-in-out;
cursor: pointer;
}
.container-btn-params:hover {
transition: all .3s ease-in-out;
border: 1px solid #8a7565;
}
.btn-params-text {
display: flex;
width: 100%;
justify-content: center;
align-items: center;
gap: 10px;
color: white;
font-size: 20px;
font-weight: 400;
font-family: sans-serif;
line-height: 29px;
}
.container-svg-icon-params {
display: flex;
height: 100%;
align-items: center;
}
.container-modal-window-selection-house {
position: absolute;
right: 40px;
top: 165px;
width: 450px;
background-color: #ffffff;
}
.svg-icon-close-modal-window-selection-house {
position: absolute;
right: 5px;
top: 10px;
border: none;
background: transparent;
display: flex;
width: fit-content;
height: fit-content;
cursor: pointer;
}
.modal-window-selection-house {
padding-top: 25px;
padding-left: 30px;
margin-right: 30px;
margin-bottom: 25px;
}
.price-selection-house {
font-family: sans-serif;
}
.container-select-prices {
display: flex;
gap: 10px;
width: 100%;
padding-top: 5px;
}
.input-label {
display: flex;
flex-direction: column;
}
.from-to {
margin-bottom: 3px;
color: #b7b7b7;
font-family: sans-serif;
cursor: default;
}
.input {
width: 170px;
border: none;
outline: none;
background-color: #e2e2e2;
padding: 5px 10px;
}
.hidden-filter-invalid-msg {
display: none;
}
.filter-invalid-msg {
color: #ff0000;
font-family: sans-serif;
font-size: 14px;
padding-top: 5px;
}
.square-selection-house {
padding-top: 25px;
font-family: sans-serif;
}
.container-select-square {
display: flex;
gap: 10px;
padding-top: 5px;
margin-bottom: 20px;
}
.container-btn-apply {
width: 100%;
height: 40px;
background-color: #c8b197;
cursor: pointer;
}
.btn-apply {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
font-family: sans-serif;
font-weight: 600;
text-transform: uppercase;
font-size: 14px;
}
.container-btn-reset {
display: flex;
justify-content: center;
width: 100%;
padding-top: 15px;
cursor: pointer;
}
.hidden-btn-reset {
display: none;
}
.btn-reset {
color: #000000;
font-family: sans-serif;
font-weight: 600;
font-size: 14px;
text-transform: uppercase;
}
.container-items {
display: flex;
flex-wrap: wrap;
border-right: 1px solid #b0b0b0;
border-left: 1px solid #b0b0b0;
}
.item {
display: flex;
flex-direction: column;
max-width: 536px;
background-size: cover;
border-right: 1px solid #b0b0b0;
}
.item > img {
max-width: 100%;
max-height: 100%;
}
.item-details {
display: flex;
flex-direction: column;
padding: 40px 40px;
border-bottom: 1px solid #b0b0b0;
}
.model-house {
font-size: 36px;
line-height: 49px;
letter-spacing: 0.15em;
text-transform: uppercase;
color: white;
font-weight: 400;
font-family: sans-serif;
transition: all 0.3s ease;
cursor: pointer;
}
.model-house:hover {
transition: all 0.3s ease;
color: #c8b17a;
}
.container-info {
display: flex;
justify-content: space-between;
}
.price-house {
display: flex;
justify-content: space-between;
color: white;
font-weight: 700;
font-family: sans-serif;
line-height: 75px;
font-size: 36px;
}
.size-house {
color: #DE0D0D;
font-weight: 700;
line-height: 78px;
font-size: 36px;
font-family: sans-serif;
}
.container-buttons {
display: flex;
width: 100%;
justify-content: space-between;
padding-top: 10px;
}
.btn-more-detailed {
width: 150px;
height: 55px;
border: 3px solid #c8b197;
cursor: pointer;
}
.btn-style-more-detailed {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
color: #ffffff;
font-size: 16px;
font-weight: 700;
font-family: sans-serif;
line-height: 18px;
text-transform: uppercase;
transition: all .3s ease-in-out;
}
.btn-more-detailed:hover .btn-style-more-detailed {
transition: all .3s ease-in-out;
background-color: #c8b197;
color: #000000;
}
.btn-presentation {
background-color: #c8b197;
width: 205px;
height: 60px;
cursor: pointer;
}
.btn-style-presentation {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
gap: 10px;
color: #000000;
font-size: 16px;
font-family: sans-serif;
font-weight: 700;
text-transform: uppercase;
line-height: 18px;
}
.container-svg-icon-pdf {
display: flex;
}
.container-show-all-houses {
text-align: center;
margin-right: 146px;
padding-top: 40px;
border-left: 1px solid #b0b0b0;
/*border-top: 1px solid #b0b0b0;*/
border-right: 1px solid #b0b0b0;
}
.show-all-houses {
background: transparent;
border: none;
padding: 0;
margin-bottom: 30px;
font-weight: 400;
font-size: 18px;
line-height: 19px;
font-family: sans-serif;
color: #ffffff;
border-bottom: 1px solid #ffffff;
transition: all .3s ease-in-out;
cursor: pointer;
}
.show-all-houses:hover {
transition: all .3s ease-in-out;
border-bottom: 1px solid #c8b197;
color: #c8b197;
}
.hidden {
display: none;
}
.no-results-message {
padding: 40px 35px;
margin-right: 146px;
text-align: center;
border-left: 1px solid #b0b0b0;
border-right: 1px solid #b0b0b0;
color: #ffffff;
font-family: sans-serif;
}
.hidden-message {
display: none;
}
JS:
const allHouses = [
{
id: 1,
title: 'LOFTHAUS R70',
price: 4465000,
area: 70,
img: 'https://topttedhbiu-dejlbfuh4uk.github.io/Layout_LoftHouse/images/item-1.jpg',
},
// Добавьте тут ещё 10 домов, на меня кричат из-за спама
];
const containerBtnApplyEl = document.querySelector('.container-btn-apply');
const containerBtnResetEl = document.querySelector('.container-btn-reset');
const filterInputEls = [...document.querySelectorAll('.filter-input')];
const filterInvalidMsgEls = [...document.querySelectorAll('.filter-invalid-msg')];
const templateEl = document.querySelector('section > template');
const containerItemEls = document.querySelector('.container-items');
const addPointToNumber = (house) => {
house.price = new Intl.NumberFormat('ru-RU', {}).format(house.price).replace(/\s/g, '.');
};
const renderHouse = (house, index) => {
const houseTemplate = templateEl.content.firstElementChild.cloneNode(true);
if (index >= 9) {
houseTemplate.classList.add('hidden');
}
houseTemplate.querySelector('img').src = house.img;
houseTemplate.querySelector('.model-house').innerText = house.title;
addPointToNumber(house);
houseTemplate.querySelector('.price-house').innerText = `${house.price} ₽`;
houseTemplate.querySelector('.size-house').innerText = `${house.area}м2`;
containerItemEls.append(houseTemplate);
};
allHouses.forEach((house, index) => {
renderHouse(house, index);
});
const showAllHousesEl = document.querySelector('.show-all-houses');
const hiddenHouseEls = [...document.querySelectorAll('.hidden')];
const containerShowAllHousesEl = document.querySelector('.container-show-all-houses');
const buttonEl = document.querySelector('.container-show-all-houses > button');
showAllHousesEl.addEventListener('click', () => {
hiddenHouseEls.forEach(hiddenHouse => {
hiddenHouse.classList.remove('hidden');
});
buttonEl.remove();
containerShowAllHousesEl.classList.remove('container-show-all-houses');
});
const clearContainerItemEls = () => {
[...containerItemEls.children].forEach(el => el.remove());
};
const getHouses = (filters) => {
const response = allHouses.filter(house => {
// house.price = house.price.replace(/\./g, '');
// house.price = parseInt(house.price, 10);
for (const filterKey in filters) {
const filterVal = filters[filterKey];
switch (filterKey) {
case 'price': {
if (house.price < filterVal.from) return false;
if (house.price > filterVal.to) return false;
break;
}
case 'area': {
if (house.area < filterVal.from) return false;
if (house.area > filterVal.to) return false;
break;
}
}
}
return true;
});
return response.length ? response : null;
};
const isValidFilterInputEl = (filterInputEl) => {
return !!filterInputEl.value || filterInputEl.value === 0;
};
const validateFilterInputEl = (filterInputEl) => {
const isValid = isValidFilterInputEl(filterInputEl);
filterInputEl.filterInvalidMsgEls.classList.toggle('hidden-filter-invalid-msg', isValid);
return isValid;
};
filterInputEls.forEach((filterInputEl, index) => {
filterInputEl.filterInvalidMsgEls = filterInvalidMsgEls[index];
filterInputEl.addEventListener('input', () => {
validateFilterInputEl(filterInputEl);
});
});
const applyElClickHandler = () => {
filterInputEls.forEach(filterInputEl => {
if (!validateFilterInputEl(filterInputEl)) {
return false;
}
});
const filters = {};
filterInputEls.forEach(filterInputEl => {
const [filterKey, filterSubKey] = filterInputEl.id.split('-');
const filter = filters[filterKey] = filters[filterKey] || {};
filter[filterSubKey] = filterInputEl.value;
});
const houses = getHouses(filters);
clearContainerItemEls();
buttonEl.remove();
containerShowAllHousesEl.classList.remove('container-show-all-houses');
if (!houses) {
const noResultsMessageEl = document.querySelector('.no-results-message');
noResultsMessageEl.classList.remove('hidden-message');
return false;
}
houses.forEach(house => {
renderHouse(house);
});
};
Ответы (1 шт):
У вас картинки имеют разную высоту. В связи с этим могут быть отличия в высоте карточек.
Размеры картинок на странице:
1 - 536x301.5
2 - 536x301.77
3 - 536x300.38 <- ниже остальных
Можно выровнять их высоту, например, добавлением обёртки для img в HTML:
<div class="item-img-wrapper"> <!-- Добавялем wrapper -->
<img src="" alt="item-1">
</div>
и заменой текущих стилей:
.item > img {
max-width: 100%;
max-height: 100%;
}
на следующие:
.item-img-wrapper > img {
width: 100%; /* меняем max-width на width для того, чтобы изображение максимально растягивалось */
height: 100%;
object-fit: cover; /* для того, чтобы изображение вписывалось в обёртку */
}
.item-img-wrapper {
max-width: 100%; /* чтобы изображение и обёртка были не шире родительского контейнера */
aspect-ratio: 1.8;
}
aspect-ratio тут используется для установки равных пропорций для изображений. можно также заменить это свойство на явное указание высоты обёртки
Таким образом картинки на странице будут иметь равные пропорции.