Как да направите персонализирани свойства (CSS променливи) по-динамични

Силата на персонализираните свойства идва от две уникални способности:

способността да променяте стойности с помощта на JS.

Персонализираните свойства стават още по-мощни оръжия, когато се комбинират с други съществуващи CSS концепции като calc().

по-динамични

Практически курс за оформление на адаптивен уебсайт от нулата!

Вземете курса и научете как да създавате модерни уебсайтове в HTML5 и CSS3

С персонализираните свойства можете ефективно да правите това, което променливите в препроцесорите като Sass могат да правят. Можете да зададете глобални и локални стойности за променливи и след това да ги използвате във вашия код. Но благодарение на каскадирането можете да задавате нови стойности на свойства в по-конкретни правила.

Каскадирането може да доведе до няколко интересни подхода, описани от Violet Peña в преглед на основните предимства на променливите и от Chris в преглед на опциите за тематизиране на уебсайтове.

Хората говорят за тези предимства на каскадирането от години, но те често се забравят, въпреки факта, че това е ключова характеристика, която ги отличава от препроцесорите. Амелия Белами-Ройдс говори за това и го използва още през 2014 г. със SVG, Филип Уолтън забеляза почти всички основни предимства на каскадирането през 2015 г., а Грегор Адамс показа как могат да се използват в минимална мрежова рамка. Тези каскадни предимства са най-лесният начин да започнете с персонализирани свойства, без да забравяте прогресивното подобрение.

ДОБРЕ. Разбрахме, че персонализираните свойства ни дават собствена функционалност на предпроцесора, както и нови случаи на употреба чрез каскадно свързване. Но има ли нещо в тях, което не сме могли да направим преди? Със сигурност!

Персонализиране на имота

Всички имоти от много частисега може да се използва по различни начини. Множество фонове могат да бъдат разделени и множество продължителности на прехода могат да бъдат разделени. Вместо transform: translateX(10vmin) rotate(90deg) scale(.8) translateY(5vmin) можете да дефинирате едно правило с няколко персонализирани свойства и след това да промените техните стойности поотделно.

Задаването на параметрите ще отнеме известно време, но след това няма да е необходимо да променяте всяка функция за трансформиране ръчно на правилния клас/селектор. След това всеки или всички класове за елемента .view могат да бъдат добавени към маркирането и свойството transform ще се промени от само себе си, както е показано в демонстрационния код по-горе.

Свойствата за независима трансформация са на път (и translaye, scale и rotate ще бъдат първите), засега те работят само с флаг в Chrome. В персонализирани свойства тази функционалност вече е налична с повече поддръжка (можете също да зададете реда на функциите. Например rotate(90deg) translateX(10vmin) е различно от translateX(10vmin) rotate(90deg)).

Ако не ви притеснява, че всички функции споделят една и съща опция за време, тогава те могат да бъдат плавно анимирани с помощта на свойството за преход при промяна на променливи. Почти магия.

Преминаване от стойности без единици към стойности с всякакви единици

Концепциите могат да бъдат разширени чрез свързването им с calc(). Можете да зададете променливи без единици ( --card-width: 10vmin или --rotation-amount: 1turn ) и да ги използвате на повече места. Това ще направи стойностите в персонализираните свойства още по-динамични.

Функциите calc() съществуват от няколко години и са може би най-полезният инструмент при добавяне на стойности с различни единици. Например, ако имате флуидна процентна ширина, която трябва да бъде намалена с 50px (width: calc(100% - 50px)). Но calc()може би много повече.

В calc можете да използвате умножение, за да образувате стойност. Кодът по-долу е напълно валиден и ни уведомява, че transform и filter са свързани, защото използват числото 10.

Това не е най-добрият случай на използване, обикновено такива изчисления не се изпращат до браузъра. 10*1vw винаги ще бъде 10vw, функцията calc е безполезна тук. Може да се използва в препроцесор с цикли, но тук можете да правите без calc ().

Ами ако заменим повтарящите се 10 с променлива? Ще можете да зададете множество стойности от една точка, дори ако стойностите са в различни единици. Можете да промените стойностите по всяко време. Благодарение на необединените променливи и calc, кодът по-долу е напълно валиден:

Можете да вземете една стойност (първоначално 10 и по-късно промяна на 80... или каквото и да е друго) и да я приложите отделно към vw или vh в трансформациите. Може да се преобразува в deg за ротация или филтър: hue-rotate().

свойства

Практически курс за оформление на адаптивен уебсайт от нулата!

Вземете курса и научете как да създавате модерни уебсайтове в HTML5 и CSS3

Не е необходимо да изхвърляте мерните единици, но стига да са в calc, имате такава възможност. Това отваря допълнителни възможности. Чрез промяна на базовата стойност в различни правила можете да реализирате анимация с промени в продължителността и забавянето. В примера по-долу ms винаги ще бъдат нашите крайни единици, но резултатът за нашето забавяне винаги трябва да бъде половината от продължителността на анимацията. За да направим това, ще трябва само да променим --duration-base.

