- Описание
- Отправленные решения
496. Свой собственный Autoprefixer
Вова работает в крупной сети магазинов по продаже двухколёсного транспорта «МыЛюбимВелосипеды.ру», в которой очень серьёзная служба информационной безопасности. Её сотрудники составили список разрешённых библиотек, в котором есть PostCSS, но, на удивление, отсутствует Autoprefixer.
Вове очень нужен в работе этот плагин, потому что у него есть пользователи, которые сидят на браузерах десятилетней давности.
К сожалению, с СИБом договориться не получилось, нет возможности расширить набор доступного ПО. Но наш герой не сдаётся, по жизни идёт и смеётся. Он решил, что можно написать Autoprefixer самостоятельно.
Помогите ему это сделать.
Autoprefixer — это плагин для PostCSS, который добавляет вендорные префиксы к CSS-свойствам.
Инструкция по написанию плагинов для PostCSS.
Плагин должен принимать объект vendorPrefixes
, который содержит возможные префиксы для CSS-свойств и псевдоэлементов.
Ключ объекта — это имя свойства или псевдоэлемента, а значение — массив с набором префиксов.
Если ключ начинается с ::
— значит, он содержит псевдоэлемент, иначе — свойство.
Для свойств необходимо добавить строчки с префиксами перед оригинальной строчкой, а для псевдоэлементов — скопировать полностью блок со всем содержимым и дописать к селектору префикс.
Все добавленные свойства и селекторы должны идти согласно порядку в массиве из vendorPrefixes
.
Примечания
В рамках этой задачи мы будем считать, что псевдоэлементы могут начинаться только с ::
.
Во время тестирования будет использован PostCSS версии 8.4.35.
Чтобы было легче разрабатывать плагин, мы сделали песочницу. Вы можете записать код вашего решения в файл plugin.js
и запустить index.js
, чтобы проверить работу.
Примеры
Пример объекта с вендорными префиксами:
const vendorPrefixes = {
'display': ['webkit', 'moz'],
'border-radius': ['webkit', 'moz', 'ms', 'o'],
'::placeholder': ['ms-input', 'moz']
};
Пример исходного CSS:
.card {
display: flex;
align-items: center;
padding: 16px;
border-radius: 10px;
}
.secondary,
input::placeholder {
color: #888;
}
Пример результата после обработки плагином:
.card {
-webkit-display: flex;
-moz-display: flex;
display: flex;
align-items: center;
padding: 16px;
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
-ms-border-radius: 10px;
-o-border-radius: 10px;
border-radius: 10px;
}
input::-ms-input-placeholder {
color: #888;
}
input::-moz-placeholder {
color: #888;
}
.secondary,
input::placeholder {
color: #888;
}
Шаблон решения
module.exports = (opts = {vendorPrefixes: {}}) => {
// Ваш плагин
};
module.exports.postcss = true;
Ограничения
Ограничение времени
1 с
Ограничение памяти
64 МБ
Пример 1
// Vendor Prefixes
{
"display": ["webkit", "moz"],
"border-radius": ["webkit", "moz", "ms", "o"],
"::placeholder": ["ms-input", "moz"]
}
// styles.css
.card {
display: flex;
align-items: center;
padding: 16px;
border-radius: 10px;
}
.secondary,
input::placeholder {
color: #888;
}
.card {
-webkit-display: flex;
-moz-display: flex;
display: flex;
align-items: center;
padding: 16px;
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
-ms-border-radius: 10px;
-o-border-radius: 10px;
border-radius: 10px;
}
input::-ms-input-placeholder {
color: #888;
}
input::-moz-placeholder {
color: #888;
}
.secondary,
input::placeholder {
color: #888;
}
Пример 2
// Vendor Prefixes
{
"transform": ["webkit", "moz", "ms", "o"],
"box-shadow": ["webkit", "moz"],
"border-radius": ["webkit", "moz"],
"margin": []
}
// styles.css
.center {
position: relative;
top: 50%;
margin: 0 auto;
transform: translateY(-50%);
}
.card {
width: 300px;
height: 300px;
border-radius: 10px;
background-color: crimson;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
.center {
position: relative;
top: 50%;
margin: 0 auto;
-webkit-transform: translateY(-50%);
-moz-transform: translateY(-50%);
-ms-transform: translateY(-50%);
-o-transform: translateY(-50%);
transform: translateY(-50%);
}
.card {
width: 300px;
height: 300px;
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
background-color: crimson;
-webkit-box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
-moz-box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
Пример 3
// Vendor Prefixes
{
"transform": ["webkit", "moz", "ms", "o"],
"box-shadow": ["webkit", "moz"],
"box-sizing": ["webkit", "moz"],
"border-radius": ["webkit", "moz"],
"justify-content": ["webkit"],
"transition": ["webkit", "moz", "o"],
"::placeholder": ["moz"],
"margin": []
}
// styles.css
* {
margin: 0;
padding: 0;
font-family: sans-serif;
box-sizing: border-box;
}
.header {
--header-height: 48px;
display: flex;
width: 100%;
height: var(--header-height, 32px);
padding: 0 16px;
justify-content: space-between;
background: crimson;
}
.menu__itemsList,
.menu__item{
display: flex;
}
.menu__itemLink,
.header__signin {
display: block;
height: var(--header-height, 32px);
padding: 0 16px;
line-height: var(--header-height, 32px);
text-decoration: none;
color: #fff;
transition: all 0.3 ease;
}
.menu__itemLink:hover {
background: #810000;
}
.menu__itemLink:focus {
outline: 2px dashed #fff;
outline-offset: -2px;
}
@media (max-width: 720px) {
.header {
justify-content: center;
background: darkgreen;
}
}
* {
margin: 0;
padding: 0;
font-family: sans-serif;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.header {
--header-height: 48px;
display: flex;
width: 100%;
height: var(--header-height, 32px);
padding: 0 16px;
-webkit-justify-content: space-between;
justify-content: space-between;
background: crimson;
}
.menu__itemsList,
.menu__item{
display: flex;
}
.menu__itemLink,
.header__signin {
display: block;
height: var(--header-height, 32px);
padding: 0 16px;
line-height: var(--header-height, 32px);
text-decoration: none;
color: #fff;
-webkit-transition: all 0.3 ease;
-moz-transition: all 0.3 ease;
-o-transition: all 0.3 ease;
transition: all 0.3 ease;
}
.menu__itemLink:hover {
background: #810000;
}
.menu__itemLink:focus {
outline: 2px dashed #fff;
outline-offset: -2px;
}
@media (max-width: 720px) {
.header {
-webkit-justify-content: center;
justify-content: center;
background: darkgreen;
}
}