Spec-Zone.ru › CSS

CSS-функция `ellipse()`

Базовая поддержка Широко доступна

Эта функция хорошо зарекомендовала себя и работает на множестве устройств и в разных версиях браузеров. Она доступна во всех браузерах с января 2020 года.

ellipse() — это функция CSS, относящаяся к одному из <basic-shape> типов данных.

Попробуйте

clip-path: ellipse(20px 50px);
clip-path: ellipse(4rem 50% at right center);
clip-path: ellipse(closest-side closest-side at 5rem 6rem);
clip-path: ellipse(closest-side farthest-side);
clip-path: ellipse(closest-corner closest-corner at 25% 25%);
clip-path: ellipse(closest-side closest-corner at 25% 25%);
clip-path: ellipse(closest-side farthest-corner at 25% 25%);
<section class="default-example" id="default-example">
  <div class="transition-all" id="example-element"></div>
</section>
#default-example {
  background: #ffee99;
}

#example-element {
  background: linear-gradient(to bottom right, #ff5522, #0055ff);
  width: 100%;
  height: 100%;
}

Синтаксис

shape-outside: ellipse(40% 50% at left);
shape-outside: ellipse(closest-side farthest-side at 30%);
border-shape: ellipse(50% 40%);

Эллипс — это, по сути, сплюснутый круг, поэтому ellipse() работает очень похоже на circle(), за исключением того, что здесь нужно указать два радиуса: x и y.

Значения

<shape-radius>
Два радиуса: x и y, именно в таком порядке. Это могут быть <length>, <percentage> или одно из следующих ключевых слов:
closest-side
Радиус равен расстоянию от центра эллипса до ближайшей стороны ограничивающего блока в заданном направлении радиуса, так что граница эллипса касается этой стороны.
farthest-side
Радиус равен расстоянию от центра эллипса до самой дальней стороны ограничивающего блока в заданном направлении радиуса, так что граница эллипса касается этой стороны.
closest-corner
Радиус равен расстоянию от центра эллипса до ближайшего угла ограничивающего блока в заданном направлении радиуса.
farthest-corner
Радиус равен расстоянию от центра эллипса до самого дальнего угла ограничивающего блока в заданном направлении радиуса.
<position>
Перемещает центр эллипса. Может быть <length>, <percentage> или таким значением, как left. Если значение <position> не указано, по умолчанию используется центр.

Формальный синтаксис

<ellipse()> = 
  ellipse( <radial-size>? [ at <position> ]? )

<radial-size> = 
  <radial-extent> |
  <length [0,∞]> |
  <length-percentage [0,∞]>{2}

<position> = 
  [ [ left | center | right ] || [ top | center | bottom ] | [ left | center | right | <length-percentage> ] [ top | center | bottom | <length-percentage> ]? | [ [ left | right ] <length-percentage> ] && [ [ top | bottom ] <length-percentage> ] ]

<radial-extent> = 
  closest-corner |
  closest-side |
  farthest-corner |
  farthest-side

<length-percentage> = 
  <length> |
  <percentage>

Примеры

Простой пример ellipse()

В этом примере эллипс обтекается текстом слева. Его горизонтальный радиус равен 40%, вертикальный — 50%, а положение задано слева. Это означает, что центр эллипса находится на левом краю блока, образуя полуэллипс, вокруг которого размещается текст. Нажмите «Play» в блоках кода, чтобы изменить эти значения и посмотреть, как меняется эллипс:

<div class="box">
  <div class="shape"></div>
  <p>
    One November night in the year 1782, so the story runs, two brothers sat
    over their winter fire in the little French town of Annonay, watching the
    grey smoke-wreaths from the hearth curl up the wide chimney. Their names
    were Stephen and Joseph Montgolfier, they were papermakers by trade, and
    were noted as possessing thoughtful minds and a deep interest in all
    scientific knowledge and new discovery. Before that night—a memorable night,
    as it was to prove—hundreds of millions of people had watched the rising
    smoke-wreaths of their fires without drawing any special inspiration from
    the fact.
  </p>
</div>
body {
  font: 1.2em / 1.5 sans-serif;
}
.shape {
  float: left;
  shape-outside: ellipse(40% 50% at left);
  margin: 20px;
  width: 100px;
  height: 200px;
}

Использование значений closest-side / farthest-side

Ключевые слова closest-side и farthest-side позволяют быстро создать эллипс на основе размеров ограничивающего блока плавающего элемента.

