Любой код из заметок тестировался ТОЛЬКО в последних версиях популярных браузеров.
Ибо, пока разработчики поддерживать совместимость со старыми браузерами - люди будут использовать старые браузеры.
1 2 3 4 5 6 7 8 |
<div class="columns"> <div>...</div> <div>...</div> <div>...</div> <div>...</div> <div>...</div> <div>...</div> </div> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
.columns { /* Настройки */ --min-column-size: 200px; --max-column-count: 4; --gap: 20px; /* Вычисления */ --breakpoint: calc(var(--min-column-size) * var(--max-column-count) + (var(--gap) * (var(--max-column-count) - 1))); --column-size: calc((100% / var(--max-column-count)) - var(--gap)); display: grid; gap: var(--gap); grid-template-columns: repeat(auto-fit, minmax(min(max(var(--column-size), (100% - var(--breakpoint)) * -999), 100%), 1fr)); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<div class="cover"> <div class="text"> <div class="text_inner"> <p>...</p> </div> </div> <button type="button" class="text_more"> <div>Читать далее</div> <div>Скрыть часть</div> </button> </div> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
.text { display: grid; grid-template-rows: 12em; transition: all 300ms linear; } .text_inner { position: relative; overflow: hidden; } .text.shown { grid-template-rows: 1fr; } .text_inner::after { content: ''; display: block; position: absolute; left: 0; right: 0; bottom: 0; height: 2em; background: rgb(255,255,255); background: -moz-linear-gradient(180deg, rgba(255,255,255,0) 0%, rgba(255,255,255,1) 100%); background: -webkit-linear-gradient(180deg, rgba(255,255,255,0) 0%, rgba(255,255,255,1) 100%); background: linear-gradient(180deg, rgba(255,255,255,0) 0%, rgba(255,255,255,1) 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#ffffff",endColorstr="#ffffff",GradientType=1); transition: all 300ms linear; opacity: 1; visibility: visible; } .text.shown .text_inner::after { opacity: 0; visibility: hidden; } .text_more.active div:nth-child(1), .text_more:not(.active) div:nth-child(2) { display: none; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
document.addEventListener('DOMContentLoaded', function(event) { // Показать / Скрыть часть текста [].forEach.call(document.querySelectorAll('.cover'), function(cover) { let text = cover.querySelector('.text'); [].forEach.call(cover.querySelectorAll('.text_more'), function(toggle) { toggle.addEventListener('click', function(e) { e.preventDefault(); if (text.classList.contains('shown')) { text.classList.remove('shown'); toggle.classList.remove('active'); text.scrollIntoView(); } else { text.classList.add('shown'); toggle.classList.add('active'); } }); }); }); }); |
Нумерация дочерних списков начинается с номера родителя.
1 2 3 4 5 6 7 8 9 10 11 |
<ol> <li>Первый уровень <ol> <li>Второй уровень <ol> <li>Третий уровень</li> </ol> </li> </ol> </li> </ol> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
ol { counter-reset: level1; list-style-type: none; } ol ol { counter-reset: level2; } ol ol ol { counter-reset: level3; } ol li { list-style-type:none; } ol li::before { counter-increment: level1; content: counter(level1) '. '; } ol ol li::before { counter-increment: level2; content: counter(level1) '.' counter(level2) ' '; } ol ol ol li::before { counter-increment: level3; content: counter(level1) '.' counter(level2) '.' counter(level3) ' '; } |
1 2 3 4 5 6 7 |
:root { --main-color: #444; } .selector { color: var(--main-color); /* вторым параметром можно указать значение по умолчанию (если переменная не задана) */ } |
1 2 3 4 5 6 7 8 9 10 11 12 |
document.addEventListener('DOMContentLoaded', function(event) { let root = document.querySelector(':root'), styles = root.getComputedStyle(root); // Получить значение styles.getPropertyValue('--main-color') // Изменить значение root.style.setProerty('--main-color', '#777'); }); |
1 2 3 4 5 6 7 8 9 10 11 12 |
/* clamp(min, mid, max); min = минимально допустимый размер mid = max в относительных единицах измерения на экране, начиная с которого нужно применять max max = максимально допустимый размер Пример: 4vw ≈ 40px на экране 1024px */ .selector { clamp(20px, 4vw, 40px); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<div class="box crumbs"> <div class="inner"> <div class="content"> <div class="crumbs_row"> <div class="crumbs_item"> <a href="#">Главная</a> </div> <div class="crumbs_sep">/</div> <div class="crumbs_item"> <a href="#">Родительская</a> </div> <div class="crumbs_sep">/</div> <div class="crumbs_item"> <div>Текущая</div> </div> </div> </div> </div> </div> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
.crumbs { line-height: 16px; white-space: nowrap; } .crumbs .inner { position: relative; overflow: auto; } .crumbs::after { content: ''; display: block; width: 30px; height: 100%; position: absolute; top: 0; right: 0; background: linear-gradient(90deg, rgba(255,255,255,0) 0%, rgba(255,255,255,1) 90%); } .crumbs .content { height: 36px; /* line-height + 20px */ } .crumbs_row { display: grid; grid-auto-flow: column; padding: 0 20px; height: 16px; /* line-height */ position: absolute; top: 0; left: 0; } .crumbs_item a { display: block; border-bottom: 1px solid transparent; } .crumbs_item a:hover { border-bottom-color: #000; } .crumbs_sep { margin: 0 5px; } /* 1280px - экран после которого контентная часть перестает растягиваться по ширине */ @media (min-width: 1280px) { .crumbs_row { padding: 0 calc((100% - 1160px) / 2); /* 1160px - максимальная ширина контентной частии */ } } |
100 – Thin || Hairline
200 – Extra Light || Ultra Light || Thin
300 – Light
400 – Normal || Regular
500 – Medium
600 – Semi Bold || Demi Bold
700 – Bold
800 – Extra Bold || Ultra Bold || Heavy
900 – Black || Heavy
1 2 3 4 |
<label> <input type="checkbox" name=""> <div>Text</div> </label> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
label input[type="radio"], label input[type="checkbox"] { display: none; } label input[type="radio"] + div, label input[type="checkbox"] + div { cursor: pointer; position: relative; display: block; padding: 0 0 0 30px; } label input[type="radio"] + div::before, label input[type="radio"] + div::after, label input[type="checkbox"] + div::before, label input[type="checkbox"] + div::after { content: ''; display: block; position: absolute; box-sizing: border-box; } label input[type="radio"] + div::before, label input[type="radio"] + div::after { border-radius: 50%; } label input[type="radio"] + div::before, label input[type="checkbox"] + div::before { top: 0; left: 0; width: 16px; height: 16px; border: 1px solid #000; } label input[type="radio"] + div::after, label input[type="checkbox"] + div::after { opacity: 0; top: 3px; left: 3px; width: 10px; height: 10px; background: #000; transition: all 200ms linear; } label input[type="radio"]:checked + div::after, label input[type="checkbox"]:checked + div::after { opacity: 1; } |
Если кликнуть по кнопке — эффект будет сохраняться до повторного клика.
НЕ используется CSS псевдокласс :hover
т.к. на мобильных устройствах он отрабатывает при клике и элемент переходит в состояние :hover
, а выходит из него только после потери фокуса, т.е. клике по другому элементу.
1 2 3 4 5 6 7 8 9 10 |
<button type="button" class="burger_button" data-target=".menu"> <div class="burger_lines">Меню</div> </button> <div class="menu"> <div class="menu_item"> <a href="#" class="menu_item_a">Item</a> </div> ... </div> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
@media (max-width: 1023px) { .head_panel { position: absolute; top: 60px; right: -100vw; width: 80vw; transition: all 300ms linear; opacity: 0; } .head_panel.shown { right: 0; opacity: 1; } .burger_button { position: relative; display: block; width: 28px; height: 28px; padding: 0; overflow: hidden; font-size: 0; text-indent: -9999px; border: none; background: none; } .burger_lines, .burger_lines::before, .burger_lines::after { position: absolute; left: 0; right: 0; width: 100%; height: 2px; background: #141414; transition: all 300ms linear; } .burger_lines { left: 0; top: 13px; } .burger_lines::before, .burger_lines::after { content: ''; display: block; } .burger_lines::before { top: -8px; } .burger_lines::after { bottom: -8px; } .burger_lines.active { background: none; } .burger_lines.active::before { top: 0; transform: rotate(45deg); } .burger_lines.active::after { bottom: 0; transform: rotate(-45deg); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
jQuery(document).ready(function($) { $B = $('body'); // Бургер (function(){ let $trigs = $B.find('.burger_button'); if (!$trigs.length) return; $trigs.each(function (i, e) { let $trig = $(e), $targ = $B.find($trig.data('target')); if (!$targ.length) return false; $trig.on('click', function() { $trig.find('.burger_lines').toggleClass('active'); $targ.toggleClass('shown'); }); }); })(); }); |
1 |
<span data-tip="Всплывающая подсказка">Демо</span> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
[data-tip] { position: relative; cursor: help; padding: 1px 3px 2px; background: rgba(0, 0, 0, .1); border-bottom: dotted 1px rgba(0, 0, 0, .8); } [data-tip]::before, [data-tip]::after { opacity: 0; visibility: hidden; position: absolute; top: 80%; transition: all 200ms linear; pointer-events: none; } [data-tip]::before { content: ''; display: block; width: 0; height: 0; left: 50%; margin: 0 0 0 -5px; border: solid transparent 5px; border-bottom-color: rgba(0, 0, 0, .8); } [data-tip]::after { content: attr(data-tip); display: inline-block; padding: 3px 6px; left: 0; margin: 10px 0 0 0; color: #fff; font-size: 13px; white-space: nowrap; background: rgba(0, 0, 0, .8); } [data-tip]:hover::after, [data-tip]:hover::before { opacity: 1; visibility: visible; z-index: 2; top: 100%; } |