

Покроковий гайд зі створення гри «З'єднайте точки» для листів (з прикладами коду)
Створити ексклюзивні листиПам'ятаєте гру з дитячих журналів або зі зворотного боку коробок із пластівцями, де потрібно з'єднати всі точки, щоб вийшла картинка? Напевно, кожному знайома ця інтрига, коли ви проводите лінію від однієї точки до іншої і не знаєте, яку картинку отримаєте.
Ми повертаємо ці приємні спогади в нашій новій інтерактивній механіці для листів під назвою «З'єднайте точки». Цей інтерактивний елемент може знайти чимало застосувань в email-маркетингу:
- сезонні кампанії можна доповнити тематичними малюнками, які одержувачі мають намалювати крапками, що підвищує загальну залученість у кампанію;
- спеціальні пропозиції можуть бути надані під час змагання з цієї гри, що робить її одночасно спортивною та веселою;
- презентація або анонсування нових продуктів за допомогою такої захопливої гри може викликати ще більший ажіотаж навколо вашого бренду та майбутніх маркетингових заходів.
У цій статті ми детально розповімо, як створити повноцінну гру, яка міститиме в собі:
- AMP-версію гри з п'ятьма зображеннями;
- інтерактивну HTML-версію з тими ж п'ятьма зображеннями;
- фолбек-версію для поштових клієнтів, які не підтримують інтерактивність.
Давайте перейдемо до гайду.
Як влаштовано гру
Для початку варто обговорити принцип функціонування гри загалом. У нашому прикладі одержувачу потрібно намалювати ракету. Сам малюнок розділений на кілька сегментів, між якими знаходяться точки. Далі нам потрібен кожен сегмент, а точки прокладаються окремо (а саме, для кожного сегмента 1-2, 2-3, 3-4 тощо створюється окремий блок, який рухається та повертається під потрібним кутом). Поєднавши все це, одержувачі можуть завершити зображення лініями, наче вони були намальовані від руки.
AMP-версія
Почнемо з додавання порожньої структури і вибору «Показувати в AMPHTML».
Після цього додайте в неї блок «HTML» і введіть такий код:
<style amp-custom>
.dot-amp .dot-container {
background: url(https://zlnfb.stripocdn.email/content/guids/CABINET_c102d17d796d323a0ee84181252016915f4177c79c86a55019b0dccf636e6f33/images/bg.png) no-repeat top center;
background-size: contain;
width: 300px;
height: 450px;
margin: 0 auto;
position: relative;
}
.dot-amp .circle {
display: inline-block;
width: 10px;
height: 10px;
background: #000;
border-radius: 50%;
}
.dot-amp .active .circle,
.dot-amp .dot:hover .circle {
background: blue;
}
.dot-amp .number {
display: block;
position: absolute;
right: -10px;
line-height: 10px;
}
.dot-amp .line {
background: #000;
width: 3px;
height: 100%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.dot-amp .dot {
display: block;
cursor: pointer;
padding: 10px;
position: absolute;
bottom: -18px;
left: 50%;
transform: translate(-50%, 0);
line-height: 10px;
}
.dot-amp .block-1-2 {
width: 7.50%;
height: 20.17%;
position: absolute;
top: 1.67%;
right: 17.75%;
transform: rotate(-23deg);
}
.dot-amp .dot-1 {
top: -14px;
bottom: auto;
}
.dot-amp .dot-1 .number {
transform: rotate(23deg);
}
.dot-amp .dot-2 .number {
transform: rotate(23deg);
}
.dot-amp .block-2-3 {
width: 7.50%;
height: 16.83%;
position: absolute;
transform: rotate(-5deg);
top: 21.83%;
right: 10.50%;
}
.dot-amp .dot-3 .number {
transform: rotate(5deg);
}
.dot-amp .result {
padding: 20px 0;
text-align: center;
}
@media only screen and (max-width: 600px) {
.dot-amp .dot-container {
width: 250px;
height: 375px;
}
}
</style>
<div class="dot-amp">
<div class="dot-container">
<div class="block-2-3">
<div class="line line-2-3" hidden [hidden]="dot2!=1 || dot3!=1"></div>
<label role="button" tabindex="3" on="tap:AMP.setState({dot3:1, active:3})" class="dot dot-3" [class]="active == 3 ? 'dot dot-3 active' : 'dot dot-3'">
<span class="number">3</span>
<span class="circle"></span>
</label>
</div>
<div class="block-1-2">
<div class="line line-1-2" hidden [hidden]="dot1!=1 || dot2!=1"></div>
<label role="button" tabindex="1" on="tap:AMP.setState({dot1:1, active:1})" class="dot dot-1" [class]="active == 1 ? 'dot dot-1 active' : 'dot dot-1'">
<span class="number">1</span>
<span class="circle"></span>
</label>
<label role="button" tabindex="2" on="tap:AMP.setState({dot2:1, active:2})" class="dot dot-2" [class]="active == 2 ? 'dot dot-2 active' : 'dot dot-2'">
<span class="number">2</span>
<span class="circle"></span>
</label>
</div>
</div>
<div class="result" hidden [hidden]="[dot1,dot2,dot3].indexOf(null) != -1">
<h2 style="padding-bottom:15px">Congratulations!</h2>
<p>Here's your personal promo code GAMIFICATION for 15% OFF sitewide.</p>
</div>
</div>
Наразі в коді 3 точки і 2 сегменти (пізніше їх буде додано більше для надання грі закінченого вигляду, як це було показано в демонстраційній GIF-ці). У макеті блоки названі сегментами block-1-2, block-2-3 тощо. Перший блок 1-2 складається з лінії та двох точок №1 і №2. У всіх інших блоках буде лінія й одна точка (у блоці 2-3 точка №3, у блоці 3-4 точка №4 тощо).
Давайте розглянемо один з блоків ближче.
Перший елемент — div; це наша лінія. Вона має атрибути hidden [hidden]="dot2!=1 || dot3!=1", де:
- hidden — приховує елемент;
- [hidden] — задає умову, коли приховувати елемент (у нашому прикладі: приховувати, поки dot2 і dot3 не стануть рівними 1).
Далі йде тег label, який є точкою 3. Він має такі атрибути: role="button" tabindex="3" on="tap:AMP.setState({dot3:1, active:3})" [class]="active == 3 ? 'dot dot-3 active' : 'dot dot-3'", де:
- role="button" — атрибут, який додається до елемента і працює як кнопка;
- tabindex="3" — обов'язковий атрибут за наявності role=«button», оскільки він задає послідовність отримання фокусу при перемиканні між елементами за допомогою клавіші табуляції;
- on="tap:AMP.setState({dot3:1, active:3})" — опрацьовувач події «клік» (on="tap:”);
- dot3 — змінна, яка спочатку має нульове значення, але коли одержувач клікає на цю точку, у змінну записується значення 1, що допомагає зрозуміти, на яку точку клікнув користувач;
- active — змінна, яка потрібна для виділення точки, коли вона активна; ми записуємо в неї номер точки, на яку клікнув користувач;
- [class]="active == 3 ? 'dot dot-3 active' : 'dot dot-3'" — атрибут, у якому записується умова відображення класів: якщо значення змінної active дорівнює 3, то додається точка активного класу dot-3, інакше залишається лише точка класу dot-3.
Решта сегментів (крім 1-2) повинні мати ту саму схему, тільки номери змінюються відповідно до номерів точок. Найперший сегмент 1-2 відрізняється тим, що в ньому є одразу 2 точки (№1 і №2).
Повідомлення про завершення гри
Наступне, про що варто розповісти, — це повідомлення, яке з'являється після завершення гри. Щоб додати своє повідомлення, замініть наш текст у зазначеній області на свій.
Він має атрибут [hidden]="[dot1,dot2,dot3].indexOf(null) != -1", який приховує елемент у разі виконання умови. У нашому прикладі блок буде прихований, якщо хоча б одна зі змінних, dot1, dot2 і dot3, має нульове значення (так буде, якщо крапку не було клікнуто). Щоб блок відображався в кастомізованій грі з заданою кількістю точок, усі вони мають бути перераховані тут.
Розбираємося зі стилями
Тепер поговоримо про те, як виглядає гра, тобто про її код стилів. Нижче ви бачите код, який задає фонове зображення ракети та розмір блоку для десктопної версії. Отже, щоб встановити своє власне фонове зображення для гри, ви маєте змінити посилання у виділеній області на посилання вашого зображення.
Важлива примітка: щоб замінити наше зображення своїм, його потрібно підготувати, як у нашому прикладі. Також необхідно змінити розмір блоку, якщо ваше зображення має інші пропорції.
Десктопна версія гри в нашому прикладі має такі розміри:
Мобільний розмір нашої гри позначений цією частиною коду:
Тим часом кольори для точок за замовчуванням і для точок під час наведення задаються в цій частині коду:
Колір ліній між точками задається в цьому фрагменті коду:
Розташування ліній за допомогою стилів та їх кастомізація
Тепер найскладніша частина стилів — та, що відповідає за кут, під яким йдуть лінії і, власне, допомагає створити малюнок:
Цей фрагмент коду задає розміри, координати та нахили кожного сегмента. Оскільки ми повертаємо весь блок за допомогою (transform: rotate(-23deg)), числа в ньому також повертаються. Щоб вони виглядали рівно, ми вирівнюємо кожне число назад за допомогою стилю трансформації, а саме rotate(23deg).
Усі значення задаються у відсотках, щоб їх не потрібно було змінювати на мобільних пристроях.
Як обчислити значення у відсотках
Ви можете одразу вказати розміри у відсотках або вибрати розміри в пікселях, а потім перетворити їх у відсотки. Відсотки обчислюються відносно контейнера з грою (dot-container). У нашому прикладі його розміри становлять 300 px за шириною і 450 px за висотою.
Візьмемо, наприклад, розміри блоку 1-2: ширина 23 px, висота 90 px.
Ми розраховуємо ширину блоку відносно ширини контейнера з грою і висоту відносно висоти.
Для ширини існує формула розрахунку:
- 23*100/300 = 7,67% — це значення записується в ширину блоку 1-2.
Для визначення висоти використовується така формула:
- 90*100/450 = 20% — це значення записується у висоту блоку 1-2.
Значення «left» і «top» можна одразу задати у відсотках або перетворити з пікселів за тією ж формулою: для left або right — відносно ширини контейнера, а для top або bottom — відносно висоти контейнера.
Таким чином, вам необхідно додати всі потрібні блоки з крапками.
Інтерактивна HTML-версія
Наступний крок нашого гайда — інтерактивна HTML-версія, створена за допомогою HTML5 і CSS3. Продовжуйте працювати з тим самим шаблоном, де ми створювали AMP-версію. Додайте ще одну порожню структуру. Виділіть її та виберіть опцію «Показувати лише в HTML».
Коли все буде готово, додайте в неї блок «HTML» і вставте такий код:
<style>
.dot-html .dot-container {
background: url(https://zlnfb.stripocdn.email/content/guids/CABINET_c102d17d796d323a0ee84181252016915f4177c79c86a55019b0dccf636e6f33/images/bg.png) no-repeat top center;
background-size: contain;
width: 300px;
height: 450px;
margin: 0 auto;
position: relative;
}
.dot-html .circle {
display: inline-block;
width: 10px;
height: 10px;
background: #000;
border-radius: 50%;
}
.dot-html .active .circle {
background: blue;
}
.dot-html .number {
display: block;
position: absolute;
right: -10px;
}
.dot-html .line {
background: #000;
width: 3px;
height: 100%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: none;
}
.dot-html .dot {
display: block;
cursor: pointer;
padding: 10px;
position: absolute;
bottom: -18px;
left: 50%;
transform: translate(-50%, 0);
}
.dot-html .block-1-2 {
width: 7.50%;
height: 20.17%;
position: absolute;
top: 1.67%;
right: 17.75%;
transform: rotate(-23deg);
}
.dot-html .dot-1 {
top: -14px;
bottom: auto;
}
.dot-html .dot-1 .number {
transform: rotate(23deg);
}
.dot-html .dot-2 .number {
transform: rotate(23deg);
}
.dot-html .block-2-3 {
width: 7.50%;
height: 16.83%;
position: absolute;
transform: rotate(-5deg);
top: 21.83%;
right: 10.50%;
}
.dot-html .dot-3 .number {
transform: rotate(5deg);
}
.dot-html .block-3-4 {
width: 7.50%;
height: 26.00%;
position: absolute;
transform: rotate(16deg);
top: 39.00%;
right: 14.50%;
}
.dot-html .dot-4 .number {
transform: rotate(-16deg);
}
.dot-html .block-4-5 {
width: 7.50%;
height: 17.50%;
position: absolute;
transform: rotate(91deg);
top: 56.83%;
right: 33.75%;
}
.dot-html .dot-5 .number {
transform: rotate(-91deg);
}
.dot-html .block-5-6 {
width: 7.50%;
height: 16.50%;
position: absolute;
transform: rotate(113deg);
top: 53.67%;
right: auto;
left: 32.00%;
}
.dot-html .dot-6 .number {
transform: rotate(-113deg);
}
.dot-html .block-6-7 {
width: 7.50%;
height: 20.00%;
position: absolute;
top: 38.17%;
right: auto;
left: 20.80%;
transform: rotate(4deg);
}
.dot-html .dot-7 {
top: -16px;
bottom: auto;
}
.dot-html .dot-7 .number {
transform: rotate(-2deg);
}
.dot-html .block-7-8 {
width: 7.50%;
height: 23.33%;
position: absolute;
transform: rotate(25deg);
top: 16.33%;
right: auto;
left: 29.00%;
}
.dot-html .dot-8 {
top: -16px;
bottom: auto;
}
.dot-html .dot-8 .number {
transform: rotate(-27deg);
}
.dot-html .block-8-9 {
width: 7.50%;
height: 20.83%;
position: absolute;
transform: rotate(54deg);
top: 0.5%;
right: auto;
left: 49.75%;
}
.dot-html .dot-9 {
top: -16px;
bottom: auto;
}
.dot-html .dot-9 .number {
transform: rotate(-54deg);
}
.dot-html .result {
padding: 20px 0;
text-align: center;
display: none;
}
@media only screen and (max-width: 600px) {
.dot-html .dot-container {
width: 250px;
height: 375px;
}
}
#input-dot-8:checked~#input-dot-9:checked~div .line-8-9,
#input-dot-7:checked~#input-dot-8:checked~div .line-7-8,
#input-dot-6:checked~#input-dot-7:checked~div .line-6-7,
#input-dot-5:checked~#input-dot-6:checked~div .line-5-6,
#input-dot-4:checked~#input-dot-5:checked~div .line-4-5,
#input-dot-3:checked~#input-dot-4:checked~div .line-3-4,
#input-dot-2:checked~#input-dot-3:checked~div .line-2-3,
#input-dot-1:checked~#input-dot-2:checked~div .line-1-2 {
display: block;
}
#input-dot-9:checked~div .dot-9 .circle,
#input-dot-8:checked~div .dot-8 .circle,
#input-dot-7:checked~div .dot-7 .circle,
#input-dot-6:checked~div .dot-6 .circle,
#input-dot-5:checked~div .dot-5 .circle,
#input-dot-4:checked~div .dot-4 .circle,
#input-dot-3:checked~div .dot-3 .circle,
#input-dot-2:checked~div .dot-2 .circle,
#input-dot-1:checked~div .dot-1 .circle,
.dot-html .dot:hover .circle {
background: blue;
}
#input-dot-1:checked~#input-dot-2:checked~div .dot-1 .circle,
#input-dot-2:checked~#input-dot-3:checked~div .dot-2 .circle,
#input-dot-3:checked~#input-dot-4:checked~div .dot-3 .circle,
#input-dot-4:checked~#input-dot-5:checked~div .dot-4 .circle,
#input-dot-5:checked~#input-dot-6:checked~div .dot-5 .circle,
#input-dot-6:checked~#input-dot-7:checked~div .dot-6 .circle,
#input-dot-7:checked~#input-dot-8:checked~div .dot-7 .circle,
#input-dot-8:checked~#input-dot-9:checked~div .dot-8 .circle {
background: #000;
}
#input-dot-1:checked~#input-dot-2:checked~#input-dot-3:checked~#input-dot-4:checked~#input-dot-5:checked~#input-dot-6:checked~#input-dot-7:checked~#input-dot-8:checked~#input-dot-9:checked~.result {
display: block;
}
</style>
<div class="dot-html">
<input id="input-dot-1" name="input-dot-1" type="radio" style="display:none">
<input id="input-dot-2" name="input-dot-2" type="radio" style="display:none">
<input id="input-dot-3" name="input-dot-3" type="radio" style="display:none">
<input id="input-dot-4" name="input-dot-4" type="radio" style="display:none">
<input id="input-dot-5" name="input-dot-5" type="radio" style="display:none">
<input id="input-dot-6" name="input-dot-6" type="radio" style="display:none">
<input id="input-dot-7" name="input-dot-7" type="radio" style="display:none">
<input id="input-dot-8" name="input-dot-8" type="radio" style="display:none">
<input id="input-dot-9" name="input-dot-9" type="radio" style="display:none">
<div class="dot-container">
<div class="block-8-9">
<div class="line line-8-9"></div>
<label for="input-dot-9" class="dot dot-9"><span class="circle"></span><span class="number">9</span></label>
</div>
<div class="block-7-8">
<div class="line line-7-8"></div>
<label for="input-dot-8" class="dot dot-8"><span class="circle"></span><span class="number">8</span></label>
</div>
<div class="block-6-7">
<div class="line line-6-7"></div>
<label for="input-dot-7" class="dot dot-7"><span class="circle"></span><span class="number">7</span></label>
</div>
<div class="block-5-6">
<div class="line line-5-6"></div>
<label for="input-dot-6" class="dot dot-6"><span class="number">6</span><span class="circle"></span></label>
</div>
<div class="block-4-5">
<div class="line line-4-5"></div>
<label for="input-dot-5" class="dot dot-5"><span class="number">5</span><span class="circle"></span></label>
</div>
<div class="block-3-4">
<div class="line line-3-4"></div>
<label for="input-dot-4" class="dot dot-4"><span class="number">4</span><span class="circle"></span></label>
</div>
<div class="block-2-3">
<div class="line line-2-3"></div>
<label for="input-dot-3" class="dot dot-3"><span class="number">3</span><span class="circle"></span></label>
</div>
<div class="block-1-2">
<div class="line line-1-2"></div>
<label for="input-dot-1" class="dot dot-1"><span class="number">1</span><span class="circle"></span></label>
<label for="input-dot-2" class="dot dot-2"><span class="number">2</span><span class="circle"></span></label>
</div>
</div>
<div class="result">
<h2 style="padding-bottom:15px">Congratulations!</h2>
<p>Here's your personal promo code GAMIFICATION for 15% OFF sitewide.</p>
</div>
</div>
Тут загальна схема така сама, як і в AMP-версії, але замість атрибутів AMP ми використовуємо теги label з тегами input за допомогою атрибута «for». У цьому атрибуті ми вказуємо id відповідного input.
Важлива примітка: кількість інпутів відповідає кількості точок на зображенні.
Розбираємося зі стилями
Стилі допомагають нам регулювати відображення ігрових елементів. Ось як виглядають стилі для відображення ліній між точками:
Якщо одержувач клікає на точки 8 і 9, ми показуємо сегмент 8-9, якщо на точки 7 і 8, ми показуємо сегмент 7-8 тощо. Як приклад ми перерахуємо всі точки, які існують у нашій грі.
Наступні стилі фарбують точки в синій колір під час наведення на них курсору і в активному стані, а стилі нижче повертають точці її вихідний (чорний) колір, якщо сегмент, до якого вона належить, уже відображається.
І останнє, але не менш важливе: стилі, що відповідають за відображення блоку з повідомленням після того, як усі точки будуть зафарбовані:
Фолбек-версія
Для поштових клієнтів, які не підтримують HTML5 і CSS3, необхідно створити додатковий блок із кодом. Він матиме структуру, схожу на нашу механіку, але без інтерактивності. Клік по елементах призведе до переходу на веб-версію листа.
Продовжуємо працювати в блоці з інтерактивним HTML, який ми зробили вище. Вставте наступний код між тегами </style> і <div class="dot-html">:
<!--[if !mso]><!--><input type="checkbox" id="fallback_ctrl" class="fallback_ctrl" style="display:none !important;mso-hide:all;" checked>
<!--<![endif]-->
<!-- FALLBACK -->
<div id="fallback" class="fallback">
<table width="100%">
<tbody>
<tr align="center">
<td><a target="_blank" href="https://viewstripo.email/41a57244-a78a-40d8-88ee-f18848aba63b1711958538852?type=amphtml"><img src="https://zlnfb.stripocdn.email/content/guids/CABINET_c102d17d796d323a0ee84181252016915f4177c79c86a55019b0dccf636e6f33/images/bg.png" alt style="display: block;" width="258" height="450"></a></td>
</tr>
</tbody>
</table>
</div><!-- /FALLBACK -->
<!--[if !mso]><!-->
<!-- INTERACTIVE ELEMENT -->
<div class="container" style="mso-hide:all;display:none;">
Крім того, вставте цей код у кінець коду:
</div><!-- /INTERACTIVE ELEMENT -->
<!--<![endif]-->
У коді фолбека є спеціальна частина, що містить посилання на веб-версію листа. Просто вставте посилання на веб-версію, як показано нижче.
Важлива примітка: докладніше про веб-версії листів і про те, як їх отримати, читайте в нашій спеціальній статті.
Розбираємося зі стилями
Щоб задати зовнішній вигляд фолбека, нам також потрібно додати стилі. Додайте цей фрагмент коду всередину тега style (простіше вставити його перед тегом закривання </style>):
/* --- */
@media screen and (-webkit-min-device-pixel-ratio: 0) {
input.fallback_ctrl:checked~.container {
display: block !important;
}
input.fallback_ctrl:checked~#fallback {
display: none !important;
}
}
[owa] .container {
display: none !important;
}
[class~="x_container"] {
display: none !important;
}
[id~="x_fallback"] {
display: block !important;
}
@media screen and (max-width: 600px) {
body[data-outlook-cycle] #fallback {
display: block !important;
}
body[data-outlook-cycle] .container {
display: none !important;
}
}
Давайте розглянемо код детальніше.
<!--[if !mso]><!--><input type="checkbox" id="fallback_ctrl" class="fallback_ctrl" style="display:none !important;mso-hide:all;" checked>
<!--<![endif]-->
Цей інпут необхідний, щоб показати або приховати версію фолбека за допомогою стилів. Ми обернули його в коментарі <!--[if !mso]><!--> … <!--<![endif]-->, щоб переконатися, що він прихований у клієнті Outlook Desktop.
Тим часом <div id="fallback" class="fallback"></div> — це блок, що містить увесь макет нашого фолбека. Він повинен мати просту структуру таблиці, яка доцільна для Outlook. У нашому прикладі це таблиця у вигляді вкладок із посиланнями, що ведуть на веб-версію. Ви можете створити свою власну версію, наприклад, щоб вміст вкладок відображався один під іншим без переходу до веб-версії. Головне — використовувати розмітку, зрозумілу для Outlook.
Стилі нижче відповідають за приховування і відображення фолбека. Якщо їх прибрати або закоментувати, фолбек-версію буде видно, і ви зможете налаштувати її дизайн під потрібний вигляд. Не забудьте повернути ці стилі перед надсиланням листа.
Ці стилі не мають чітких правил для кожного поштового клієнта, але є набір хаків, які можна використовувати для керування відображенням:
- стилі, що починаються з [owa], використовуються для Outlook;
- стилі [class~="x_container"] необхідні для Outlook у разі, якщо [owa] не працює;
- стилі body[data-outlook-cycle] необхідні для роботи з Outlook на мобільних пристроях iOS і Android;
- mso-hide:all; використовуються для Outlook.com.
Повний код для інтерактивної та фолбек-версій
Тут наведено код фолбека гри, разом з інтерактивною HTML-частиною та фолбек-версією:
<style>
.dot-html .dot-container {
background: url(https://zlnfb.stripocdn.email/content/guids/CABINET_c102d17d796d323a0ee84181252016915f4177c79c86a55019b0dccf636e6f33/images/bg.png) no-repeat top center;
background-size: contain;
width: 300px;
height: 450px;
margin: 0 auto;
position: relative;
}
.dot-html .circle {
display: inline-block;
width: 10px;
height: 10px;
background: #000;
border-radius: 50%;
}
.dot-html .active .circle {
background: blue;
}
.dot-html .number {
display: block;
position: absolute;
right: -10px;
}
.dot-html .line {
background: #000;
width: 3px;
height: 100%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: none;
}
.dot-html .dot {
display: block;
cursor: pointer;
padding: 10px;
position: absolute;
bottom: -18px;
left: 50%;
transform: translate(-50%, 0);
}
.dot-html .block-1-2 {
width: 7.50%;
height: 20.17%;
position: absolute;
top: 1.67%;
right: 17.75%;
transform: rotate(-23deg);
}
.dot-html .dot-1 {
top: -14px;
bottom: auto;
}
.dot-html .dot-1 .number {
transform: rotate(23deg);
}
.dot-html .dot-2 .number {
transform: rotate(23deg);
}
.dot-html .block-2-3 {
width: 7.50%;
height: 16.83%;
position: absolute;
transform: rotate(-5deg);
top: 21.83%;
right: 10.50%;
}
.dot-html .dot-3 .number {
transform: rotate(5deg);
}
.dot-html .block-3-4 {
width: 7.50%;
height: 26.00%;
position: absolute;
transform: rotate(16deg);
top: 39.00%;
right: 14.50%;
}
.dot-html .dot-4 .number {
transform: rotate(-16deg);
}
.dot-html .block-4-5 {
width: 7.50%;
height: 17.50%;
position: absolute;
transform: rotate(91deg);
top: 56.83%;
right: 33.75%;
}
.dot-html .dot-5 .number {
transform: rotate(-91deg);
}
.dot-html .block-5-6 {
width: 7.50%;
height: 16.50%;
position: absolute;
transform: rotate(113deg);
top: 53.67%;
right: auto;
left: 32.00%;
}
.dot-html .dot-6 .number {
transform: rotate(-113deg);
}
.dot-html .block-6-7 {
width: 7.50%;
height: 20.00%;
position: absolute;
top: 38.17%;
right: auto;
left: 20.80%;
transform: rotate(4deg);
}
.dot-html .dot-7 {
top: -16px;
bottom: auto;
}
.dot-html .dot-7 .number {
transform: rotate(-2deg);
}
.dot-html .block-7-8 {
width: 7.50%;
height: 23.33%;
position: absolute;
transform: rotate(25deg);
top: 16.33%;
right: auto;
left: 29.00%;
}
.dot-html .dot-8 {
top: -16px;
bottom: auto;
}
.dot-html .dot-8 .number {
transform: rotate(-27deg);
}
.dot-html .block-8-9 {
width: 7.50%;
height: 20.83%;
position: absolute;
transform: rotate(54deg);
top: 0.5%;
right: auto;
left: 49.75%;
}
.dot-html .dot-9 {
top: -16px;
bottom: auto;
}
.dot-html .dot-9 .number {
transform: rotate(-54deg);
}
.dot-html .result {
padding: 20px 0;
text-align: center;
display: none;
}
@media only screen and (max-width: 600px) {
.dot-html .dot-container {
width: 250px;
height: 375px;
}
}
#input-dot-8:checked~#input-dot-9:checked~div .line-8-9,
#input-dot-7:checked~#input-dot-8:checked~div .line-7-8,
#input-dot-6:checked~#input-dot-7:checked~div .line-6-7,
#input-dot-5:checked~#input-dot-6:checked~div .line-5-6,
#input-dot-4:checked~#input-dot-5:checked~div .line-4-5,
#input-dot-3:checked~#input-dot-4:checked~div .line-3-4,
#input-dot-2:checked~#input-dot-3:checked~div .line-2-3,
#input-dot-1:checked~#input-dot-2:checked~div .line-1-2 {
display: block;
}
#input-dot-9:checked~div .dot-9 .circle,
#input-dot-8:checked~div .dot-8 .circle,
#input-dot-7:checked~div .dot-7 .circle,
#input-dot-6:checked~div .dot-6 .circle,
#input-dot-5:checked~div .dot-5 .circle,
#input-dot-4:checked~div .dot-4 .circle,
#input-dot-3:checked~div .dot-3 .circle,
#input-dot-2:checked~div .dot-2 .circle,
#input-dot-1:checked~div .dot-1 .circle,
.dot-html .dot:hover .circle {
background: blue;
}
#input-dot-1:checked~#input-dot-2:checked~div .dot-1 .circle,
#input-dot-2:checked~#input-dot-3:checked~div .dot-2 .circle,
#input-dot-3:checked~#input-dot-4:checked~div .dot-3 .circle,
#input-dot-4:checked~#input-dot-5:checked~div .dot-4 .circle,
#input-dot-5:checked~#input-dot-6:checked~div .dot-5 .circle,
#input-dot-6:checked~#input-dot-7:checked~div .dot-6 .circle,
#input-dot-7:checked~#input-dot-8:checked~div .dot-7 .circle,
#input-dot-8:checked~#input-dot-9:checked~div .dot-8 .circle {
background: #000;
}
#input-dot-1:checked~#input-dot-2:checked~#input-dot-3:checked~#input-dot-4:checked~#input-dot-5:checked~#input-dot-6:checked~#input-dot-7:checked~#input-dot-8:checked~#input-dot-9:checked~.result {
display: block;
}
/* --- */
@media screen and (-webkit-min-device-pixel-ratio: 0) {
input.fallback_ctrl:checked~.container {
display: block !important;
}
input.fallback_ctrl:checked~#fallback {
display: none !important;
}
}
[owa] .container {
display: none !important;
}
[class~="x_container"] {
display: none !important;
}
[id~="x_fallback"] {
display: block !important;
}
@media screen and (max-width: 600px) {
body[data-outlook-cycle] #fallback {
display: block !important;
}
body[data-outlook-cycle] .container {
display: none !important;
}
}
</style>
<!--[if !mso]><!--><input type="checkbox" id="fallback_ctrl" class="fallback_ctrl" style="display:none !important;mso-hide:all;" checked>
<!--<![endif]-->
<!-- FALLBACK -->
<div id="fallback" class="fallback">
<table width="100%">
<tbody>
<tr align="center">
<td><a target="_blank" href="https://viewstripo.email/c29e42f1-be3f-4496-baae-104fe5d89bb51719820023314?type=amphtml"><img src="https://zlnfb.stripocdn.email/content/guids/CABINET_c102d17d796d323a0ee84181252016915f4177c79c86a55019b0dccf636e6f33/images/bg.png" alt style="display: block;" width="258" height="450"></a></td>
</tr>
</tbody>
</table>
</div><!-- /FALLBACK -->
<!--[if !mso]><!-->
<!-- INTERACTIVE ELEMENT -->
<div class="container" style="mso-hide:all;display:none;">
<div class="dot-html"><input id="input-dot-1" name="input-dot-1" type="radio" style="display:none"><input id="input-dot-2" name="input-dot-2" type="radio" style="display:none"><input id="input-dot-3" name="input-dot-3" type="radio" style="display:none"><input id="input-dot-4" name="input-dot-4" type="radio" style="display:none"><input id="input-dot-5" name="input-dot-5" type="radio" style="display:none"><input id="input-dot-6" name="input-dot-6" type="radio" style="display:none"><input id="input-dot-7" name="input-dot-7" type="radio" style="display:none"><input id="input-dot-8" name="input-dot-8" type="radio" style="display:none"><input id="input-dot-9" name="input-dot-9" type="radio" style="display:none">
<div class="dot-container">
<div class="block-8-9">
<div class="line line-8-9"></div><label for="input-dot-9" class="dot dot-9"><span class="circle"></span><span class="number">9</span></label>
</div>
<div class="block-7-8">
<div class="line line-7-8"></div><label for="input-dot-8" class="dot dot-8"><span class="circle"></span><span class="number">8</span></label>
</div>
<div class="block-6-7">
<div class="line line-6-7"></div><label for="input-dot-7" class="dot dot-7"><span class="circle"></span><span class="number">7</span></label>
</div>
<div class="block-5-6">
<div class="line line-5-6"></div><label for="input-dot-6" class="dot dot-6"><span class="number">6</span><span class="circle"></span></label>
</div>
<div class="block-4-5">
<div class="line line-4-5"></div><label for="input-dot-5" class="dot dot-5"><span class="number">5</span><span class="circle"></span></label>
</div>
<div class="block-3-4">
<div class="line line-3-4"></div><label for="input-dot-4" class="dot dot-4"><span class="number">4</span><span class="circle"></span></label>
</div>
<div class="block-2-3">
<div class="line line-2-3"></div><label for="input-dot-3" class="dot dot-3"><span class="number">3</span><span class="circle"></span></label>
</div>
<div class="block-1-2">
<div class="line line-1-2"></div><label for="input-dot-1" class="dot dot-1"><span class="number">1</span><span class="circle"></span></label><label for="input-dot-2" class="dot dot-2"><span class="number">2</span><span class="circle"></span></label>
</div>
</div>
<div class="result">
<h2 style="padding-bottom:15px">Congratulations!</h2>
<p>Here's your personal promo code GAMIFICATION for 15% OFF sitewide.</p>
</div>
</div>
</div><!-- /INTERACTIVE ELEMENT -->
<!--<![endif]-->
Ця частина коду призначена лише для перевірки і для того, щоб переконатися, що ви не припустилися помилок на попередніх етапах нашого гайда. Якщо щось не працює так, як задумано, порівняйте свій код із цим повним прикладом, щоб зрозуміти, у чому справа.
На завершення
На перший погляд, гра може здатися досить простою, але її принадність у тому, що ви обмежені тільки своєю фантазією в тому, який малюнок можна вигадати. Складність і захопливість гри залежить лише від того, наскільки сильно ви захочете зробити її такою, створюючи різні версії гри «З'єднайте точки».
Сподіваємося, що цей гайд стане надійною опорою для наповнення ваших листів інтерактивністю та новими механіками.