<div class="box">
  <div class="shape"></div>
  <p>
    One November night in the year 1782, so the story runs, two brothers sat
    over their winter fire in the little French town of Annonay, watching the
    grey smoke-wreaths from the hearth curl up the wide chimney. Their names
    were Stephen and Joseph Montgolfier, they were papermakers by trade, and
    were noted as possessing thoughtful minds and a deep interest in all
    scientific knowledge and new discovery. Before that night—a memorable night,
    as it was to prove—hundreds of millions of people had watched the rising
    smoke-wreaths of their fires without drawing any special inspiration from
    the fact.
  </p>
</div>
body {
  font: 1.2em / 1.5 sans-serif;
}
.shape {
  float: left;
  shape-outside: ellipse(closest-side farthest-side at 30%);
  margin: 20px;
  width: 100px;
  height: 140px;
}

Интерактивный пример ключевых слов радиуса

В этом примере можно проверить, как перемещение центральной точки эллипса влияет на результат при использовании каждого из четырёх ключевых слов <shape-radius> — независимо выбранных для радиуса по оси x и радиуса по оси y.

Поскольку closest-corner и farthest-corner появились в ellipse() позже, скрипт проверяет поддержку каждого ключевого слова с помощью CSS.supports(), прежде чем включить его. Ключевые слова, которые ещё не поддерживаются вашим браузером, отключаются в обоих раскрывающихся списках и помечаются как «не поддерживается».

HTML

Сначала в HTML задаются элементы управления для выбора ключевых слов радиуса по осям x и y и указания положения эллипса, а затем добавляется элемент <pre> для отображения clip-path, выбранного с помощью этих элементов управления. После него добавляется элемент #support-note, показывающий, когда определённые ключевые слова радиуса не поддерживаются.

<div class="controls">
  <div class="controls-row">
    <label>
      X radius:
      <select id="radius-x-keyword">
        <option value="closest-side">closest-side</option>
        <option value="closest-corner">closest-corner</option>
        <option value="farthest-side">farthest-side</option>
        <option value="farthest-corner" selected>farthest-corner</option>
      </select>
    </label>
    <label>
      Y radius:
      <select id="radius-y-keyword">
        <option value="closest-side">closest-side</option>
        <option value="closest-corner">closest-corner</option>
        <option value="farthest-side" selected>farthest-side</option>
        <option value="farthest-corner">farthest-corner</option>
      </select>
    </label>
  </div>
  <div class="controls-row">
    <label>
      Position X:
      <input type="range" id="pos-x" min="0" max="200" value="120" />
    </label>
    <label>
      Position Y:
      <input type="range" id="pos-y" min="0" max="120" value="40" />
    </label>
  </div>
</div>

<pre id="declaration"></pre>

<p id="support-note"></p>