Можете дори да използвате кубични безиерови функции в потребителски свойства. В примера по-долу са създадени няколко вертикално подредени блока. Всеки е малко по-малък от предишния и на всеки е даден множителкубична функция на Безие. Този множител ще бъде приложен отделно към 4-те части на основната функция Безие. Така че всеки блок ще има своя собствена индивидуална функция, но функциите ще бъдат взаимосвързани. Добавете или премахнете блок, за да видите как си взаимодействат. Щракнете където и да е на екрана, за да промените посоката на анимацията.

За рандомизиране на базовата функция с всеки клик се използва JS, чрез който се задава и множителят за блоковете. Основен CSS:

Ако разглеждате този пример в определен браузър (или се чудите защо класът .advanced-calc е в примера), тогава трябва да сте подозирали, че има проблеми с подхода. Има една много важна уловка... calc не винаги работи еднакво във всички браузъри. Ана Тюдор е провела много дълга дискусия относно разликите в поддръжката на браузъра за calc и е написала няколко допълнителни теста за други опростени случаи на calc.

Добрата новина е, че всички браузъри, които поддържат персонализирани свойства, също работят с calc, когато конвертират единици като px, vmin, rem и други линейни единици в свойства като width и transform: translate().

Не е най-добрата новина: Firefox и Edge често имат проблеми с други типове единици като deg, ms и дори % в някои случаи. Тоест предишният филтър: hue-rotate() и --rotation ще бъдат игнорирани. В някои случаи тези браузъри дори не разбират calc(1 * 1), т.е. дори стойност без единици (както в rgb()) може да бъде проблем.

Всички браузъри с поддръжка на персонализирани свойства позволяват променливи в cubic-bezier, но не всички позволяват calc на всяко ниво. Това са основните ограничения с calc в момента, според мен... и те дори не включват персонализирани свойства.

За тези проблеми браузърите иматгрешки, те могат да бъдат заобиколени с помощта на прогресивно подобрение. Ранните демонстрации правят cubic-bezier само ако знаят, че могат да се справят с тях. В противен случай ще получите основната функция. Те ще преминат погрешно @supports CSS, така че е необходима проверка на типа JS Modernizr:

Персонализираните свойства са прекрасен инструмент в CSS, но тяхната сила се отприщва, когато се комбинират с JS. В демонстрацията на cubic-bezier показахме, че нова стойност на свойството може да бъде написана в JS:

Кодът по-горе ще зададе новата стойност за глобалното свойство (зададено в правилото :root в CSS). Или можете да продължите направо и да зададете нова стойност за даден елемент (по този начин давайки на елемента максимална специфичност и оставяйки променливата непроменена за други елементи, които го използват). Това е удобно да направите, когато трябва да управлявате състоянието и да променяте стилове според зададените стойности.

Дейвид Khourshid обсъди мощни начини за взаимодействие с персонализирани свойства чрез JS в контекста на Observables и те вървят заедно наистина добре. Отворена е широка гама от начини за взаимодействие на персонализирани свойства с JS, независимо дали става дума за Observables, промени в състоянието в React или манипулатори на събития.

Взаимодействието е особено важно за свойства, които приемат множество стойности. JS използва стиловия обект от много дълго време за промяна на стилове, но е доста трудно да се промени която и да е отделна част от дълга стойност. Ако трябва да променим едно фоново изображение от 10, тогава трябва да знаем кое ще променим и да оставим останалите недокоснати. С transform е още по-трудно, когато трябва само да промените rotate() и да оставите scale() непроменен. Използвайки JS в персонализирани свойства, можете да промените всяка част от стойността поотделно, което улеснява работата със стойността за цялото свойствотрансформирам.

Методът без мерни единици също ще работи добре тук. Функцията setProperty() може да предава само числа на CSS, което ще опрости JS кода в някои случаи.

Време за използване?

Персонализираните свойства са налични в най-новите версии на браузърите Mozilla, Google, Opera, Apple и Microsoft. Сега е моментът да експериментирате. Повечето от описаното в тази статия вече може да се използва с добри резервни варианти. Актуализациите на браузъра за calc идват скоро, но персонализирани свойства вече могат да се използват в някои ситуации. Например, ако работите върху хибридно мобилно приложение за най-новите версии на iOS, Android или Windows, ще имате много повече опции.

Персонализираните свойства са голямо допълнение към CSS и ще ви отнеме известно време, за да разберете как работят. Първо намокрете краката си и ако ви харесва, гмурнете се с главата.

Автор: Дан Уилсън

Издание: Командата webformyself.

персонализирани

Практически курс за оформление на адаптивен уебсайт от нулата!

Вземете курса и научете как да създавате модерни уебсайтове в HTML5 и CSS3