9

Как создать такую окружность, как на рисунке?
На рисунке есть ещё задний фон. Можно нарисовать круг с градиентом, и с помощью :before закрыть внутреннюю часть по периметру, но как тогда показать задний фон через :before?
введите сюда описание изображения

word
  • 2,810
  • 4
  • 34
  • 69
  • но как тогда показать задний фон через :before? - так же, как и везде: background: url(...) – Алексей Шиманский Jun 22 '17 at 07:24
  • @Алексей Шиманский, это получается нужно скриптом вычислять положение текущей окружности относительно заднего фона, чтобы внутри окружности в before показать именно ту часть, где находится окружность над фоном – word Jun 22 '17 at 07:37
  • получается что так. это самый вариант в лоб, тксзть – Алексей Шиманский Jun 22 '17 at 07:38
  • @Алексей Шиманский, ну и как это реализовать? а разве с помощью svg нельзя это сделать? – word Jun 22 '17 at 07:40

5 Answers5

8

Используя пример ответа @Максим Ленский, сгенерированный генератором, можно сделать читабельный и понятный вариант:

<svg viewBox="0 0 220 220" width="220" height="220">
    <defs>
        <linearGradient id="gradient">
            <stop offset="0" style="stop-color:#0070d8" />
            <stop offset="0.5" style="stop-color:#2cdbf1" />
            <stop offset="1" style="stop-color:#83eb8a" />
        </linearGradient>
    </defs>
    <ellipse ry="100" rx="100" cy="110" cx="110" style="fill:none;stroke:url(#gradient);stroke-width:6;" />