Затем в HTML задаются несколько элементов <div>, используемых для отображения эллипса, ограничивающего блока и маркера центра. Наиболее важны ограничивающий блок (#refbox) и содержащийся в нём элемент .fill, которые задают градиент (об этом говорится в следующем разделе, посвящённом CSS). С помощью JavaScript для ограничивающего блока задаётся clipPath, обрезающий градиент по форме эллипса.

<div class="canvas">
  <div class="refbox" id="refbox">
    <div class="fill"></div>
  </div>
  <div class="outline"></div>
  <div class="center-marker" id="center-marker"></div>
</div>

Обратите внимание, что .outline и .center-marker добавлены, чтобы было проще видеть ограничивающий блок и центр эллипса отсечения, которые иначе были бы невидимы. Элемент .outline должен находиться в разметке после #refbox: поскольку сам он не обрезается, его отрисовка после ограничивающего блока гарантирует, что его пунктирная граница всегда будет поверх градиента .fill, даже если эллипс отсечения выходит за пределы ограничивающего блока.

CSS

Ниже показан CSS для холста, ограничивающего блока и элементов заливки. Обратите внимание, что .fill задаёт градиент, выходящий за пределы ограничивающего блока и заполняющий большую часть холста. Этот градиент будет обрезан с помощью функции ellipse() (для этого мы динамически задаём путь отсечения CSS в коде JavaScript).

.canvas {
  position: relative;
  width: 640px;
  height: 480px;
  overflow: hidden;
  border: 1px solid #888888;
}

.refbox {
  position: absolute;
  top: 180px;
  left: 220px;
  width: 200px;
  height: 120px;
  box-sizing: border-box;
}

.fill {
  position: absolute;
  inset: -240px;
  background: linear-gradient(to bottom right, #ff5522, #0055ff);
}

CSS для элементов управления и остальных элементов не показан, так как он не нужен для понимания метода ellipse(). Желающие могут посмотреть его в интерактивном примере.

body {
  display: flex;
  flex-direction: column;
  gap: 20px;
  align-items: flex-start;
}

.controls {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.controls-row {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  align-items: center;
}
.outline {
  position: absolute;
  top: 180px;
  left: 220px;
  width: 200px;
  height: 120px;
  box-sizing: border-box;
}

.outline {
  border: 3px dashed #e6007a;
  pointer-events: none;
}

.center-marker {
  position: absolute;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: white;
  border: 2px solid black;
  transform: translate(-50%, -50%);
  pointer-events: none;
}

#declaration {
  margin: 0;
}

#support-note {
  margin: 0;
  color: #b3001b;
}

JavaScript

Сначала мы получаем ссылки на все элементы, используемые в примере.

const selectX = document.getElementById("radius-x-keyword");
const selectY = document.getElementById("radius-y-keyword");
const posX = document.getElementById("pos-x");
const posY = document.getElementById("pos-y");
const refbox = document.getElementById("refbox");
const declaration = document.getElementById("declaration");
const marker = document.getElementById("center-marker");
const supportNote = document.getElementById("support-note");

Затем мы определяем функцию checkSupport(), которая проверяет поддержку каждого ключевого слова радиуса и включает или отключает соответствующие параметры в обоих раскрывающихся списках. Для проверки поддержки ключевых слов используется метод CSS.supports().

function checkSupport() {
  const unsupported = new Set();
  for (const option of selectX.options) {
    const test = `ellipse(${option.value} ${option.value} at 0px 0px)`;
    if (!CSS.supports("clip-path", test)) {
      unsupported.add(option.value);
    }
  }
  for (const select of [selectX, selectY]) {
    for (const option of select.options) {
      if (unsupported.has(option.value)) {
        option.disabled = true;
        option.textContent += " (not supported)";
      }
    }
    if (select.selectedOptions[0]?.disabled) {
      const firstSupported = [...select.options].find(
        (option) => !option.disabled,
      );
      if (firstSupported) {
        select.value = firstSupported.value;
      }
    }
  }
  if (unsupported.size > 0) {
    supportNote.textContent = `Your browser doesn't support: ${[...unsupported].join(", ")}.`;
  }
}

Далее мы определяем функцию update(), которая вызывается при изменении элементов управления. Она задаёт путь отсечения для ограничивающего блока на основе выбранных ключевых слов радиусов по осям x и y и положения, а также перемещает маркер центра в соответствующее место.

function update() {
  const xKeyword = selectX.value;
  const yKeyword = selectY.value;
  const x = Number(posX.value);
  const y = Number(posY.value);

  // Build the clip-path value and apply it to the reference box
  const value = `ellipse(${xKeyword} ${yKeyword} at ${x}px ${y}px)`;
  refbox.style.clipPath = value;

  // Update the displayed declaration text and marker position
  declaration.textContent = `clip-path: ${value};`;
  marker.style.left = `${refbox.offsetLeft + x}px`;
  marker.style.top = `${refbox.offsetTop + y}px`;
}

selectX.addEventListener("change", update);
selectY.addEventListener("change", update);
posX.addEventListener("input", update);
posY.addEventListener("input", update);
checkSupport();
update();

Результат

Измените положение центра и ключевое слово для каждого радиуса, чтобы увидеть их относительное влияние. Обратите внимание, что ограничивающий блок вместе с выбранными ключевыми словами радиусов по осям x и y и заданным положением используется для вычисления эллипса отсечения. Этот эллипс может выходить за пределы ограничивающего блока (например, при использовании closest-corner или farthest-corner); градиент .fill намеренно сделан больше ограничивающего блока, чтобы полностью покрывать обрезаемый эллипс, как бы далеко он ни выходил за его пределы.

Спецификации

Спецификация
Модуль CSS Shapes, уровень 1
# funcdef-basic-shape-ellipse

Совместимость с браузерами

Настольные компьютеры Мобильные устройства
Chrome Edge Firefox Opera Safari Chrome Android Firefox для Android Opera Android Safari на iOS Samsung Internet WebView Android WebView на iOS
ellipse
37
79
54
24
10.1
37
54
24
10.3
3.0
37
10.3
closest-corner
Нет
Нет
предварительная версия
Нет
18.4
Нет
Нет
Нет
18.4
Нет
Нет
18.4
farthest-corner
Нет
Нет
предварительная версия
Нет
18.4
Нет
Нет
Нет
18.4
Нет
Нет
18.4

См. также

  • Свойства, использующие этот тип данных: border-shape, clip-path, shape-outside
  • Руководство по базовым фигурам

© 2005–2025 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Values/basic-shape/ellipse

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API