Lorem Ipsum, имхо флоаты это прошлый век, только если не верстаешь сайт для какой-нибудь древней компании, на компе у которых стоит IE8. Я бы сделал на гридах или флексах. Во-вторых rem обычно используют для обозначения размера шрифтов, т.е. 1rem всегда будет равен значению font-size заданному в html. И, вроде бы, min-content, max-content и fit-content не дружат с IE
Вешаете много вспомогательных классов, таких как text-left, px-2, mr-1 и тд, но при этом пишите и свои кастомные классы тоже, такие как apSquare и sold.
И тут сразу несколько вопросов:
1) Зачем два разных класса? apSquare и sold? (Возможно, этот вопрос возникает в связи с тем, что код в демке вырван из общего контекста)
2) Почему классы в разном стиле - kebab-case и cammelCase
3) Вы захламляете html кучей классов, но всё равно в css пишете свои правила для этих элементов. В итоге, html распух, чтобы изменить стиль элемента нужно править и в css и в html.
4) Некоторые стили ещё и заинлайнены в style атрибут. (Допускаю что тут была какая то анимация, но это можно сделать не инлайня стили в элементы, а с помощью переключения классов и css transition)
br используется в редких случаях, когда явно нужно сделать перенос текста на новую строку. В остальных стоит делать переносы с помощью css или используя подходящие тэги. Например, p.
тэг small используют не для того, чтобы нарисовать текст меньшего размера, а чтобы указать что он
содержит заявления об отказе от ответственности, оговорки, юридические ограничения или авторские права. small также иногда используется для указания авторства или соответствия лицензионным требованиям.
Позиционировать badge с помощью position в этих карточках не удачный подход, не зависимо от того position relative или absolute. (с одной проблемой Вы уже столкнулись. Другие проблемы ожидают при адаптиве и если нужно будет что-то поменять в карточке. Например, в первой строке будет длинное слово)
У вас однозначно в карточках проглядываются строки. Так и сделайте карточку построчно. Например, с помощью тех же div или p.
Полнейшая каша из единиц измерений. em, rem, проценты.
Если хотите использовать rem, то нужно помнить, что по умолчанию в браузерах 16px, но пользователь может переопределить. И тогда нужно быть готовым к тому, что всё станет больще\меньше. а font-size задавать в rem а не процентах, иначе какой смысл вообще использовать rem.
padding в em Вы сознательно указали? Этот приём используется для динамического изменения размера элемента на основе размера шрифта.
А вот border-radius уже в rem, почему? Зачем?
Куча лишних свойств.
Зачем Вам у .badge
vertical-align
text-align
white-space
у .apSquare
float
width
min-width
height
Почему карточки в целом сделаны спанами, если спан это строчный текстовый элемент, а у Вас очевидно что это блоки с информацией.
JS
Добавляете обработчик клика через атрибут onclick. Так не делают очень давно.
идут в js и пишут, например, в вашем случае, так:
var cards = document.querySelectorAll('.sold') // нашли все элементы с классом sold
cards.forEach(addCardClickHandler) // для каждого элемента вызываем функцию addCardClickHandler
function addCardClickHandler (card) { // которая принимает на вход элемент card (см. документацию для forEach)
card.addEventListener('click', cardClickHandler) // и добавляет элементу обработчик клика функцию clickHandler
}
function cardClickHandler(evt) { // функция обработчика клика принимает на вход объект события.
var cardID = evt.target.getAttribute('id') //evt.target - элемент, на котором произошёл клик. Получили его id.
// код, который у вас в функции showAppInfo
}
Есть ряд причин так делать. Основные из них:
• Более чистый html, а значит и более лёгкий, а значит и загрузится быстрее.
• Разделение html и js привносит порядок. Каждый отвечает за свои задачи. HTML за разметку, JS за функционал. Благодаря этому, так же, например, можно этот html можно спокойно перенести в другой проект, где будет другой Js с этими элементами делать другое.
• Добавление обработчиков таким образом позволяет легко добавлять несколько обработчиков кликов, а так же удалять обработчики, что бывает нужно для оптимизации и в некоторых других целях.
Показанный выше пример можно улучшить, воспользовавшись деллигированием. Деллигирование, это приём, когда обработчик вешаете на родительский элемент, но нацелен обработчик на обработку событий дочерних элементов.
Это делается для производительности ведь так мы только одну функцию обработчик задаём на один элемент, а не на все элементы.
И, например, если элементы в разметке появляются асинхронно. Например, товары в каталоге, которые дорисовываются когда пользователь, скажем, нажимает "показать ещё" - нам не нужно будет добавлять обработчик на новые элементы, так как обработчик уже есть на родительском контейнере.
1) Зачем два разных класса? apSquare и sold? (Возможно, этот вопрос возникает в связи с тем, что код в демке вырван из общего контекста)
Да, действительно, код в примере вырван из контекста, sold это цвет элементов, их несколько в оригинале.
2) Почему классы в разном стиле - kebab-case и cammelCase
Таким образом я решил разделять классы Bootstrap и свои, чтобы не путаться.
4) Некоторые стили ещё и заинлайнены в style атрибут. (Допускаю что тут была какая то анимация, но это можно сделать не инлайня стили в элементы, а с помощью переключения классов и css transition)
Это было что-то вроде анимации. У меня использовался фильтр и карточки не подходящие под фильтр делались opacity: 0.25; и pointer-events: none;
Класс .badge это класс Bootstrap.