</svg>
  • нету заголовка - многие браузеры не видят svg без заголовка –  Jun 22 '17 at 07:59
  • @Максим Ленский, а подскажите пожалуйста, этот атрибут stroke:url(#linearGradient853) можно указывать свободно? т.е. он постоянен? не меняется? – word Jun 22 '17 at 08:05
  • @МаксимЛенский в инлайновом видят, а в примере он и есть. – Artem Gorlachev Jun 22 '17 at 08:06
  • @Максим Ленский, если не затруднит вас, подскажите, а как сделать кроссбраузерный вариант с тем варианом градиента, как у Artem Gorlachev ? – word Jun 22 '17 at 08:08
  • нету заголовков у вас , хотя мне без разницы но просто потом появится очередной вопрос о том почему не работает svg к примеру в мозилке –  Jun 22 '17 at 08:09
  • @word просто заголовки вписать и тогда вид будет совсем не читабельный –  Jun 22 '17 at 08:09
  • @МаксимЛенский, в инлайновом svg заголовки не нужны. И будут работать везде. Они нужны только когда выносите его в svg файл. – Artem Gorlachev Jun 22 '17 at 08:11
  • @ArtemGorlachev не знал , спс за поянения –  Jun 22 '17 at 08:12
  • @ArtemGorlachev А можете сделать вариант, чтобы можно было бы эту разметку указать как background: url(data:image/svg+xml,и тут svg код);? Причём чтобы этот svg подстраивался под div определённого ширины и высоты. – Vadim Ovchinnikov Jun 22 '17 at 08:34
  • @VadimOvchinnikov, либо ставите кодировку utf8 data:image/svg+xml;utf8,<svg ...> ... </svg>, либо переводите в base64 data:image/svg+xml;base64, ...., но по кроссбраузерности тут подсказать не могу – Artem Gorlachev Jun 22 '17 at 08:39
  • @ArtemGorlachev, подскажите, как сделать радиус 70 пикселей? jsfiddle.net/bb8qa5on – word Jun 22 '17 at 08:41
  • http://jsfiddle.net/bb8qa5on/1/ учтите что у вас рамка за окружностью находится, поэтому добавил ширины и высоты самому блоку – Artem Gorlachev Jun 22 '17 at 08:45
  • @ArtemGorlachev, радиус стал ещё меньше. Нужно чтобы ширина и высота окружности была 140 пикселей – word Jun 22 '17 at 08:59
  • @ArtemGorlachev, подскажите пожалуйста, как увеличить радиус? – word Jun 22 '17 at 09:18
  • @word, ну уже методом тыка можно же подогнать. всего 4 цифры. чтобы ширина окружности была 140, радиус должен быть 70, как я и скинул – Artem Gorlachev Jun 22 '17 at 09:21
6

Как вариант можно использовать mask-image:

.box {
  height: 200px;
  width: 200px;
  border-radius: 50%;
  background-image: linear-gradient(to right, #0B73D3, #37DAEF, #86E98E);
  -webkit-mask-image: radial-gradient(circle at center, transparent 67%, white 68%);
  mask-image: radial-gradient(circle at center, transparent 67%, white 68%);
}

body { background-image: url(https://www.w3schools.com/css/img_fjords.jpg); background-size: cover; }

<div class="box"></div>

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

Darth
  • 13,217
MihailPw
  • 6,384
  • да даже в последнем хроме рваные линии – Artem Gorlachev Jun 22 '17 at 08:14
  • @ArtemGorlachev на 58-59-ых все идеально. FF 53 - тоже – MihailPw Jun 22 '17 at 08:17
  • @AGS17 я четко вижу внизу на внутренней окружности рваную линию. может у меня слишком перфекционистский взгляд. а может вы на ретине_ – Artem Gorlachev Jun 22 '17 at 08:21
  • @ArtemGorlachev как это вижу я https://www.screencast.com/t/iQG60v2RbiH .Приложите может скрин как у вас... – MihailPw Jun 22 '17 at 08:22
  • https://jsfiddle.net/kv37k9ba/ – Artem Gorlachev Jun 22 '17 at 08:23
  • https://yadi.sk/i/S0_MXK4L3KMFYq справа мой свг, слева ваш – Artem Gorlachev Jun 22 '17 at 08:24
  • @ArtemGorlachev выглядит растянутым, не знаю что за проблемы у вас с отображением. – MihailPw Jun 22 '17 at 08:27
  • @Artem Gorlachev, как сделать радиус 70 пикселей? – word Jun 22 '17 at 08:31
  • @word, пишите в комментарии к тому ответу, про который спрашиваете. – Artem Gorlachev Jun 22 '17 at 08:40
  • @AGS17, разобрался с вашим вариантом, у вас сглаживание идет 1% градиентом, если убрать его то сглаживание пропадет напрочь. Думаю у нас разница в видео или os. Тема удобная, можно делать очень интересные вещи, но в этом варианте не стоит;) – Artem Gorlachev Jun 22 '17 at 08:43
  • @ArtemGorlachev у меня без сглаживания выглядит резким – MihailPw Jun 22 '17 at 09:04
  • @AGS17 Я бы не сказал, что поддержка браузеров остваляет желать лучшего. Не поддерживается только IE и Edge. – Vadim Ovchinnikov Jun 23 '17 at 10:10
2

Как обычно такими вещами занимается svg , рекомендую почитать о этой прелести, есть отличный сайт администратор которого присусвует на ruSO

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
  id="svg8" version="1.1" viewBox="0 0 297 210">
  <defs
     id="defs2">
    <linearGradient
       id="linearGradient853-5-9-6">
      <stop
         id="stop849"
         offset="0"
         style="stop-color:#489c37;stop-opacity:1" />
      <stop
         id="stop851"
         offset="1"
         style="stop-color:#2a3eff;stop-opacity:0.733" />
    </linearGradient>
    <linearGradient
       gradientUnits="userSpaceOnUse"
       y2="194.94643"
       x2="171.57741"
       y1="193.43452"
       x1="136.8512"
       id="linearGradient885"
       xlink:href="#linearGradient853-5-9-6" />
  </defs>
  <g
     transform="translate(0,-87)"
     id="layer1">
    <ellipse
       ry="78.619049"
       rx="88.824409"
       cy="195.70238"
       cx="151.56847"
       id="path10"
       style="fill:none;fill-opacity:1;stroke:url(#linearGradient885);stroke-width:6;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill" />
  </g>
</svg>
  • благодарю, а подскажите, как можно подобрать градиент для окружности, потому-что на вышеприведённом рисунке градиент немного отличается, нужно точно такой или хотя-бы примерный – word Jun 22 '17 at 07:41
  • Поправил пример –  Jun 22 '17 at 07:52
1

Можно сделать это чистым CSS без SVG, но тогда придётся явно задавать цвет фона для картинки:

div {
  width: 100px;
  height: 100px;
  border-radius: 50%;
  position: relative;
  /* Явно задаём белый цвет */
  background-color: white;
}

div:after { content: ""; background: linear-gradient(#0070d8, #2cdbf1, #83eb8a); position: absolute; left: -5px; right: -5px; top: -5px; bottom: -5px; border-radius: 50%; z-index: -1; }

<div></div>
  • Тут проблема была в том, чтобы внутри применялся цвет бэкграунда, насколько я понял. – MihailPw Jun 22 '17 at 08:26
1

Можно использовать ответ @ArtemGorlachev и немного его модифицировать для того, чтобы он растягивался под произвольный блок:

<svg viewBox="0 0 220 220"  width="100%" height="100%" preserveAspectRatio="none">
    <defs>
        <linearGradient id="gradient">
            <stop offset="0" style="stop-color:#0070d8" />
            <stop offset="0.5" style="stop-color:#2cdbf1" />
            <stop offset="1" style="stop-color:#83eb8a" />
        </linearGradient>
    </defs>
    <ellipse ry="100" rx="100" cy="110" cx="110" style="fill:none;stroke:url(#gradient);stroke-width:6;" />
</svg>

Можете сделать SVG либо отдельным файлом (предпочтительный способ), либо как часть значения background (представленный ниже код будет работать только в webkit браузерах):

div {
  width: 250px;
  height: 250px;
  background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 220 220" width="100%" height="100%" preserveAspectRatio="none"><defs><linearGradient id="gradient"><stop offset="0" style="stop-color:#0070d8" /><stop offset="0.5" style="stop-color:#2cdbf1" /><stop offset="1" style="stop-color:#83eb8a" /></linearGradient></defs><ellipse ry="100" rx="100" cy="110" cx="110" style="fill:none;stroke:url(#gradient);stroke-width:6;" /></svg>');
}
<div></div>

Для того, чтобы код работал в MS Edge и Firefox символы внутри url должны быть escaped после кодировки utf8, для них результат с учётом обходного пути (замена двойных кавычек на одинарные, # на %23 и % на %25) будет выглядет так:

div {
  width: 250px;
  height: 250px;
  background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 220 220' width='100%25' height='100%25' preserveAspectRatio='none'><defs><linearGradient id='gradient'><stop offset='0' style='stop-color:%230070d8' /><stop offset='0.5' style='stop-color:%232cdbf1' /><stop offset='1' style='stop-color:%2383eb8a' /></linearGradient></defs><ellipse ry='100' rx='100' cy='110' cx='110' style='fill:none;stroke:url(%23gradient);stroke-width:6;' /></svg>");
  background-size: 100% 100%; /* Фикс для Firefox, чтобы изображение корректно растягивалось */
}
<div></div>