Перейти к содержимому

Блог

0 дней без ошибок с SVG background

У нас SVG в качестве фона сверху нашего сайта, основной фон — просто серый. Для картинки у нас такой css:

.container {
background-image: url(path/to/our.svg);
background-repeat: no-repeat;
background-size: 100% 144px;
}

Всех всё устраивает, однако подкрались праздники и дизайнерка предложила обновить картинку на более праздничную (и, конечно, добавить снег, но с ним как раз проблем не было). Дизайнерка попросила не растягивать новую картинку (как мы делаем обычно, просто растягивая её до 100%), так что обновила css:

.container {
background-image: url(path/to/holiday.svg);
background: no-repeat;
background-size: auto 144px;
background-position: left top;
}

Тестировщики протестировали, и всё улетело в предпраздничный релиз.

Пару дней спустя мне написал коллега: можем ли мы что-то сделать с нашим праздничным фоном на широких экранах? Я проверила, и это была катастрофа: на широких экранах (более чем 2500px) наш фон заканчивался на 2000px, и дальше справа было просто серое пятно.

Фикс был быстрый и простой:

.container {
background-image: url(path/to/holiday.svg);
background: repeat-x;
background-size: auto 144px;
background-position: left top;
}

Просто не забывайте: либо 100%, либо repeat.

HOC или не HOC?

В наборе кат для изучения паттернов попалась одна про Higher-Order Component(HOC) в React — truncate paragraph with HOC in React. Плюс недавно разбиралась с паттерном Декоратор, и примером применения для React как раз считается HOC.

И вот я задумалась: а действительно ли хоки актуальны?

Чаще всего я вижу хоки, когда работаю с кодом, написанным 3-4 года назад, но в новом коде я практически их не вижу. Опять же, в старой документации React есть целая страница, посвященная HOC и примерам использования, а вот в новой классной документации ничего нет.

Кажется, что кастомные хуки вытеснили хоки. Что такого особенного ты можешь сделать с HOC, что не можешь, просто написав кастомный хук?

Лично я предпочитаю кастомные хуки или даже классы с вынесенной в них бизнес-логикой. Для меня это более очевидный и поддерживаемый подход.

Boxes in boxes, Или что застряло у меня в голове

Я периодически решаю задачи на leetcode или codewars, и недавно наткнулась на кату “Boxes in boxes”.

Это вроде бы не то чтобы сложная задача, но я застряла. Для начала, у меня есть проблемы с пространственным мышлением, так что я не сразу поняла сам паттерн с рисованием этих ящиков.

И даже когда я поняла паттерн, я… не смогла написать решение. Понимала, что нужно рисовать ящики от первого и затем с повторением уже существующих нарисованных, но как? Это просто не укладывалось в моей голове.

После двух вечеров размышлений, я была вынуждена посмотреть чужие решения (эта задача просто сводила меня с ума). И знаете что? Даже после того, как я увидела код и поняла, что он должен делать, я так и не могла осознать, а каким же образом это приводит нас к нужному результату.

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

Оставлю мой код с комментами здесь, чтобы если можно было вспомнить ход мысли:

function draw(n) {
// all for one box, our start
let res = [" _ ", "|_|"];
for (let i = 1; i < n; i++) {
res = [
// top line - just add tops of boxes
' _' + res[0],
// draw existing boxes without left border (top 1/2 part is repeat existing but partially)
...res.slice(1).map(str => '| ' + str.slice(1)),
// draw existing with left border and without bottom
...res.slice(1, -1).map(str => '| ' + str),
// draw bottom
'|_' + res[res.length-1],
]
}
return res.join('\n');
}

Остаётся только надеяться, что на интервью мне эта задача не попадётся 🤪

Сегодня узнала, что можно в ref передавать callback

От моего внимания как-то ускользнуло, что в React можно передавать функцию-callback как ref для элемента, а не только объект, созданный с помощью useRef.

const scroller = (node: HTMLDivElement) => {
if (!node) return;
node.scrollIntoView({ behavior: "smooth" });
};
// somewhere in component
<div ref={scroller} />

Как это работает:

  • Когда элемент добавляется в DOM, React вызывает функцию-callback и передает в неё DOM-узел как аргумент.
  • Когда элемент удаляется из DOM, React вызывает эту функцию с аргументом null.
  • Callback также вызывается каждый раз, когда передается новая функция (например, при каждом рендере, если она определена как обычная функция).

No more absolute for overlapping

Спасибо Wes Bos за примеры, как можно обойтись без position: absolute для накладывающихся друг на друга элементов: tweet 1 и tweet 2. Я применила этот вариант уже раза 3 в текущем проекте, переверстывая старые элементы, и насколько же лучше это выглядит 😊

За подробностями — в твиттер Wes Bos, у него там видео с примерами, или на css-trics.

Я фанат именованных grid-area, поэтому мой любимый подход: родительский компонент превращаем в grid и задаем grid-template-areas: 'stack'. Компонентам-детям, которые должны накладываться, задаём grid-area: stack. (имя grid-area может быть любым, главное, чтобы было одинаковым у тех элементов, над которыми колдуем)

Либо можно не задавать именованную grid-area, а просто указать для нужных элементов одинаковые grid-row-start и grid-column-start. Вот так:

.container > * {
grid-area: 1 / 1;
}