Задачки с собеседований и не только


Сегодня будет один из ответов на задачку с собеседования. Вопрос обычно звучит так: назовите все способы передать данные на сервер из браузера. Мы не рассматриваем тут очевидные ответы, а рассмотрим интересные техники связанные только с CSS. Кстати, эти же техники могут использоваться в системах мониторинга и трекинга. И так, поехали.

Передача данных на сервер используя только CSS

Вся идея передачи данных на сервер через CSS базируетcя на одной простой идее — это загрузка URL через свойство url(), которое используется для разных целей. Все. А вот дальше уже можно фантазировать и фантазия может привести к тому, что зная эту технику можно сделать целую систему мониторинга сайта на одном лишь чистом CSS.

Детектим клик по ссылке

#somelink1:active::after {
content: url("/tracker/?action=somelink1");
}

Детектим браузер

В CSS пишем:

@supports (-webkit-appearance:none) and (not (-ms-ime-align:auto)){
#chrome_detect::after {
content: url("/tracker/?browser=chrome");
}
}

@supports (-moz-appearance:meterbar) {
#firefox_detect::after {
content: url("/tracker/?browser=firefox");
}
}

@supports (-ms-ime-align:auto) {
#edge_detect::after {
content: url("/tracker/?browser=edge")
}
}

В страницу встраиваем следующие теги:

<div id="chrome_detect"></div><div id="firefox_detect"></div>
<div id="edge_detect"></div>

Если нужные старые IE, то подключаем условные комментарии.

Определяем ориентацию

CSS:
@media (orientation: portrait) {
#orientation::after {
content: url(“/tracker/?orientation=portrait”);
}
}
@media (orientation: landscape) {
#orientation::after {
content: url(“/tracker/?orientation=landscape”);
}
}
HTML:
<div id="orientation"></div>

Определяем размер экрана

CSS:
@media (min-device-width: 360px) {
#width::after {
content: url("/tracker/?width=360");
}
}
/*
...360px, 640px, 720px, 1024px, 1280px, 1366px, 1920px, 3840px...
*/
@media (min-device-width: 4096px) {
#width::after {
content: url("/tracker/?width=4096");
}
}
HTML:
<div id="width"></div><div id="height"></div>

То же самое проделываем для heights и прописываем стандартные размеры: 2160px, 1366px, 1080px, 1024px, 768px, 720px, 690px, 667px, 640px, 600px, 576px, 568px, 540px, 504px, 480px, 360px, 320px, 240px.

Input detection

Можно получить данные из input’ов

#checkbox:checked {
content: url("/tracker/?action=checkbox");
}

Данные, которые вводятся в input:

CSS:
#mail:valid {
background-image: url("/tracker/?action=input-email-valid");
}
#mail:invalid {
background-image: url("/tracker/?action=input-email-error");
}
HTML:
<input type="mail" id="mail" required>

и так далее. Все ограничивается вашей фантазией.

Измерить длительность

Можно узнать как долго было какое-то действие. Например можно понять как долго курсор был над объектом:

@keyframes duraloop {
0% {background-image: url("/tracker/?duration=0")}
10% {background-image: url("/tracker/?duration=10")}
20% {background-image: url("/tracker/?duration=20")}
...
100% {background-image: url("/tracker/?duration=100")}
}

#duration:hover::after {
animation: duraloop 5s infinite;
animation-name: duraloop;
animation-duration: 10s;
animation-iteration-count: infinite;
content: url("/tracker/?duration=-1");
}

Таким образом можно считывать длительность фокуса и прочие вещи.

Прочее

Еще осталось правило font-face, которое так же можно использовать для отправки данных на сервер.

Github с готовым proof of concept и демо можно найти по ссылке:

https://github.com/jbtronics/CrookedStyleSheets

Если есть идеи — делайте пулреквесты.