Ответы пользователя по тегу CSS
  • Реально ли сделать лепестковую диаграмму с градиентом?

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    В CSS и SVG есть какие-то градиенты и фильтры, из которых можно что-то такое плюс-минус собрать. Ну и вариации clip-path или масок, чтобы обрезать. Но. Логика формирования градиентов там своя, и она не всегда хорошо подходит под идею, как оно должно выглядеть. Иногда все мешается очень грязно, или какие-то полосы появляются. Не идеально там все. Много костылей нужно подставлять. Если будет нужна какая-то совсем особая интерполяция - то от количества костылей и подпорок тошно станет. Один раз подогнать можно, но с автоматизацией могут возникнуть сложности. А задача построения диаграмм почти всегда требует автоматизации. Это может быть не совсем очевидно с самого начала, но усугубляется там все очень быстро. Так что может иметь смысл сразу брать canvas и делать свою логику под свои хотелки. Там мы нарисовать можем что угодно, мы уже не зависим от браузера и его представлений о градиентах. Это более сложное решение в своей основе, чем подбор градиентов в SVG, но более перспективное в плане его дальнейшего развития.

    Ответ написан
    1 комментарий
  • Тормоза браузера из-за стилей, решение?

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    Для начала для нас важно осознать, что у разных фильтров разная вычислительная сложность. Они не все "плохие". Алгоритмы для brightness, grayscale, hue-rotate и других манипуляций с цветом выполняются за O(1) для каждого пикселя. Т.е. нагрузка на железо растет линейно в зависимости от площади элемента на экране. Это не так страшно. А вот фильтры размытия, blur или drop-shadow, имеют сложность где-то в районе O(R^2). Там есть разные варианты оптимизаций, но в среднем мы говорим именно о квадратичной зависимости от радиуса размытия. И это для каждого пикселя. Именно отсюда мы имеем сильные тормоза при попытке что-то большое размыть на пол экрана. Дохлые видеокарты телефонов и ноутбуков не вывозят. Браузеры не умеют такие вещи переиспользовать, так что это переразмытие происходит снова и снова, и мы имеем что имеем.

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

    В контексте верстки тут есть полтора варианта, что можно сделать. Можно рассчитывать такие вычислительно-сложные штуки еще при разработке и загружать в страницу сразу в виде картинок или видео. Это не идеальный вариант, пропорции получаются фиксированные, но иногда подходит. Есть вариант рассчитывать такие штуки в фоне на WebGL. Т.е. мы грузим интерфейс, смотрим какого там все размера получается, и один раз в фоновом режиме генерируем картинки нужного размера и потом плавно показываем. Такой вариант частенько встречается в рекламно-конкурсных проектах, когда за прелоадером в начале скрывается в том числе и такая генеративная история. Тут мы получаем гибкость в плане размеров и хорошую производительность сайта в целом, потому что все операции проходят только один раз, а дальше у нас все переиспользуется в виде обычных картинок. Каких-то принципиально других вариантов у нас пока нет. Только дизайн менять.
    Ответ написан
    3 комментария
  • Как использовать в clip-path: path() проценты (ну и calc)?

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    Весь затык у нас тут в том, что CSS не позволяет в рамках path жонглировать единицами измерения. Почему? Люди задавались этим вопросом с самого момента появления path в CSS. Но этот функционал всегда был в SVG. Так что можно добавить маску в SVG (тут у нас размер элемента, условные 100% на 100%, считается за 1 на 1):

    <svg width='0' height='0'>
        <defs>
            <clipPath id='example' clipPathUnits='objectBoundingBox'>
                <path d="M 0 0 a 1 1 0 0 0 1 1 h -1 v -1z"/>
            </clipPath>
        </defs>
    </svg>

    И тогда в CSS уже будет все просто:

    .example {
        clip-path: url(#example);
    }

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

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    Где-то в светлом будущем у нас будет CSS Painting API, с помощью которого можно будет рисовать какие угодно бордеры. А пока можно его сымитировать обычным канвасом (правда придется отступы подгонять под особенности шрифта, но это уже детали, один раз можно сделать):



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

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    порядок действий

    1. Сделать 12 элементов.
    2. Расположить элементы по кругу. Тут абсолютное позиционирование В текущих реалиях вечнозеленых браузеров мы можем использовать нативные функции sin() и cos(), чтобы рассчитать, где какие из них должны быть расположены на окружности не покидая мир CSS. Тут никакой магии, геометрия за 7 класс школы.
    3. Естественным образом в расчетах координат появится угол, который можно менять, тем самым поворачивая всю эту карусель. Его можно уже из скриптов менять по той логике, которая нужна для взаимодействия с пользователем.
    4. Обрезать все штатным clip-path.




    Это если говорить про HTML+CSS подход. Он легко делается, но он не идеальный внутри. Есть две проблемы, которые не решатся заменой свойств на другие. Первая - это дергающиеся элементы. В каких-то браузерах это будет проявляться меньше, в каких-то больше. Как ни крути положения элементов округляются до целого количества пикселей по неведомой для нас логике и в движении будут заметны сдвиги в 1px туда-сюда. И производительность - это вторая потенциальная проблема. Двигать много элементов одновременно, особенно если они большие - не всегда хорошо. Не факт, что это будет проблемой в вашем случае, но в теории может стать с учетом всего остального, что будет на странице. Более производительным в теории вариантом будет нарисовать все это на канвасе. Там же можно будет взять под контроль все округления. По крайней мере до какой-то степени. Это следующий шаг, куда можно все это развивать. Логика будет той же самой, но уже на других технологиях. Вероятно вам будет проще начать с варианта на CSS.
    Ответ написан
    5 комментариев
  • Как создать такую фигуру?

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    Я думал через clip-path но там нет такой плавности... даже чат джипити не понимает...

    Если уж говорить про clip-path, то там есть clip-source, с помощью которого мы можем поиспользовать clipPath из мира SVG, а в рамках SVG уже можно нарисовать себе любую форму. В разделе синтаксиса и на MDN, и в стандарте, это буквально первый предлагаемый вариант использования clip-path. Не доверяйте вашей чатгопоте. Читайте документацию самостоятельно. Там много интересного.
    Ответ написан
    4 комментария
  • Как задать универсальный @keyframes для нескольких разных блоков, без скриптов?

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    С точки зрения производительности в CSS анимациях почти всегда имеет смысл сразу смотреть на свойство transform, а не на width или height. А в терминах трансформаций у нас для изменения размеров используются вариации функции scale():

    50% {
        transform: scaleX(0.9) scaleY(1.1);
    }

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

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    как решить?

    .img img {
        display: block;
    }

    Всё это нужно для затемнения фотографии

    Можно рассмотреть еще вариант без отдельного элемента с фоном:
    img {
        filter: brightness(0.6);
    }
    Ответ написан
    Комментировать
  • Как сделать плавную анимацию при смене значений через js?

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    Вероятно вам нужен обычный transition, он будет срабатывать каждый раз, когда значения будут меняться:

    .items {
        .single-chart {
            .circular-chart {
                .circle {
                    /* animation: progress 1s ease-out forwards; */
                    transition: stroke-dasharray 1s ease-out;
                }
            }
        }
    }
    Ответ написан
    1 комментарий
  • Как сделать чтобы у меня 3д анимация вращения не плавала в дополнительной плоскости?

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    У нас три координаты - XYZ. Для CSS все элементы на странице - плоские, у них нет толщины, и их размеры по оси Z нулевые. Поэтому CSS за нас не угадает, куда должен смещаться transform-origin по оси Z для кирпичика, который существует исключительно в нашем воображении. Вы смещаете грани кирпичика в отрицательные значения по оси Z, но точка transform-origin, через которую проходит ось вращения, остается в плоскости Z = 0.

    Получается, что вам нужно как-то вручную совместить ось вращения и центр кирпичика. Тут два пути - либо сместить точку transform-origin на пол кирпичика вглубь по Z:

    .cube {
        transform-origin: 50% 50% -25px;
    }

    Так ось вращения будет проходить через его текущий центр. Либо сместить грани кирпичика, чтобы он изначально собирался не "весь вглубь экрана", а "половина вглубь, половина к нам". Его центр сразу будет в плоскости Z = 0, где по умолчанию находится transform origin, и не нужно будет ничего дополнительно двигать.
    Ответ написан
    1 комментарий
  • Как максимально просто создать фигуру как на изображении для последующей анимации?

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    Вариант с градиентами - сложный для анимирования. Рисование линий со stroke-dasharray - это стандартный выбор. Но dash array может быть длинным, им можно описать самые разные последовательности линий и пробелов, так что если вам не нужны разные цвета, то можно сделать одну линию:

    Ответ написан
    5 комментариев
  • Как через css сделать такие блики на bk сайта?

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    Формально можно взять фильтр blur с большим радиусом и размыть абсолютно расположенные на фоне элементы. В SVG есть аналогичный фильтр. Но лучше так не делать. Для таких размытий используется вычислительно сложный алгоритм и можно существенно увеличить нагрузку на устройства пользователей на ровном месте. Это просто сложно рендерить в реальном времени.

    Производительнее будет это размытое нечто картинкой вставить. Тоже не идеально, грузиться будет дольше, но выбирая между тормозами всего или слегка более долгой загрузкой ни на что не влияющей кляксы на фоне - в 99% случаев стоит выбрать второе.

    Есть, конечно, еще более развитый вариант - взять canvas, отрендерить эту штуку на нем один раз в фоновом режиме, а потом использовать результат как картинку. Так оно не будет требовать загрузки картинки по сети, и мы не будем грузить устройства пользователей постоянно. Но это уже другой вопрос, про другие инструменты.

    P.S.: Добавлю еще такой момент, что при использовании картинки может возникнуть такая мысль, что в CSS есть еще градиенты - и это ведь тоже как картинки, может быть их использовать? Но собрать такое из градиентов гораздо сложнее, чем кажется. Сложение полупрозрачных градиентов - это не тот же алгоритм, что размытие. При взаимном наложении клякс друг на друга результат будет отличаться. Чтобы иметь такое же красивое размытие - придется иметь много градиентов, что сведет на нет саму идею снижения нагрузки на железо через них.
    Ответ написан
    Комментировать
  • Как сделать фиксированную высоту сайта?

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    В таких вопросах хорошо показывать код, а не скриншоты, но в общем случае если нам нужно вписать что-то очень большое на фон и сделать так, чтобы оно вылезало за края экрана, но не вызывало скролла нигде, то этой большой штуке делается контейнер с overflow: hidden. Внутри контейнера она может вылезать куда угодно, это уже не будет влиять на размер страницы в целом.
    Ответ написан
    3 комментария
  • Как распределить элементы на адаптивной, векторной кривой?

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    Хорошего нативного и кроссбраузерного решения у нас пока нет. Но у path в SVG есть методы getTotalLength и getPointAtLength, а из них можно сообразить себе утилиту для расположения кружков вдоль кривой в удобных единицах измерения. Это не так здорово, как на CSS, но тем не менее:

    function putCircleOnPath(path, circle, percent) {
        const length = path.getTotalLength();
        const point = path.getPointAtLength(length * percent / 100);
    
        circle.setAttribute('cx', point.x);
        circle.setAttribute('cy', point.y);
    }


    Получится что-то такое:

    Ответ написан
    2 комментария
  • Какие могут быть подводные камни при верстке в REM c шрифтом HTML в VW?

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    Классическая реализация этого подхода предполагает, что есть CSS шлюз, ограничивающий минимальный/максимальный размер шрифта для минимального/максимального размера экрана, и логика дизайна явно завязана на размер шрифта. Как в мире, где люди печатают разные штуки на бумаге. Плюс альтернативные единицы измерения - vw, vmax, проценты - если нужно. Это помогает сохранить в верстке логику дизайна в явном виде. Используя искусственную логику 1rem = 10px, и rem не в значении "базовый размер шрифта", а просто как костыль для адаптивности, вы упрощаете изначальные подсчеты, но в верстке получается гора рандомных дробных значений, которые не пойми что обозначают. Тут нужно либо подгонять все под 10px сетку, что не всегда уместно, либо по мере усложнения интерфейса это все превратится в такую кашу, что врагу не пожелаешь. Собственно это возвращает нас к изначальной проблеме верстки в пикселях. Куча магических значений и никакой логики в коде. Это главный недостаток вашего способа приготовления rem.

    Вторая проблема, более общая - округление значений. При изменении размера экрана будут появляться дробные размеры всего. Они будут округляться до целого количества пикселей. При этом у нас есть много ситуаций, когда разные браузеры будут округлять по-разному, или просто не туда, куда мы ожидаем. Появляются разные артефакты. В модных сайтах, где в дизайне много негативного пространства, мы можем этого не заметить, но в тесных интерфейсах кроваво-энтерпрайзных приложений это быстро станет проблемой. Там пиксели = надежность и предсказуемость.
    Ответ написан
    2 комментария
  • Почему в normalize.css выдает две ошибки?

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    Вероятно вы используете либо встроенный в VSCode линтер для CSS, либо stylelint. С настройками по умолчанию они оба сообщают о наличии префиксов у CSS-свойств. В случае со встроенным линтером - у него есть настройка css.lint.vendorPrefix, смысл которой в том, что к свойству с префиксом нужно добавлять свойство без префикса, и если его нет, то это выглядит странно. В случае со stylelint - есть правило property-no-vendor-prefix. Там логика другая - в нормально выстроенном процессе сборки всю работу с префиксами на себя берет autoprefixer, соответственно само появление префиксов в коде выглядит как что-то лишнее. Если они добавляются автоматически, то писать их самому в обычных ситуациях вроде как не нужно.

    В normalize.css эти префиксы нужны, именно в том виде, в котором они там есть, чтобы подровнять стили между разными браузерами. В этом его задача. Так что предупреждения от обоих линтеров в данном случае не имеют практического смысла. Этот файл такой, какой есть, и мы не будем его трогать. Можно добавить этот файл в исключения, чтобы замечания по нему не мозолили глаза.
    Ответ написан
    Комментировать
  • Можно ли опустить первые 0% в linear-gradient?

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    Да, можно пропустить первое значение в 0%. Если почитать стандарт, то там прямым текстом написано, что эти значения, где расположить цвета на градиенте - не обязательные. Можно вообще все пропустить. Если они пропущены, то расположение цветов в градиенте восстанавливается по четкому алгоритму.

    В целом ответы на подобные вопросы о тонкостях интерпретации CSS имеет смысл искать в стандартах.
    Ответ написан
    2 комментария
  • Почему bottom:0 не работает?

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    Использование position: relative совместно со свойствами top, right, bottom или left смещает элемент относительно его естественного расположения на странице. Поэтому все работает так, как и должно. Ваш main естественным образом расположен в верхней части родителя и смещен на 0px. Ну то есть никуда не смещен.

    Вероятно вы получите нужное вам поведение если будете использовать position: absolute.
    Ответ написан
    Комментировать
  • Как быть с анимацией в Firefox?

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    Это известный баг у масок в Firefox. Проявляется и с mask, и с clip-path. Суть проблемы в том, что маска применяется уже после трансформации, после поворота, и при расчете ее границ возникают сложности с округлениями до целого количества пикселей. Браузер не знает, в какую сторону лучше округлять. В результате для каких-то пикселей на границах маска применяется не так, как мы ожидаем, ее граница как бы смещается на 1px. Самый простой и безболезненный способ избавиться от проблемы в вашем конкретном случае - избавиться от масок. Нет маски - нет проблемы. Исходя из вашей задачи ничто не мешает использовать svg-иконки сразу, как есть, в виде обычных картинок, без нагораживания всей этой истории с белым квадратом, который потом обрезается.
    Ответ написан
    4 комментария
  • Шрифты по разному ведут себя в консоли и на реальном устройстве, почему?

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    Прежде, чем ломать голову над тем, проблема это в эмуляторе в Chrome или нет, стоит проверить, а воспроизводится ли проблема в других браузерах или даже в самом Chrome, если само его окно поменять в размерах. И да, воспроизводится. Текст обрезается то сверху, то снизу. Это не проблема эмулятора. Нужно смотреть логику в коде, кто смещает текст.

    А в коде на некоторых разрешениях экрана вы тексту добавляете padding сверху. А на некоторых - не добавляете. Вот он и ездит вверх-вниз внутри контейнера с overflow: hidden и обрезается. А звездочкам с абсолютным позиционированием на padding все равно, они не ездят. Это то, что нужно исправить.

    По поводу эмулятора в Chrome: он всегда имел сложности с единицами vh/vw. С годами его поведение менялось, но в целом все его тараканы в голове всегда можно было прибить с помощью мета тега для вьюпорта. Вы его используете только чтобы задать изначальное масштабирование, но там еще есть возможности для ограничения - minimum-scale, maximum-scale и грубое user-scalable. С ними нужно быть осторожнее в продакшене, чтобы не ломать людям доступность, но в каких-то замороченых случаях отладки можно применить, чтобы забрать у эмулятора возможность что-то масштабировать и странно трактовать единицы измерения. Но, еще раз, практика эта странная, ваше верстка должна работать без таких ограничений.
    Ответ написан
    Комментировать