Эффект расширения карты App Store

CSS
Эффект расширения карты App Store

Привет, меня зовут Стивен.

В этом эпизоде ​​мы будем имитировать эффект расширения карты в App Store:

Я хотел сделать это только с помощью HTML и CSS, но в итоге пришлось использовать JavaScript, так что давайте начнем.

Видеоверсия этого урока находится по адресувоооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооо поДобро пожаловать три подряд внимание!

часть HTML

Откройте редактор CodePen и сначала создайте структуру HTML. добавить один<div>, классcard, добавить картинку внутрь, использовать источник картинкиUnsplashСлучайные картинки с сайта. Затем добавьте заголовок, например, текст «ПРИЛОЖЕНИЕ ДНЯ».

затем добавьте<div>, классcontent-wrapper, добавьте еще<div>, классcontent. Зачем вам два слоя<div>Ну, мы вернемся к этому позже.

Добавьте внутрь новый текст, сгенерируйте несколько поддельных символов, а затем используйте<p>Этот тег абзаца упорядочивает их.

Структура HTML примерно такая, а затем часть CSS.

Разделы CSS

новый:rootселектор, чтобы установить базовый размер текста на15px. шрифтfont-familyустановить какHelvetica.

Затем определите некоторые переменные. Поскольку этот эффект подходит для отображения по ширине мобильных телефонов, я установлю ширину веб-страницы на480px,определение--body-widthда480px. Затем определите размер карты,--card-widthопределяется как420px,--card-heightопределяется как280px.

Переопределить высоту картинки, высоту неразвернутой картинки--img-heightопределяется как226px, высота развернутого изображения--img-height-expandedопределяется как320px. Наконец, цвет фона установлен на темно-серый.

Присоединяйсяbodyселектор, установите ширину наvar(--body-width), цвет фона установлен на светло-серый,marginустановить какauto, который будетbodyУстановите.

Затем отцентрируйте содержимое слева и справа, установитеdisplayдаflex,flex-directionустановить какcolumn,align-itemsустановить какcenter,Потомmin-heightустановить как100vh. Добавьте немного сверху и снизуpadding, установить как1rem 0.

Присоединяйся.cardселектор с шириной, установленной наvar(--card-width), высота установлена ​​наvar(--card-height), цвет фона установлен на белый.

Пока я не вижу белого фона, потому что размер этого изображения сравнивается сcardКонтейнер больше и полностью закрыт. новый.card imgселектор, будетdisplayустановить какblock, ширина установлена ​​на100%, затем установите высотуvar(--img-height), в это время вы обнаружите, что пропорции изображения неверны, добавьтеobject-fit: coverЭтот параметр позволяет масштабировать изображение для заполнения.

назад.card, добавьте закругленные углы,border-radiusустановить как1rem. Добавьте еще немного теней, и цвет станет очень светло-серым.

Затем вы обнаружите, что верхний левый угол и верхний правый угол изображения не имеют закругленных углов, мы можем установить это в.cardПрисоединяйсяoverflow: hidden,Позволять.cardЗакройте лишнее и превратите изображение в закругленные углы. Однако с момента открытия.card, закругленные углы становятся прямыми углами, иoverflowНевозможно применить анимацию, поэтому здесь она использоваться не будет.overflow, но вimgПримените настройки закругленных углов непосредственно к верхнему левому и верхнему правому углам.

Затем установите стиль заглавного слова и добавьте.card h4селектор, будетmarginустановить как0, установлен размер текста1.5rem; сделать шрифт жирным; добавитьpadding, верх и низ настроены на0.8rem, левый и правый настроены на1.2rem; цвет фона установлен на белый.

Я хочу, чтобы текст был более центрирован по вертикали, установитеline-heightдля2rem, затем немного уменьшите кернинг,letter-spacingустановить как-0.5px, а потомpadding-bottomустановить как0, не покроет.cardУглы закруглены.

Дальше идет часть настройки контента, добавляйте их отдельно.card .content-wrapperа также.card .content-wrapper .contentСелектор.

Почему мы разделяем.content-wrapperа также.contentШерстяная ткань? Поскольку, когда карта нажимается для расширения, высота контейнера содержимого будет рассчитана и установлена ​​JavaScript, поэтому мы применим расширенную анимацию к внешнему слою, а настройка высоты будет применена к внутреннему слою.

Таким образом, при закрытии карты нет необходимости восстанавливать настройку высоты, суть в том, чтобы писать меньше JavaScript и позволить это делать CSS.

установить первым.contentстиль, добавитьpadding, установить сверху и снизу01.2rem; установить белый цвет фона; затемoverflowустановить какauto, так что когда содержимое превышает высоту, заданную контейнером, страницу можно будет прокручивать. Позже высота контейнера будет контролироваться JavaScript.

Стиль внутреннего абзаца также корректируется, добавляя.card pселектор, чтобы установить размер текста на1.2rem, высота строки устанавливается равной1.5remВот и все.

затем к.content-wrapper, заданная высота0, затем добавьтеoverflow: hidden, поэтому часть за пределами контейнера будет скрыта.

Теперь, когда стиль карточки почти такой же, перед запуском функции расширения скопируйте еще несколько карточек в HTML. Чтобы отображались разные случайные изображения, я добавлю разные параметры к URL-адресу Unsplash и добавлю 1, 2, 3, 4 сзади, и все.

затем к.cardв селекторе добавитьmargin: 1rem 0Немного разделите карты.

часть JavaScript

