• Как влияет подключение на твой сайт?

    mizutsune
    @mizutsune
    Frontend Developer
    Подключение библиотек/плагинов через CDN конечно в той или иной степени может увеличить скорость загрузки, но нужно понимать что у такого подхода есть свои подводные камни.

    На самом деле минусов может быть больше, но я выделю два основных:

    1. Неизвестно какое обновление получит та или иная внешняя библиотека, что в свою очередь может стать угрозой для безопасности.

    2. Несмотря на популярность CDN, не стоит забывать что эта сеть не является настолько мощной, чтобы пробиваться сквозь различные блокировки сайтов, интернет провайдерами.

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

    Имеется какой-нибудь сайт, например интернет магазин. Сам сайт открывается отлично, всё работает, но на сайте через CDN подключены несколько десятков библиотек, допустим: Слайдер, Модальные окна, Аккордеоны, Тултипы и ещё 100500+ библиотек и плагинов.

    У 99% посетителей всё будет загружаться, работать отлично, но есть как минимум 1% людей у которых подключение к CDN блокируется. Получается что у этого процента посетителей сайт будет отображаться кривым и поломанным, а ещё множество функций будут недоступны. Если суть не понятна, тогда сверстайте страницу, напичкайте её компонентами, а затем просто отключите скрипты и стили. Не думаю что результат понравится вам как разработчику, а обычным пользователям тем более.

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

    Можно было бы конечно привести ещё какие-нибудь примеры подводных камней, но я не особо в курсе прям всех плохих сценариев, потому что обычно подключаю библиотеки из того же хранилища, где лежат основные скрипты/стили/etc.

    Ну, а выбирать между нативным fetch и axios, нужно исходя из нужного функционала. На данный вопрос сложно ответить, так как это зависит от многих факторов.
    Ответ написан
  • Как определить при помощи JS браузер пользователя и его ip?

    mizutsune
    @mizutsune
    Frontend Developer
    Можно достать информацию из navigator.userAgent и регулярными выражениями разбить полученную информацию на нужные фрагменты, после чего использовать. Но такой вариант подходит если есть опыт работы с регулярными выражениями.

    Если пойти другим путем, можно вывести в консоль объект navigator и посмотреть какие свойства имеются в наличии, после чего подготовить функцию в которой будет происходить получение информации из нужных свойств объекта. Например в navigator.userAgentData хранится информация, которую можно использовать сразу, без обработки регулярными выражениями.

    Или поискать библиотеки для подобных задач и использовать их для решения своих задач. Например есть такая библиотека UAParser.js или browser-dtector или Detect.js или куча других готовых решений.

    Про получение IP - адреса, уже написали в соседних ответах.
    Ответ написан
    Комментировать
  • Как сделать на JS чтобы скрипт срабатывал только на определенной ширине экрана?

    mizutsune
    @mizutsune
    Frontend Developer
    Как вариант можно использовать window.matchMedia.

    Пример:

    const slider = new Slider();
    const breakpoint = window.matchMedia("(min-width: 1200px)");
    
    if (breakpoint.matches) {
       slider.init();
    }


    Или:

    const slider = new Slider();
    const breakpoint = window.matchMedia("(max-width: 1200px)");
    
    const breakpointChecker = () => {
       if (breakpoint.matches) {
          slider.init();
       } else {
          slider.destroy();
       }
    };
    
    breakpoint.addEventListener("change", breakpointChecker);
    breakpointChecker();


    У нормальных слайдеров имеются методы init() и destroy() или аналогичные методы для включения и отключения слайдера. Так вот, используя эти методы в связке с matchMedia(), можно добиться желаемого результата.

    Альтернативный вариант.

    Можно использовать window.innerWidth или element.clientWidth или window.outerWidth в связке с условным оператором if.

    Пример:

    // если ширина окна больше или равна 1200px,
    // выполняем инициализацию слайдера
    
    if(window.innerWidth >= 1200) {
       slider.init();
    }


    Однако данная проверка будет работать только при загрузке страницы и если нужно включать/отключать слайдер при ресайзе, то в таком случае потребуется использование обработчика с событием resize + с каким-нибудь флагом или с функцией debounce, чтобы не допускать вызова функций при каждом изменении размера окна.
    Ответ написан
    Комментировать
  • Как сделать кнопки в виде квадратиков и списка?

    mizutsune
    @mizutsune
    Frontend Developer
    Самый простой и наилучший способ - это просто добавить нужные SVG иконки в кнопки. Можно было бы конечно и бекграундами, но судя по скрину, нужно изменение цвета иконок при hover эффекте, поэтому будет лучше использовать Single Inline SVG или использовать спрайт с иконками.

    <button value="product_card_frontpage" class="grid-view">
       <svg width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
          <path d="......" />
       </svg>
    </button>


    <button value="product_card_full_width" class="list-view">
       <svg width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
          <path d="......" />
       </svg>
    </button>


    Можно и через бекграунды вставлять и менять цвет иконок, например с помощью css filter, но это на мой взгляд какое-то странное решение. Есть ещё вариант с css масками, но нужно смотреть поддержку этого свойства.

    Разумеется есть и другие варианты кроме использования Inline SVG. Например использование дополнительных html тегов для создания "иконок" или реализация с помощью градиентов/теней/псевдоэлементов/etc. Однако нужно понимать, что есть "адекватные" и "правильные" решения задач, а есть "творческие" подходы, которые не всегда и не везде уместны.

    И если реализовывать иконки с помощью CSS, то можно обойтись по одному span тегу + два псевдоэлемента на каждую иконку:

    Иконки на CSS

    <span class="icon-grid"></span>

    * {
         box-sizing: border-box;
    }
    
    .icon-grid {
         position: relative;
         display: block;
         transform: scale(5);
         height: 10px;
         width: 10px;
    }
    
    .icon-grid::after,
    .icon-grid::before {
         content: "";
         display: block;
         position: absolute;
         width: 10px;
         height: 4px;
         border-right: 4px solid red;
         border-left: 4px solid red;
         top: 0;
         left: 0;
    }
    
    .icon-grid::before {
         top: 6px;
    }


    <span class="icon-list"></span>

    * {
         box-sizing: border-box;
    }
    
    .icon-list {
         transform: scale(5);
         position: relative;
    }
    
    .icon-list,
    .icon-list::after,
    .icon-list::before {
         display: block;
         width: 20px;
         height: 2px;
         border-radius: 3px;
         background: #3f51b5;
    }
    .icon-list::after,
    .icon-list::before {
         content: "";
         position: absolute;
         top: -6px;
    }
    .icon-list::after {
         top: 6px;
    }



    Основной параметр размера иконок зависит от значения scale(<length>) в свойстве transform. Можно конечно сделать иконки и по другому(возможно даже лучше), но как пример сгодится.
    Ответ написан
    Комментировать
  • Как прикрепить меню навигации кверху при скролле?

    mizutsune
    @mizutsune
    Frontend Developer
    Переместить навигацию из элемента с классом hero в общий контейнер. Сейчас навигация находится в блоке hero и не сможет выйти за его пределы при использовании position: sticky, так как не является прямым дочерним элементом блока, внутри которого и нужна липкая навигация. Рекомендую почитать как на самом деле работает position: sticky.

    Ну и вообще, зачем у элемента .container - стоит max-height: 50px? Думаю что надо бы убрать это ограничение.
    Ответ написан
  • Как с помощью flex сделать как на картинке?

    mizutsune
    @mizutsune
    Frontend Developer
    1. Первые два изображения - это независимые блоки и поэтому вставляем их в контейнер без оборачивания в группу.
    2. Оставшиеся два изображения - которые находятся в вертикальной колонне, оборачиваем в группу чтобы в дальнейшем было проще изменять стили и раскладку, например при адаптиве.

    Ответ написан
    Комментировать
  • Как можно изменить цвет изображения css?

    mizutsune
    @mizutsune
    Frontend Developer
    На сайте пользователь может выбрать для своих записей разные иконки из базы, все иконки черно-белые и в формате png.


    При таком раскладе дел, можете поиграть со следующими свойствами: mix-blend-mode, background-blend-mode, filter, но с таким набором далеко не уедешь, учитывая что нужна чётная и удобная возможность менять цвет иконок(изображений). Всё усложняется тем что речь идёт об обычных пользователях, которым нужен удобный UI, а ещё тем что используемые иконки являются растровой графикой.

    CSS хотя и обладает богатым набором функций, хаков, возможностей, но есть вещи которые невозможно сделать одним только CSS и смена цвета изображений есть в списке этих вещей. Нет, ну в той или иной степени можно конечно создать фильтры, всякие наложения, смешивание цветов, играть градиентами и что-то там крутить до посинения, надеясь что всё же выйдет, но это работает не всегда или выдаёт совсем не тот результат. Скажу проще: Не стоит заниматься забиванием гвоздей - микроскопом.

    Пробовал иконки svg использовать со свойством fill, но один фиг не получалось сменить цвет, тк я ссылку на изображения вставляю.


    Допустим у вас одноцветные иконки в формате SVG, тогда вместо добавления ссылки на иконку в теге img, вставляйте иконку как SVG в HTML разметку и проблем со сменой заливки не будет. Это будет наиболее выгодный и безболезненный способ решить данную задачу.

    Однако если пойти другим путем и добавить к CSS, немного JS, то вот тогда можно сделать что-нибудь более менее удобное. Есть инструменты, способные реализовать "изменение цвета", как например этот генератор css фильтров, но даже если подобные тулзы и решают те или иные задачи, всё же есть шанс что однажды это либо перестанет работать или что-то пойдёт не так.
    Ответ написан
    Комментировать
  • Как сделать, чтобы при выборе файлов(например, картинок) они отображались на сайте?

    mizutsune
    @mizutsune
    Frontend Developer
    Если нужно в стиле превью отобразить выбранное изображение до отправки на сервер, тогда можно сделать например вот так:

    <input type="file" id="file" value="Change Image">
    <img class="picture" alt="demo">


    const picture = document.querySelector(".picture");
    const inputFile = document.querySelector("#file");
    
    inputFile.addEventListener("change", ({ target: t }) => {
         const [file] = t.files;
    
         if (!file) return;
    
         if (!file.size) return;
    
         const reader = new FileReader();
    
         reader.onload = () => {
              picture.src = reader.result;
         };
    
         reader.readAsDataURL(file);
    });


    Пример достаточно простой, без всяких дополнительных проверок(которые можно обойти), но думаю для начала пойдет.
    Ответ написан
    1 комментарий
  • Как ограничить видимость переменных между html страницами?

    mizutsune
    @mizutsune
    Frontend Developer
    Допустим нужно проделать какие-то манипуляции с DOM. Например, сделать вывод массива в определенный элемент на определенной странице. В таком случае, можно использовать нечто такое:

    function myAwesomeFunction() {
      if(!document.querySelector("#target")) return;
    
      //some code 
    }


    То есть нужно вложить код в функцию, внутри которой проверять есть ли нужный элемент на странице и если он есть, продолжаем выполнение, а если элемента нет на странице выходим из функции. Ну вообще не обязательно ставить условие внутри функции, можно вызов основной функции переместить в условие. То есть:

    if(document.querySelector("#target")) {
       myAwesomeFunction(); 
    }


    Альтернативный вариант.

    Можно использовать window.location для решения подобных задач, но у данного способа есть свои подводные камни.
    Ответ написан
  • Как корректно соединить текст и картинку?

    mizutsune
    @mizutsune
    Frontend Developer
    Один из вариантов - это использовать псевдоэлементы для двойного бекграунда блока.

    Вариант - #1

    .element {
            width: 100%;
            height: 400px;
            position: relative;
    }
    
    .element:before {
            content: "";
            width: 30%;
            height: 100%;
            background: #673ab7;
            position: absolute;
            top: 0;
            left: 0;
    }
    
    .element:after {
            content: "";
            width: 70%;
            height: 100%;
            background: url(image.jpg);
            position: absolute;
            top: 0;
            right: 0;
    }




    Блок с текстом уже при желании можно отцентрировать кучей различных способов.

    Если рассматривать другие варианты, то к примеру можно взять свойство background-image и применить с его помощью два фона к блоку, путём указания двух разных бекграундов, плюс минус потребуется настройка положения, размера, etc. Допустим первый бекграунд сделаем градиентом, а для второго уже можно использовать изображение.

    Вариант - #2
    .element {
            width: 100%;
            height: 400px;
            background: linear-gradient(to right, #e91e63 100%, transparent), url(image.jpg);
            background-size: 30% 100%, 70% 100%;
            background-position: left center, right center;
            background-repeat: no-repeat, no-repeat;
    }


    Есть конечно ещё множество других вариантов, но некоторые из них не стоит рассматривать, потому что данная задача решается одним только CSS, без добавления лишних сущностей в разметку.
    Ответ написан
    2 комментария
  • Как реализовать такой эффект?

    mizutsune
    @mizutsune
    Frontend Developer
    Это называется Before/After Image Slider Comparison или просто Image Comparison Slider.

    Несколько плагинов на JQuery.
    Несколько разных вариантов.
    Ещё можно на Codepen поискать. Есть несколько вариантов.

    Или если хорошо поискать и на других сайтах, то может найдутся вполне неплохие варианты.
    Ответ написан
    Комментировать
  • Как сделать выпуклую форму для контейнера с видео?

    mizutsune
    @mizutsune
    Frontend Developer
    Можно сделать например через clip-path + SVG.

    Если кратко объяснить процесс, то это делается примерно так:

    Рисуете в графическом редакторе фигуру, которая будет использоваться в качестве контейнера для видео. Далее копируем код SVG и воспользовавшись данным инструментом, получаем координаты для реализации clip-path.

    Финальная реализация будет выглядеть примерно так:

    <svg class="svg">
      <clipPath id="my-clip-path" clipPathUnits="objectBoundingBox">
        <path d="M0.5,0 L1,1 H0"></path>
      </clipPath>
    </svg>
    
    <div class="clipped">
      <video src="./assets/video.mp4"></video>
    </div>


    .svg {
         position: absolute;
         width: 0;
         height: 0;
    }
    
    .clipped {
         width: 100%;
         max-width: 500px;
         height: 350px;
         -webkit-clip-path: url(#my-clip-path);
         clip-path: url(#my-clip-path);
    }
    
    video {
            width: 100%;
            height: 100%;
            object-fit: cover;
    }
    Ответ написан
    3 комментария
  • Как нормализовать высоту элемента во флексбоксе?

    mizutsune
    @mizutsune
    Frontend Developer
    Так как в вопросе нет ссылки на песочницу, остаётся только догадываться что там, но судя по скринам скорее всего структура блока с карточками такая:

    <parent>
       <card></card>
       <card></card>
       <card></card>
       <card></card>
       <button></button>
    </parent>


    И если у родительского блока установлено display: flex и без изменений свойство align-items, тогда получается такая вот картина:

    6307d351d66e6315633533.png

    Это потому что в свойстве align-items по дефолту стоит значение stretch. Можете погуглить об этом и найдете полезную информацию, но во всяком случае вот:

    Флексы растягиваются таким образом, чтобы занять всё доступное пространство контейнера.


    Если нужно по-быстрому решить задачу, тогда просто добавьте для родительского контейнера:

    align-items: center;

    Если решать задачу иначе то лучше вынести кнопку за пределы блока с карточками и сверстать нормально, так как скорее всего это слайдер, а в слайдерах обычно навигацию не кладут вместе со слайдами. Это как-то неправильно.
    Ответ написан
    1 комментарий
  • Просмотрите простой код, почему Sublime и другие редакторы жалуются?

    mizutsune
    @mizutsune
    Frontend Developer
    Не закрыт тег <article> с классом info и тег <div> с классом services.
    Ответ написан
    Комментировать
  • Как наложить картинку на текст?

    mizutsune
    @mizutsune
    Frontend Developer
    1. Оборачиваем нужное слово, например в тег <span сlass="element">Hello</span> и для удобства добавляем класс, по которому будет стилизовать элемент.
    2. Так как тег span является строчным элементом, добавим ему свойство display со значением inline-flex или inline-block. Это нужно для получения корректных значений, при вычислении высоты и ширины элемента.
    3. Задаём нужный font-size, font-family, line-height(можно добавить ещё font-weight, но это по желанию) и узнаем ширину и высоту элемента. При изменении размера шрифта - эти данные конечно будут меняться, но это наверняка не будет особой проблемой.
    4. Задаём изображению флага - размеры высоты и ширины блока с текстом. Картинку можно даже сделать немного больше.


    Теперь переходим к стилям CSS:

    .element {
            background-image: url(./image.jpg);
            background-repeat: no-repeat;
            background-size: cover;
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
            font-size: 50px;
            line-height: 50px;
            display: inline-flex;
            font-family: "Roboto", sans-serif;
    }


    Через группу свойств:

    background-image: url(./picture.jpg);
    background-repeat: no-repeat;
    background-size: cover;


    Задаём фоновое изображение для элемента(для текста) и настраиваем дополнительные параметры отображения бекграунда. Если вдруг нужно отцентрировать изображение по вертикали или горизонтали, используем предназначенные для этого свойства: background-position-x или background-position-y.

    Основную работу выполняют следующие свойства: -webkit-text-fill-color и background-clip, которые создают эффект прозрачности, что позволяет использовать бекграунд элемента в качестве фона для текста. Однако можно обойтись и без свойства -webkit-text-fill-color, заменив его следующей строчкой color: transparent.

    Однако, смотрим поддержку данных свойств:

    -webkit-text-fill-color 
    -webkit-background-clip


    И если текущее состояние не устраивает, используем SVG с текстом и заливкой в виде картинки.
    Ответ написан
    Комментировать
  • Как вставить html файл в другой html файл с помощью webpack или другого сборщика?

    mizutsune
    @mizutsune
    Frontend Developer
    Можете попробовать как вариант posthtml-include. Подключаете как модуль в своём сборщике, если есть поддержка и используете.
    Ответ написан
    Комментировать
  • Почему transition не срабатывает при скрытии элемента?

    mizutsune
    @mizutsune
    Frontend Developer
    Для начала несколько рекомендаций:

    1. Следует отказаться от стилизации элементов по ID селектору, потому что это считается плохой практикой.
    2. Для простой функции переключения класса у элемента, не нужно столько кода.

    Почему transition не срабатывает при скрытии элемента?


    - transition: opacity 0.3s;
    + transition: opacity 0.3s, visibility 0.3s;


    При комбинированном использовании свойств opacity и visibility, следует указывать оба свойства в transition, желательно с одинаковым временем перехода от одного состояния к другому.

    CSS и JS можно сократить и привести к нормальному виду.


    CSS:

    .block {
        width: 250px;
        height: 250px;
        background: #eee;
        opacity: 0;
        visibility: hidden;
        transition: opacity 0.3s, visibility 0.3s;
      }
    
      .block-active {
        opacity: 1;
        visibility: visible;
      }


    JS:

    function show() {
        const element = document.getElementById("block");
        element.classList.toggle("block-active");
      }


    Или:

    function show() {
         const element = document.getElementById("block");
    
         switch (Boolean(element.classList.contains("block-active"))) {
              case false:
                   return element.classList.add("block-active");
              case true:
                   return element.classList.remove("block-active");
         }
    }
    Ответ написан
    5 комментариев
  • Как скрыть все блоки при выборе одного?

    mizutsune
    @mizutsune
    Frontend Developer
    .tabs-panels__panel {
         display: none;
    }
    
    .tabs-panels__panel-active {
         display: block;
    }


    <div id="tabs" class="tabs">
        <div class="tabs__nav">
            <button class="tabs-nav__button tabs-nav__button-active" data-tabs-target="tabs-panel-1">
                Section 1
            </button>
            <button class="tabs-nav__button" data-tabs-target="tabs-panel-2">
                Section 2
            </button>
        </div>
        <div class="tabs__panels">
            <div id="tabs-panel-1" class="tabs-panels__panel">
                <div class="tabs-panels-panel__container">
                    Content Of Section 1
                </div>
            </div>
            <div id="tabs-panel-2" class="tabs-panels__panel tabs-panels__panel-active">
                <div class="tabs-panels-panel__container">
                    Content Of Section 2
                </div>
            </div>
        </div>
    </div>


    const container = document.querySelector("#tabs");
    
    container.addEventListener("click", ({ target: t }) => {
         if (t.classList.contains("tabs-nav__button")) {
              const tabsTriggerButton = container.querySelectorAll(".tabs-nav__button");
              const tabsContentPanels = container.querySelectorAll(".tabs-panels__panel");
    
              const currentPanelID = t.dataset.tabsTarget;
    
              if (!currentPanelID) return;
    
              tabsTriggerButton.forEach(v => v.classList.remove("tabs-nav__button-active"));
              t.classList.add("tabs-nav__button-active");
    
              tabsContentPanels.forEach(v => {
                   v.id === currentPanelID ?
                        v.classList.add("tabs-panels__panel-active") :
                        v.classList.remove("tabs-panels__panel-active");
              });
         }
    });
    Ответ написан
    Комментировать
  • Как при наведении на картинку сделать под ней фон в виде окружности?

    mizutsune
    @mizutsune
    Frontend Developer
    Вариант первый:



    В данном примере при наведении на блок, меняется цвет фона у псевдоэлемента, который находится на заднем фоне изображения. Псевдоэлемент можно заменить например SVG фигурой, чтобы добиться похожего визуального эффекта как на сайте Юла.

    Вариант второй:



    В данном примере при наведении на блок, меняется цвет заливки у SVG вектора.
    Ответ написан
    6 комментариев
  • Насколько часто в js библиотеках попадаются бэкдоры?

    mizutsune
    @mizutsune
    Frontend Developer
    Как от этого защититься?


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

    Поэтому намного выгоднее и удобнее взять какую-нибудь популярную библиотеку прочитать документацию по ней и начать использовать в своём проекте. Это конечно всё хорошо, но как защититься если всё таки используешь сторонние библиотеки?

    1. Хранить используемые библиотеки у себя.
    2. Не обновляться без нужды, а если и обновляться, то проводить анализ обновленного кода.
    3. Нужно уметь читать код библиотек, полностью понимать что там написано, что делает каждая функция.
    4. Подключать библиотеки в проекте без использования CDN версий и прочего. Желательно со своего сайта, чтобы строго контролировать используемую версию библиотеки.
    5. Желательно не использовать библиотеки, имеющие кучу внешних зависимостей.
    6. По возможности использовать популярные библиотеки, но не доверять им на 100%. Тот факт что библиотека популярна и имеет сколько-то тысяч звездочек на Github, не гарантирует того, что однажды там не появится какой-нибудь гнилой код, выполняющий не очень хорошие действия. Помним про пункты: 1, 2, 3, 4, 5.

    Конечно выполнение этих пунктов тоже требует ресурсов, но по крайней мере увеличивает шанс защититься от всяких нехороших сценариев.
    Ответ написан
    Комментировать