Ниже представлен упрощенный макет, в котором используется 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"> </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>
Сделайте 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"> </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 обусловлена сочетанием соотношения сторон viewBox
(отношение ширины к высоте => 10: 60) и ширины столбца (из класса col-xs-1
). Таким образом, если ширина столбца составляет 100 пикселей, высота SVG будет 600 пикселей. Фактическая высота будет зависеть от ширины окна браузера, поскольку ширина col-xs-1
выражается в процентах.
Фантастический. Спасибо, Пол. Один вопрос и одно примечание - вопрос: есть идеи, как браузер решает отображать SVG в 314,91 пикселей в высоту? Мне это кажется совершенно произвольным. Примечание: псевдокласс в контейнере SVG не нужен, если правило
display: flex
не закомментировано для.row
.