• Как сверстать этот элемент?

    space2pacman
    @space2pacman
    Просто царь.

    Ответ написан
    Комментировать
  • Можно ли использовать тег picture внутри figure?

    MrDecoy
    @MrDecoy Куратор тега HTML
    Верставший фронтендер
    А почему нет? picture рендерит img.
    А img же можно в figure?
    https://caninclude.glitch.me/can/include/?child=pi...
    Ответ написан
    1 комментарий
  • Зачем пользоваться сейчас препроцессорами sass и scss?

    delphinpro
    @delphinpro Куратор тега CSS
    frontend developer
    Посмотрите на бутстрап.
    Единственный файл variables.scss позволяет гибко кастомизировать весь фреймворк.
    Стили структурированы.

    Это два основных преимущества: централизованное управление и организация кода.

    Далее, довольно много популярных компонентов и плагинов поставляются с scss/less исходниками. При необходимости кастомизации (а такая необходимость присутствует почти всегда), вы можете пойти тремя путями:

    1. Скопировать себе файл стилей и переписать его
    2. Подключить оригинальные стили и переназначить селекторы в своей таблицы.
    3. Подключить исходники и только переназначить переменные

    Еще кейс:

    Берем какой-то крупный фреймворк, пусть будет тот же бутстрап. Половина компонентов нам в нем не нужны.
    Мы снова можем подключить весь оригинальный файл с лишними стилями. Или мы можем взять исходники и подключить в сборку только необходимое нам. Если завтра нам понадобится еще какой-то компонент, мы просто раскомментируем строку с его подключением.

    Еще:

    Нам нужно задавать размеры в rem.

    Мы можем пойти по плохому пути: назначить руту font-size: 10px и легко рассчитывать ремы в уме. Но ведь задавать пиксели для html не следует.
    Или мы можем написать функцию toRem() в препроцессоре и использовать ее.

    Не говорю уже о более сложных расчетах.
    Или о громоздких.
    Вот например: https://codepen.io/delphinpro/pen/QvLZxg?editors=0100
    Посмотрите строку 62 в стилях. Там генерится 60 селекторов. Удобно будет такое писать на голом CSS?

    Могу еще писать, но время дорого.
    Ответ написан
    Комментировать
  • Как сделай такой эффект на слове ICE на css?

    Ankhena
    @Ankhena Куратор тега CSS
    Нежно люблю верстку
    3 комментария
  • Как ускорить загрузку карты Яндекс?

    @aleksandr-n
    На мой взгляд лучший вариант описан тут
    Асинхронная загрузка
    Для асинхронной загрузки скрипта потребуется добавить атрибут async и вызов callback-функции в параметре onload т.к. ymaps.ready(init) будет недоступен.
    <div id="map" style="width: 100%; height: 300px;"></div>

    <script async src="//api-maps.yandex.ru/2.0/?load=package.standard&lang=ru-RU&onload=getYaMap"></script>
    <script>
    function getYaMap(){
    	var myMap = new ymaps.Map("map",{center: [30.325,59.935],zoom: 13});
    	ymaps.geocode("Санкт-Петербург, ул. Невский проспект, 28").then(function (res) {
    		var coord = res.geoObjects.get(0).geometry.getCoordinates();
    		var myPlacemark = new ymaps.Placemark(coord);
    		myMap.geoObjects.add(myPlacemark);
    		myMap.setCenter(coord);					
    	});
    }
    </script>

    Отложенная загрузка
    Самый лучший вариант – отложить загрузку скрипта на 2-3 секунды с помощью setTimeout().
    <div id="map" style="width: 100%; height: 300px;"></div>

    <script>
    setTimeout(function(){
    	var elem = document.createElement('script');
    	elem.type = 'text/javascript';
    	elem.src = '//api-maps.yandex.ru/2.0/?load=package.standard&lang=ru-RU&onload=getYaMap';
    	document.getElementsByTagName('body')[0].appendChild(elem);
    }, 2000);
    function getYaMap(){
    	var myMap = new ymaps.Map("map",{center: [30.325,59.935],zoom: 13});
    	ymaps.geocode("Санкт-Петербург, ул. Невский проспект, 28").then(function (res) {
    		var coord = res.geoObjects.get(0).geometry.getCoordinates();
    		var myPlacemark = new ymaps.Placemark(coord);
    		myMap.geoObjects.add(myPlacemark);
    		myMap.setCenter(coord);					
    	});
    }
    </script>
    Ответ написан
    1 комментарий
  • Как реализовать вот такой эффект?

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    SVG-маски - наше все. Хотя в этом случае вариант с clip-path тоже очень даже рабочий. Еще есть вариант маски на шейдерах, но это совсем особый случай, хотя может внезапно оказаться очень производительным.

    Ответ написан
    Комментировать
  • Как бороться с дыркой если justify-content:space-between?

    AndrewHaze
    @AndrewHaze
    Умею гуглить яндексом
    Есть такой хак
    <flex элемент с justify-content:space-between>:after {
            content: "";
            flex: auto;
            justify-content: flex-start;
    }

    правда в IE всё как всегда
    Ответ написан
    2 комментария
  • Как сделать идеальный квадрат задав только размер одной стороне блока?

    SmthTo
    @SmthTo Куратор тега CSS
    Все перепёлки мира будут оплакивать мою смерть.
    Ответ написан
    Комментировать
  • Как верстать доступные сайты?

    MrDecoy
    @MrDecoy
    Верставший фронтендер
    То, о чём Вы спрашиваете, официально называется WAI-ARIA.
    Тут можно скачать бесплатно экранного диктора и с помощью него тестировать свои сайты, осуществляя навигацию по ним с помощью табуляции, а так же открывая специальное меню с помощью горячих клавиш (командная кнопка приложения, которую назначите, по умолчанию ins+f7, или f6? Не помню уже точно :-) )

    Доклады Вадима Макеева на ютубе:
    https://www.youtube.com/watch?v=MWJKwn_gKR4
    https://www.youtube.com/watch?v=ssJsjGZE2sc

    Если действительно умеете соблюдать семантику, то, скорее всего, Вы уже сделали достаточно.
    Рускоязычные ресурсы по доступности:
    https://weblind.ru/
    specialbank.ru/guide (В данный момент чёт не работает, но должен)
    Есть курс, где учат именно этому: https://kurmak.info/
    Статья на хабре: https://habr.com/ru/post/40730/ (там внизу есть полезные ссылки)
    Тут можно найти информацию по этому вопросу, в том числе перевод статей из первой ссылки англоязычных ресурсов

    В подкасте Веб-стандарты упоминается об этом очень часто. Тут можно прослушать все выпуски, а так же покопаться в выпусках и поискать упоминания доступности и статьи про это.

    Есть англоязычные ресурсы
    Про доступные компоненты: https://inclusive-components.design/ (нажимаете в хроме справа сверху "перевести страницу" и профит)
    Есть спецификация: https://www.w3.org/TR/wai-aria-1.1/#usage (аналогично, перевод в браузере и профит)
    MDN: https://developer.mozilla.org/en-US/docs/Learn/Acc...
    Ответ написан
    1 комментарий
  • Как фильтровать элементы с кириллицей в isotope.js?

    firedragon
    @firedragon
    Не джун-мидл-сеньор, а трус-балбес-бывалый.
    Я бы использовал транслит.

    абиссинское золото -> abessinskoye_zoloto

    https://github.com/greybax/cyrillic-to-translit-js
    Ответ написан
    Комментировать
  • Устарел ли getElementsBy* и чем лучше querrySelector?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Вот народ ушел в спор о производительности, но никто даже не попытался разобраться, а что под капотом... Производительность ведь искусственными бенчмарками меряют, ага...
    Что ж, времена сейчас такие
    многие на работу кодеров берут, которые даже интереса не имеют в глубь копать. Инженеров брать... - это устаревший подход, как выразился автор "популярного сайта", который прочел автор вопроса. Инженеры они дорогие, и найти их сложно, лучше кодер, пусть и не желающий на работе мозг включать, не говоря уж о желании в устройстве инструментов разбираться.

    Говорить о том, что некие фичи устарели - крайне глупо, если знать, что они ведут себя иначе, чем более модные альтернативы. Предлагаю немного разобраться и начать с того что на поверхности:
    - getElementById и querySelector возвращают конкретную ноду в единственном экземпляре
    - querySelectorAll и getElementsByName возвращает статичную коллекцию NodeList
    - getElementsByClassName, getElementsByTagName и getElementsByTagNameNS возвращают динамическую коллекцию HTMLCollection
    Как видим результат у разного апи различен, а значит и говорить, что некоторые из них устарели - глупо.
    Правда тут есть забавный момент
    в спеке HTMLCollection отмечен как "исторический артефакт", который не стоит использовать при проектировании нового апи. Но заметка эта не для веб-разработчиков, а для тех кто проектирует новое DOM апи.

    С устареванием вроде разобрались, но в вопросе еще есть часть "чем лучше". И тут есть теория, что getElementsBy* быстрее querySelector*. Чисто теоретически звучит логично, querySelector* должен делать полный поиск по дереву со сложностью O(n), а getElementsBy* могут использовать индексы на базе HashMap и получать данные со сложностью O(1), тут и особенности HTMLCollection будут кстати, так как можно не копировать коллекцию, а отдавать одну и ту же (и браузеры действительно так делают). Но без пруфов теория так и останется теорией.
    И бенчмарки - так себе пруф
    Хотя направлять инвесторов в нужную сторону - самое то. Проблема бенчмарков, что можно написать их так, что любая из сравниваемых сторон заметно обгонит другую. Дело техники. Например BubbleSort с O(n2) при определенных условиях в чистую уделывает MergeSort и QuickSort с их O(n×log2n), а именно при n=20 или меньше, 400 простых memswap в наглую рвут 87 рекурсивных операций с memcpy внутри
    Гораздо лучше тут выглядят исходники. И я выбрал исходники chromium, как самого распространенного:
    - getElementsBy* методы все как один обращаются к некой шаблонной функции EnsureCachedCollection, которая в свою очередь обращается к некоему NodeLists кэшу, устроенному внутри действительно как HashMap или что-то наподобие. Никакого поиска тут нет, просто берутся готовые значения, сложность у всего этого действительно константная O(1).
    - querySelector* используют абстракцию SelectorQuery, которая и в самом деле делает поиск по DOM. Но данный поиск неплохо оптимизирован и обвешан кэшами. Притом CSSOM использует абсолютно тот же алгоритм поиска DOM нод для каждого селектора в css.
    Для примера
    в подключенных на странице этого вопроса стилях более 1600 правил (некоторые из которых потенциально могут содержать несколько селекторов), полная обработка стилей из этого файла заняла на моей машине (Ryzen 3600 в стоке) чуть больше 9 мс. Если все это немного округлить, то понадобится 15000 querySelectorAll подряд, притом с разными селекторами, чтоб был промах кэша, дабы я ощутил заметную глазу задержку в ~100мс


    На этом спор думаю можно закрыть. querySelector* методы действительно могут быть медленнее, но чтоб убить ими производительность, нужно очень постараться. На фоне того, что пишут кривые ручки среднестатистического дешевого js-кодера это будет незначительной потерей измеряемой в наносекундах. Используйте то что удобнее в каждой конкретной ситуации.
    Ответ написан
    1 комментарий
  • Когда использовать микс, а когда модификатор?

    Realetive
    @Realetive
    MODX Ambassador России, самозванный БЭМ-евангелист
    Первое, что нужно научиться делать — находить повторяющиеся сущности (которые в последствии станут Блоками и Элементами). Вы уже пытаетесь сделать это, но пока получается слишком многословно, судя по количеству классов и это, очевидно, сбивает с толку.
    Я уже рассказывал на последнем БЭМапе (https://youtu.be/d4dcGj8abv0) о том, как я ищу эти повторяющиеся закономерности, поэтому постараюсь кратко:
    1) Собираем и группируем «данные»
    Разберём «шапку» и «подвал». И там, и там есть логотип, какая-то навигация, контактная информация, ссылки на соц. сети, в шапке есть кнопка:
    1.1) «Шапка»

    {
      logo: {
        img: 'путь до картинки',
        text: '…',
      },
      contacts: [
        'телефон',
        'email',
        'график работы',
        'адрес',
        'соц. сети',
        'кнопка обратной связи',
      ],
      navigation: [
        'пункт меню…',
        'пункт меню…',
        'пункт меню…',
      ]
    }


    1.2) В «подвале» почти то же самое, что-то в другом порядке, но это неважно, и нет «кнопки обратной связи» из секции «Контактов».

    1.3) Есть ещё самостоятельные секции «Свяжитесь с нами» на главной странице и на странице контактов, которые тоже используют пункты из секции «Контактов» (теперь уже понятно, что такое частое повторение позволяет выделить это в блок).

    1.4) Логотип и навигацию тоже выделим в блоки (я разделил логотип на два элемента — изображение и текст, потому что на малых экранах текст превращается в замыленое нечитаемое говно, поэтому его лучше убрать).

    1.5) Получается какая-то такая структура:

    // Блок логотипа
    {
      logo: [
        { img: '…' },
        { text: '…' },
      ]
    }
    
    // Блок контактов
    {
      contacts: [
        { tel: '…' },
        { email: '…' },
        { schedule: '…' },
        { address: '…' },
        { socials: [
          { vk: '…' },
          { telegram: '…' },
          { instagram: '…' },
        ] },
        { map: '…' },
        { feedback: '…' },
      ]
    }
    
    // Блок навигации
    {
      navigation: [
        { item: '', link: '…' },
        { item: '', link: '…' },
        { item: '', link: '…' },
      ]
    }
    
    // Блок «Шапки»
    {
      header: [
        {
          logo: [] // Тут всё без изменений
        },
        {
          contacts: [
            'tel',
            'email',
            'schedule',
            'address',
            'socials',
            'feedback',
          ]
        },
        {
          navigation: [] // Тут тоже без изменений
        }
      ]
    }
    
    // Блок «Подвала»
    {
      footer: [
        {
          logo: [] // Тут всё без изменений
        },
        {
          navigation: [ // Тут почти без изменений
            // …
            'Марки автомобилей' // Без выпадающего списка
            // …
          ]
        },
        {
          contacts: [
            'tel',
            'email',
            'address',
            'socials',
            'schedule', // Без иконки
          ]
        },
      ]
    }



    2) Вроде, пока хватит. «БЭМизируем» эти данные.
    Структура в формате JSON

    // Блок логотипа
    {
      block: 'logo'
      content: [
        { elem: 'img', src: '…' },
        { text: '…' },
      ]
    }
    
    // Блок контактов
    {
      block: 'contacts'
      content: [
        { elem: 'tel', content: '…' },
        { elem: 'email', content: '…' },
        { elem: 'schedule', content: '…' },
        { elem: 'address', content: '…' },
        { elem: 'socials', content: [
          { elem: 'vk', content: '…' },
          { elem: 'telegram', content: '…' },
          { elem: 'instagram', content: '…' },
        ] },
        { elem: 'map', content: '…' },
        { elem: 'feedback', content: '…' },
      ]
    }
    
    // Блок навигации
    {
      navigation: [
        { item: '', link: '…' },
        { item: '', link: '…' },
        { item: '', link: '…' },
      ]
    }
    
    // Блок «Шапки»
    {
      header: [
        {
          block: 'logo'
        },
        {
          block: 'contacts',
          // У этого блока определённо свой контент,
          // будем отличать его от других вариантов
          // этого блока с помощью модификатора
          mods: { view: 'header' },
          content: [
            { elem: 'tel' },
            { elem: 'email' },
            { elem: 'schedule' },
            { elem: 'address' },
            { elem: 'socials' },
            { elem: 'feedback' },
          ]
        },
        {
          block: 'navigation',
          // Этот блок по внешнему виду отличается от блока в «Подвале»,
          // поэтому обозначим его модификатором
          mods: { view: 'header' },
          content: [
            // …
            // У одного пункта выпадающий список
            {
              elem: 'item',
              item: 'Марки автомобилей',
              elemMods: { dropdown: true },
              content: [
                // …
                { elem: 'subitem', item: 'Infinity', href: '…' }
              ]
            },
            // …
          ]
        }
      ]
    }
    
    // Блок «Подвала»
    {
      footer: [
        {
          block: 'logo'
        },
        {
          block: 'navigation',
          mods: { view: 'footer' },
          content: [ // Тут почти без изменений
            // …
            { elem: 'Марки автомобилей', link: '…' }, // Без выпадающего списка
            // …
          ]
        },
        {
          contacts: [
            'tel',
            'email',
            'address',
            'socials',
            { elem: 'schedule', elemMods: { noIcon: true } }, // Без иконки
          ]
        },
      ]
    }


    2.1) Базовый лэйаут: https://codepen.io/Realetive/pen/PoGRjZo
    2.2) Добавляем обёртки для группировки некоторых элементов: https://codepen.io/Realetive/pen/KKgoBdN
    Про обёртки и зачем они нужны уже обсуждалось в https://ru.bem.info/forum/656/, очень советую.
    2.3) Добавим отступы: https://codepen.io/Realetive/pen/bGwvjow
    Как видите, миксы по-прежнему не нужны.
    3) У контента есть фиксированная ширина, обозначим её через класс-элемент блока page: например, .page__layout:
    https://codepen.io/Realetive/pen/WNGzgjJ
    Но вёрстка закономерно сбилась, потому что классы, которые мы назначали для родительского уровня, «поднялись» ещё н один уровень. Добавим ещё обёртки, чтобы «выровнять» лэйаут: стили header перенесутся в header__body, из footer в footer__body: https://codepen.io/Realetive/pen/wvzmEpy
    4) Получилось достаточно много «лишних» обёрток только лишь для позиционирования. Можно было бы этого избежать, если бы стили были описаны в одном классе. Но тогда мы лишимся пользы разделения логики благодаря БЭМ-неймингу. Вместо этого объединим эти слои с помощью миксов: page__header + header, header__body + page__layout, page__footer + footer, footer__body + page__layout: https://codepen.io/Realetive/pen/RwGMYyV

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

    Блок с контактами делается аналогичным способом:
    .page__section.page__section_view_feedback
      .page__layout
        .form.form_view_feedback.page__column_width_half (миксуем блок формы обратной связи и лэйаут 1/2 колонки)
          …
        .contacts_view_feedback.page__column_width_half
          .contacts__info
            .contacts__address
            .contacts__email
            .contacts__tel
            .contacts__schedule
          .contacts__map
    Ответ написан
    1 комментарий
  • Как получить реальные 100vh на смартфоне?

    SkiperX
    @SkiperX Куратор тега CSS
    Решение на js
    /*Viewport Height Correction
        https://github.com/Faisal-Manzer/postcss-viewport-height-correction
         .foo {
                height: 100vh;
                height: calc(var(--vh, 1vh) * 100); //
          }
        */
        var customViewportCorrectionVariable = 'vh';
        function setViewportProperty(doc) {
            var prevClientHeight;
            var customVar = '--' + ( customViewportCorrectionVariable || 'vh' );
            function handleResize() {
                var clientHeight = doc.clientHeight;
                if (clientHeight === prevClientHeight) return;
                requestAnimationFrame(function updateViewportHeight(){
                    doc.style.setProperty(customVar, (clientHeight * 0.01) + 'px');
                    prevClientHeight = clientHeight;
                });
            }
            handleResize();
            return handleResize;
        }
        window.addEventListener('resize', setViewportProperty(document.documentElement));
        /*/Viewport Height Correction*/
    Ответ написан
    Комментировать
  • Как найти участок проблемного кода если исходники не поддаются анализу?

    @dmitry-toster
    Как выявить то самое проблемное место в коде, где добавляется лишний класс к кнопке?

    1. Брейкпоинтом браузера
    5ff3aaebcc55a434489373.png
    Также можно отследить любые события и манипуляции с DOM
    2. Поиск по коду проекта (искать по названию класса). В любой современной IDE это делается за пару секунд
    3. Браузерным расширением фреймворка (если таковой используется). Которое покажет название компонента и его искать уже в исходниках проекта
    Ответ написан
    1 комментарий
  • Как сделать много 301 редиректов?

    shambler81
    @shambler81 Куратор тега htaccess
    1 собираешь в экселе файл с 500 урлами что и куда.
    2. https://donatstudios.com/RewriteRule_Generator
    собственно все.
    Если есть логика типа изменить 1 часть урла например у 400 товаров заменить /catalog на /tovar
    ТО прикрепляй файлик сюда, я тебе сделюаю регулярки на повторяющиеся элементы.
    Ответ написан
    Комментировать
  • Функция .next() на чистом Javascript?

    dollar
    @dollar
    Делай добро и бросай его в воду.
    <div class="one">
          <p class="text"></p>
    </div>
    <div class="two">
          <p class="text"></p>
    </div>
    <script type="text/javascript">
          let contain = document.querySelector('.one > .text');
          contain.innerHTML = 'Текст 1';
          let next = contain.parentElement.nextElementSibling.firstElementChild;
          next.innerHTML = 'Текст 2';
    </script>
    Ответ написан
    Комментировать