Далее, чтобы разобраться с расширением карты, я добавлюclassИзменить его стиль, чтобы добиться эффекта расширения. Чтобы сократить объем написания JavaScript, я бы добавил jQuery, открыл «Настройки», добавил jQuery в раздел «JS» и нажал «Сохранить и закрыть».

В разделе JavaScript добавьте.cardизon('click')мероприятие. определить переменную,cardназначатьe.currentTarget, то, что вы получаете здесь, это щелчок.cardсебя.

тогда присоединяйтесь$(card).toggleClass('active'), так что когда карта не имеетactiveОн будет добавлен при добавлении класса, а иногда будет удален для достижения эффекта расширения и свертывания.

Настройка стилей CSS

Теперь вы можете вернуться в раздел CSS и установитьactiveв состоянииcardстиль. Добавьте 4 селектора, которые.card.activeизменить положение карты,.card.active h4стиль заголовка,.card.active imgстиль изображения и.card.active .content-wrapperРазверните текст.

Первое, что я хочу сделать, это расширить текст, в.content-wrapperВ селекторе добавьтеheight: 100vh, затем нажмите на карточку, чтобы попробовать:

Видно, что текст успешно расширился, а затем и карточка сдвинулась.На самом деле, помимо перемещения, мы еще немного увеличим карточку, чтобы заполнить ширину слева и справа.

существует.cardдобавить в селекторtransform, первый наборtranslateY(), на сколько двигаться вверх, собственно, нам нужно рассчитать расстояние между элементом и вершиной, чтобы она могла быть близко к вершине, мы временно устанавливаем ее как-300px, который будет рассчитан позже.

Добавить ещеscale()Сделайте карту немного больше, коэффициент увеличенияbodyШирина, деленная на ширину карты, т.е.480Поделить на420,transform-originЦентральная точка устанавливается на50% 0, нажмите один раз, вы увидите, что уже есть 80% эффекта.

Сначала выполните тонкую настройку стиля, в развернутом состоянии удалите настройки закругленных углов, а также удалите настройки закругленных углов изображения. Затем сделайте изображение немного выше:

Добавьте некоторые настройки перехода анимации, вернитесь к.cardселектор, присоединяйтесьtransition: .3s all, ускорение равноcubic-bezier(0, 1, 0.95, 1.05):

Вы можете открыть инструменты разработчика и увидеть вот такой линейный график ускорения:

Вы можете попробовать потянуть эту кривую, вы можете добиться различных эффектов ускорения, моя настройка может сделать так, чтобы она имела небольшой эффект отскока, когда она открывается и закрывается.

Рассчитать водоизмещение

Вернемся к части JavaScript, мы хотим рассчитать расстояние карты от вершины. определить переменнуюcard_offset_scrolltop, картыoffset().topминусwindow.scrollTop(), что является расстоянием прокрутки. Затем задаем результат расчета на карточку в виде CSS-переменной, имя переменной меняется на--data-offset-top, установленное значение умножается на-1и добавитьpxБлок.

Возвращаясь к разделу CSS, мы.card.activeВнутриtransformизtranslateY()внутри-300pxзаменитьvar(--data-offset-top), а затем нажмите, чтобы проверить:

Может быть успешно размещен в верхней части страницы.

продолжать оптимизировать

Вы думали, что это было сделано? Не останавливайтесь, продолжайте оптимизировать остальное.

Теперь после открытия карты прокрутка страницы устанет, поэтому после открытия карты сделайте паузуbodyпрокрутка.

В части JavaScript определите, имеет ли картаactiveЭтот класс, то есть в открытом состоянии, находится вbodyприсоединиться кnoscrollЭтот класс, наоборот он удаленnoscrollэтот класс.

Откройте раздел CSS и добавьтеbody.noscrollселектор, наборoverflow: hidden, чтобы добиться эффекта предотвращения прокрутки.

Затем разберитесь с прокручиваемой частью текста, на стороне JavaScript определитеheightпеременная, назначенная какwindow.height(). Чтобы вычислить высоту текстовой части, используйтеwindowВычтите высоту изображения из высоты, а затем вычтите высоту заголовка.

Затем примените эту высоту к.contentНа контейнере проверьте это:

Почему нельзя докрутить до конца? Это значит, что расчет высоты неверен, а что не так с расчетом?

Дайте три секунды подумать об этом, 3, 2, 1.

Это связано с нашей картой, черезtransformизscale()Он увеличен, поэтому при расчете высоты картинки и заголовка умножайте коэффициент увеличения.

определить переменную с именемratio, назначенный как480/420, умножьте высоту изображения и заголовка наratio, и, наконец, разделить сумму на этоratio, и проверьте это снова:

На этот раз высота правильная.

Выполните окончательную тонкую настройку, и при прокрутке вы найдете нижнюю часть ПРИЛОЖЕНИЯ ДНЯ.paddingчуть меньше, в.card.active h4добавить вpadding-bottom: .8rem:

Затем добавьте несколько эффектов затухания при появлении текста, в.content-wrapperДобавьте настройки прозрачностиopacity: .8,transition: .3s all ease-out:

расширяясь снова.content-wrapperдобавить вopacity: 1,transition: .3s all ease-in, так что будут разные эффекты ускорения при открытии и закрытии.

Давайте посмотрим на завершенный эффект этого случая

Это все для этого эпизода.


Исходный код для этого случая находится накод спрей.IO/стивен класс/боюсь...

Ваша поддержка-моя мотивация, пожалуйста, обратите вниманиеМинимальный класс CodingStartup, давайте работать вместе!