Як змусити <svg> елемент розширити або скористатись своїм батьківським контейнером?


112

Мета полягає в тому, щоб <svg>елемент розширився до розміру свого батьківського контейнера, в цьому випадку a <div>, незалежно від того, наскільки великий він чи малий цей контейнер.

Код:

<style>
    svg, #container{
        height: 100%;
        width: 100%;
    }
</style>

<div id="container">
    <svg xmlns="http://www.w3.org/2000/svg" version="1.1" >
         <rect x="0" y="0" width="100" height="100" />
    </svg>
</div>

Найбільш поширеним рішенням цієї проблеми, здається, є встановлення viewBoxатрибута на <svg>елементі.

viewBox="0 0 widthOfContainer heightOfContainer"

Однак, здається, це не працює в тих випадках, коли елементи всередині <svg>елемента мають заздалегідь задані ширини та / або висоти. Наприклад, <rect>елемент у наведеному вище коді має чітко встановлені ширину та висоту.

Тож очевидним рішенням є використання% ширини та% висоти також для цих елементів. Але чи потрібно це навіть робити? Тим більше, оскільки він <img src=test.svg >працює чудово і розширює / стискає без проблем із явно заданими <rect>висотами та шириною.

Якщо такі елементи, як <rect>і інші подібні до нього елементи, повинні мати їх ширину та висоту, визначені у відсотках, чи існує спосіб встановити Inkscape таким чином, щоб усі елементи з <svg>документом використовували відсоткові ширини, висоти тощо .. замість фіксованих розмірів ?


1
Збережіть svg як файл, ніж посилайте його на зображення, як <img src = "file.svg" />, і таким чином ви можете використовувати ширину: 100% або висоту: 100%
Бурімі

Відповіді:


56

Це viewBoxне висота контейнера, це розмір малюнка. Визначте viewBoxширину 100 одиниць, а потім визначте, що вона rectмає бути 10 одиниць. Після цього, як би ви масштабували SVG, rectширина зображення буде на 10%.


33
Але питання в тому, як масштабувати SVG?
Адріан Гейне

6
@AdrianLang Масштабування відбувається автоматично, коли ви встановлюєте розмір об’єкта SVG, як це вже робиться в коді у запитанні. Ось фіксована версія прикладу .
robertc

Ти маєш рацію, чудово, що насправді працює на мене. Я думаю, що моєю проблемою були властивості висоти та ширини у моєму кореневому елементі svg.
Адріан Гейне

2
Я зробив декілька незначних змін у цій скрипці, щоб зробити розмір вимушеним по горизонталі та вертикалі, не зберігаючи співвідношення сторін, і змусив його працювати в IE, тоді як подана скрипка @robertc не була. Сподіваюся, це допоможе комусь у дорозі!
Містер Багряний

3
За замовчуванням ваш svg буде масштабувати якомога більше, щоб він був повністю видимий, але зберігав його співвідношення сторін (тому квадратний viewBox не заповнить повністю прямокутний батьківський). Якщо ви дійсно хочете змусити його повністю покрити батьківський контейнер, додайте до SVG-елемента зберегти SaveAspectRatio = "none" .
patricksurry

24

Припустимо, у мене є SVG, який виглядає приблизно так: pic1

І я хочу помістити його в дів і змусити його заповнити діву чуйно. Мій спосіб зробити це такий:

Спочатку я відкриваю файл SVG у такій програмі, як inkscape. У меню Файл-> Властивості документа я встановлюю ширину документа до 800 пікселів і висоту - 600 пікс (можна вибрати інші розміри). Потім я вписую SVG в цей документ.

pic2

Потім я зберігаю цей файл як новий файл SVG і отримую дані про шлях до цього файлу. Тепер у HTML код, який робить магію, такий:

<div id="containerId">    
    <svg
    id="svgId" 
    xmlns:svg="http://www.w3.org/2000/svg"
    xmlns="http://www.w3.org/2000/svg"
    version="1.1"
    x="0"
    y="0"
    width="100%"
    height="100%"
    viewBox="0 0 800 600"
    preserveAspectRatio="none">
       <path d="m0 0v600h800v-600h-75.07031l-431 597.9707-292.445315-223.99609 269.548825-373.97461h-271.0332z" fill="#f00"/>
    </svg>
</div>

Зауважте, що ширина та висота SVG встановлені на 100%, оскільки ми хочемо, щоб він заповнював контейнер вертикально та горизонтально, але ширина та висота viewBox збігаються із шириною та висотою документа у чорнильному кольорі, який становить 800px X 600 пікс. Наступне, що вам потрібно зробити, - це встановити файл зберігання збереженняАспектРаціо на "ні". Якщо вам потрібно отримати більше інформації про цей атрибут, ось хороше посилання . І це все є.

Ще одна річ полягає в тому, що цей код працює майже у всіх основних браузерах, навіть у старих, але для деяких версій Android та ios вам потрібно використовувати код javascrip / jQuery, щоб підтримувати його. Я використовую наступне в документах, готових і змінюючи розміри:

$('#svgId').css({
    'width': $('#containerId').width() + 'px',
    'height': $('#containerId').height() + 'px'
});

Сподіваюся, це допомагає!


5
+1 для замітки ЗапасAspectRatio. Після полювання на високому та низькому рівні, щоб отримати SVG фактично розтягнутись (а не масштабом) до діву, це була правильна відповідь.
Адельф

@Gazoris, Дякую за цю чудову відповідь. є питання щодо того ж. Що робити, якщо мій svg вкладений. наприклад, <svg> <svg id = "1"> </svg> <svg id = "2"> </svg> </svg> я хочу умовно відображати svg 1 та 2, і він повинен мати ширину та висоту контейнера <div id = "контейнер" style = "ширина: 200px; висота: 200px;"> </div> чи можете ви мені допомогти з цим.
Парасад Прасада

@ Реза Барадаран: Геній.
DanMad

6

Що для мене нещодавно працює - це видалити всі height=""та width=""атрибути з <svg>тегу та всіх дочірніх тегів. Потім ви можете використовувати масштабування, використовуючи відсоток висоти або ширини батьківського контейнера.


5
Чи можете ви навести робочий приклад? Я не можу змусити це щось зробити.
Майкл

2

@robertc має право, але ви також повинні зауважити, що svg, #containerспричиняє масштабування SVG в експоненціальному відношенні нічого, крім 100% (один раз #containerі раз для svg).

Іншими словами, якщо я застосував 50% h / w до обох елементів, це насправді 50% 50%, або .5 * .5, що дорівнює .25 або 25% шкалі.

Один селектор працює добре, коли використовується @robertc.

svg {
  width:50%;
  height:50%;
}

Це тому , що ваш селектор svg, #containerвідповідає як на svgелемент DOM і на #containerелемент DOM. Я вважаю, що ви натомість шукали svg #container, але специфікація батьків не потрібна, якщо ви все одно використовуєте ідентифікатор.
Ніт

Чи не саме те, що я сказав: "раз для # container і раз для svg"?
Джастін Путні

1
Про пробачте, ви праві, але ваша відповідь трохи дивно сформульована, що призводить до нерозуміння. Це звучить так, ніби ви спочатку говорите про потенційну ганчу.
Ніт

1

Для свого iphone Ви можете використовувати в голові баліз:

"width=device-width"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.