Как я могу предотвратить отображение встроенного SVG на произвольной высоте, не задавая ему (или его родительскому элементу) явную высоту?

Ниже представлен упрощенный макет, в котором используется Bootstrap 3. Средний столбец в строке содержит встроенный SVG, который обеспечивает своего рода переход от синего поля к зеленому.

Почему я хочу это сделать? Стилизация SVG с помощью CSS браузера - это круто! Более того, это означает, что мне не нужно создавать кучу PNG для каждой возможной высоты строки и сочетания цветов, к которым я мог бы применить этот элемент дизайна.

Хотя я мог бы использовать JS для динамической установки высоты div'ов col- * на основе самого высокого из них, не содержащего SVG, похоже, должен быть способ сделать это с помощью CSS.

Обратите внимание, что я пробовал установить display: flex для элемента .row (это закомментировано в таблице стилей). Хотя он гарантирует, что столбцы имеют одинаковую высоту, он дает эффект увеличения блоков содержимого, а не уменьшения стиля.

Этот Plunker включен на тот случай, если вам, как и мне, будет немного проще работать, чем с фрагментом StackOverflow.

html, body.stackoverflow-snippet {
  color: white;
  font-size: 25px;
  height: 100%;
}

.row {
  /*
   * Ultimately I would use the following rule to ensure the columns are equal
   * height, since their content is dynamic, but the problem is less obvious
   * when this rule is in effect.
   */
  /* display: flex; */
}

.row.desired-result div {
  /*
   * To see the desired effect, set the height to any known value. In my case, I
   * can't set the height of the divs explicitly the because user-generated
   * content populates these divs and may change their height.
   */
  height: 35px;
}

.row .rounded {
  padding-left: 0;
}

.blue {
  background: blue;
}

.green {
  background: green;
}

svg {
  height: 100%;
}

svg circle {
  fill: blue;
}
<!DOCTYPE html>
<html>

<head>
  <link rel = "stylesheet" href = "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
</head>

<body class = "stackoverflow-snippet">
  <div class = "container-fluid">
    <!-- first row: desired result -->
    <div class = "row desired-result">
      <div class = "blue col-xs-6">Desired result</div>
      <div class = "green rounded col-xs-1">
        <svg xmlns:svg = "http://www.w3.org/2000/svg" xmlns = "http://www.w3.org/2000/svg" class = "inline-svg inlined-svg" viewBox = "90 20 10 60" role = "img">
          <circle r = "50" cy = "50" cx = "50"></circle>
        </svg>
      </div>
      <div class = "green col-xs-5">(explicit height)</div>
    </div>
    <!-- second row: just a visual break to separate the rows of interest -->
    <div class = "row">
      <div class = "col-xs-12">&nbsp;</div>
    </div>
    <!-- third row: natural height -->
    <div class = "row">
      <div class = "blue col-xs-6">Ack!</div>
      <div class = "green rounded col-xs-1">
        <svg xmlns:svg = "http://www.w3.org/2000/svg" xmlns = "http://www.w3.org/2000/svg" class = "inline-svg inlined-svg" viewBox = "90 20 10 60" role = "img">
          <circle r = "50" cy = "50" cx = "50"></circle>
        </svg>
      </div>
      <div class = "green col-xs-5">(natural height)</div>
    </div>
  </div>
</body>

</html>
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Введение в CSS
Введение в CSS
CSS является неотъемлемой частью трех основных составляющих front-end веб-разработки.
Как выровнять Div по центру?
Как выровнять Div по центру?
Чтобы выровнять элемент <div>по горизонтали и вертикали с помощью CSS, можно использовать комбинацию свойств и значений CSS. Вот несколько методов,...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
CSS: FlexBox
CSS: FlexBox
Ранее разработчики использовали макеты с помощью Position и Float. После появления flexbox сценарий полностью изменился.
0
0
34
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Сделайте SVG position: absolute. Затем "100%" высота будет измерена относительно его родительского контейнера. Если вы также не забыли установить для родительской ячейки значение position: relative, чтобы превратить ее в подходящий содержащий блок.

.svg-container {
  position: relative;
}

.inline-svg {
  position: absolute;
  left: 0;
}

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

.svg-container::before {
  content: '\a0'
}

Результат:

html, body.stackoverflow-snippet {
  color: white;
  font-size: 25px;
  height: 100%;
}

.row {
  /*
   * Ultimately I would use the following rule to ensure the columns are equal
   * height, since their content is dynamic, but the problem is less obvious
   * when this rule is in effect.
   */
  /* display: flex; */
}

.row.desired-result div {
  /*
   * To see the desired effect, set the height to any known value. In my case, I
   * can't set the height of the divs explicitly the because user-generated
   * content populates these divs and may change their height.
   */
  height: 35px;
}

.row .rounded {
  padding-left: 0;
}

.blue {
  background: blue;
}

.green {
  background: green;
}

svg {
  height: 100%;
}

svg circle {
  fill: blue;
}

.svg-container {
  position: relative;
}

.svg-container::before {
  content: '\a0'
}

.inline-svg {
  position: absolute;
  left: 0;
}
<!DOCTYPE html>
<html>

<head>
  <link rel = "stylesheet" href = "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
</head>

<body class = "stackoverflow-snippet">
  <div class = "container-fluid">
    <!-- first row: desired result -->
    <div class = "row desired-result">
      <div class = "blue col-xs-6">Desired result</div>
      <div class = "green rounded col-xs-1">
        <svg xmlns:svg = "http://www.w3.org/2000/svg" xmlns = "http://www.w3.org/2000/svg" class = "inline-svg inlined-svg" viewBox = "90 20 10 60" role = "img">
          <circle r = "50" cy = "50" cx = "50"></circle>
        </svg>
      </div>
      <div class = "green col-xs-5">(explicit height)</div>
    </div>
    <!-- second row: just a visual break to separate the rows of interest -->
    <div class = "row">
      <div class = "col-xs-12">&nbsp;</div>
    </div>
    <!-- third row: natural height -->
    <div class = "row">
      <div class = "blue col-xs-6">Ack!</div>
      <div class = "green rounded col-xs-1 svg-container">
        <svg xmlns:svg = "http://www.w3.org/2000/svg" xmlns = "http://www.w3.org/2000/svg" class = "inline-svg inlined-svg" viewBox = "90 20 10 60" role = "img">
          <circle r = "50" cy = "50" cx = "50"></circle>
        </svg>
      </div>
      <div class = "green col-xs-5 svg-container">
        (natural height)</div>
    </div>
  </div>
</body>

</html>

Фантастический. Спасибо, Пол. Один вопрос и одно примечание - вопрос: есть идеи, как браузер решает отображать SVG в 314,91 пикселей в высоту? Мне это кажется совершенно произвольным. Примечание: псевдокласс в контейнере SVG не нужен, если правило display: flex не закомментировано для .row.

universalhandle 09.08.2018 17:55

Высота SVG обусловлена ​​сочетанием соотношения сторон viewBox (отношение ширины к высоте => 10: 60) и ширины столбца (из класса col-xs-1). Таким образом, если ширина столбца составляет 100 пикселей, высота SVG будет 600 пикселей. Фактическая высота будет зависеть от ширины окна браузера, поскольку ширина col-xs-1 выражается в процентах.

Paul LeBeau 09.08.2018 19:43

Другие вопросы по теме