mark: SVG - stroke von Umrandungen

Beitrag lesen

Verstehe. Du suchstvector-effect: non-scaling-stroke

Ich bin mir ziemlich sicher, dass es damit nicht funktioniert.

Ich habe nun alle Varianten getestet. Matthias Scharwies Methode ist bislang die einzige, die zufriedenstellend funktioniert.

Eine kleine Anmerkung vielleicht zu Matthias Scharwies Lösungsvorschlag: Statt x/y kann und muss man manchmal sogar transform: translate(X, Y) verwenden.

Ich habe ein kleines Testdokument zusammengebastelt, damit man wirklich genau versteht, was ich meine und vielleicht ist es dem einen oder anderen hilfreich.

Ich bin alle drei Lösungsvorschläge durchgegangen. stroke-alignment:inside wird noch nicht unterstützt, sonst wären es 4.

    1. svg:not(:root) {overflow: visible;}
    1. viewBox und x/y anpassen
    1. vector-effect="non-scaling-stroke"

https://codepen.io/anon/pen/YWgRNN

<!DOCTYPE html>
<html lang="de">
<head>
    <meta charset="UTF-8">
    <title>SVG Bounding Box Test</title>
    
    <style>
        .svg-samples{
            display: none;
        }
        
        section{
            margin-bottom: 5em;
            padding-bottom: 4em;
            border-bottom: 3px dashed lightgrey; 
        }
        
        .testing-area{
            width: 100%;
            overflow: hidden;
        }
        
        
        .testing-area svg{
            display: inline-block;
            vertical-align: middle;
            width: 12em;
            height: 12em;
            fill: none;
            margin: 1em;
        }
        
        .testing-area svg.small{
            width: 3em;
            height: 3em;
        }
        
        
        /*
         * 
         *  Stroke-width defaults
         * 
         * */
        
        .rect{
            stroke: deeppink;
            stroke-width: 4;
        }
        
        .circle-l{
            stroke: lightblue;
            stroke-width: 50;
        }
        
        .circle-s{
            stroke: lime;
            stroke-width: .04;
        }
        
        .octagon{
            stroke: black;
            stroke-width: .5;
        }
        
        
        /*
         * 
         *  Stroke-width changes
         * 
         * */
        
        .attempt-1 .rect,
        .attempt-2 .rect{
            stroke-width: 44;
        }
        
        .attempt-1 .circle-l,
        .attempt-2 .circle-l{
            stroke-width: 400;
        }
        
        .attempt-1 .circle-s,
        .attempt-2 .circle-s{
            stroke-width: .3;
        }
        
        .attempt-1 .octagon,
        .attempt-2 .octagon{
            stroke-width: 8;
        }
        

        .attempt-3 .rect{
            stroke-width: 1;
        }
        
        .attempt-3 .circle-l{
            stroke-width: 1;
        }
        

        .attempt-3 .circle-s{
            stroke-width: 1;
        }

        .attempt-3 .octagon{
            stroke-width: 1;
        }
        
        
        /*
         * 
         * 
         *     LÖSUNGSANSATZ 1 svg:not(:root){ overflow: visible; }
         * 
         * */
        
        .attempt-1 svg:not(:root){
            overflow: visible;
        }
        
        
    </style>
</head>
<body>

    <h1>SVG Bouding Box Test</h1>
    
    <svg class="svg-samples">
        <symbol id="rectangle" preserveAspectRatio="xMidYMid meet" viewBox="0 0 800 800">
            <rect width="800" height="800" />
        </symbol>
        
        <symbol id="circle-large" preserveAspectRatio="xMidYMid meet" viewBox="0 0 8000 8000">
            <circle cx="4000" cy="4000" r="4000" />
        </symbol>
        
        <symbol   x="0"  y="0"  id="circle-small" preserveAspectRatio="xMidYMid meet" viewBox="0 0 10 10">
            <circle cx="5" cy="5" r="5" />
        </symbol>
        
        <symbol id="octagon" preserveAspectRatio="xMidYMid meet" viewBox="0 0 177.9 177.9">
              <path d="M.2 52.2l52-52h73.4l52 52v73.4l-52 52H52.2l-52-52z" />
        </symbol>
        
        
        <!--    /*
                 * 
                 * 
                 *     LÖSUNGSANSATZ 2 angepasste viewBox
                 * 
                 * */  
        -->
        
        
        <!-- +44 -->
        <symbol id="rectangle-mod" preserveAspectRatio="xMidYMid meet" viewBox="0 0 844 844">
            <rect x="22" y="22" width="800" height="800" />
        </symbol>
        
        <!-- +400 -->
        <symbol id="circle-large-mod" preserveAspectRatio="xMidYMid meet" viewBox="0 0 8400 8400">
            <circle cx="4200" cy="4200" r="4000" />
        </symbol>
        
        <!-- +.3 -->
        <symbol id="circle-small-mod" preserveAspectRatio="xMidYMid meet" viewBox="0 0 10.3 10.3">
            <circle cx="5.15" cy="5.15" r="5" />
        </symbol>
        
        <!-- +8 -->
        <symbol id="octagon-mod" preserveAspectRatio="xMidYMid meet" viewBox="0 0 185.9 185.9">
              <path transform="translate(4, 4)" d="M.2 52.2l52-52h73.4l52 52v73.4l-52 52H52.2l-52-52z" />
        </symbol>
        
        
        <!--    /*
                 * 
                 * 
                 *     LÖSUNGSANSATZ 3 non-scaling-stroke
                 * 
                 * */  
        -->
        
        <symbol id="rectangle-non-scaling-stroke" preserveAspectRatio="xMidYMid meet" viewBox="0 0 800 800">
            <rect vector-effect="non-scaling-stroke" stroke-width="4" width="800" height="800" />
        </symbol>
        
        <symbol id="circle-large-non-scaling-stroke" preserveAspectRatio="xMidYMid meet" viewBox="0 0 8000 8000">
            <circle vector-effect="non-scaling-stroke" cx="4000" cy="4000" r="4000" />
        </symbol>
        
        <symbol id="circle-small-non-scaling-stroke" preserveAspectRatio="xMidYMid meet" viewBox="0 0 10 10">
            <circle vector-effect="non-scaling-stroke" cx="5" cy="5" r="5" />
        </symbol>
        
        <symbol id="octagon-non-scaling-stroke" preserveAspectRatio="xMidYMid meet" viewBox="0 0 177.9 177.9">
              <path vector-effect="non-scaling-stroke" d="M.2 52.2l52-52h73.4l52 52v73.4l-52 52H52.2l-52-52z" />
        </symbol>
                
    </svg>
               
    
    <section class="problem">
        <h2>Das Problem:</h2>
        
        <div>
           Idealerweise wären große und kleine Icons in der Farbintensität identisch. Dafür ist jedoch eine Änderung der
           stroke-width nötig, sonst ist die Umrandung ggf. nicht mehr erkennbar. Siehe nachfolgende Darstellung: zuerst sind die Icons
           groß abgebildet, dann, fast nicht sichtbar klein. Bei einem Rechteck ist das Problem nicht sofort ersichtlich,
           da der Stroke gleichmäßig beschnitten wird.
            
            <ul>
                <li>Die Stroke-width ist abhängig von der viewBox.</li>
                <li>Die ViewBox beschneidet den Stroke.</li> 
            </ul>
        </div>
        
        <div class="testing-area">
            <svg class="rect">
                <use xlink:href="#rectangle" />
            </svg>
            
            <svg class="circle-l">
                <use xlink:href="#circle-large" />
            </svg>
            
            <svg class="circle-s">
                <use xlink:href="#circle-small" />
            </svg>
            
            <svg class="octagon">
                <use xlink:href="#octagon" />
            </svg>
            
            <svg class="rect small">
                <use xlink:href="#rectangle" />
            </svg>
            
            <svg class="circle-l small">
                <use xlink:href="#circle-large" />
            </svg>
            
            <svg class="circle-s small">
                <use xlink:href="#circle-small" />
            </svg>
            
            <svg class="octagon small">
                <use xlink:href="#octagon" />
            </svg>
        </div>
    </section>    
    
    
    
    <section class="attempt attempt-1">
        <h2>Lösungsansatz 1</h2>
        
        <p>
            svg:not(:root) {overflow: visible;}<br />
            Nachteil: funktioniert nur im Firefox
        </p>
        
        <div class="testing-area"> 
            <svg class="rect small">
                <use xlink:href="#rectangle" />
            </svg>
            
            <svg class="circle-l small">
                <use xlink:href="#circle-large" />
            </svg>
            
            <svg class="circle-s small">
                <use xlink:href="#circle-small" />
            </svg>
            
            <svg class="octagon small">
                <use xlink:href="#octagon" />
            </svg>
        </div>
    </section>
    
    <section class="attempt attempt-2">
        <h2>Lösungsansatz 2</h2>
        
        <p>
            Anpassung der viewBox<br />
            Vorteil: Funktioniert in allen Browsern.<br />
            Nachteil: relativ aufwendig.<br />
            Bemerkung: Verschiebung der X/Y-Koordinate kann, bzw. muss in manchen Fällen mit transform: translate(X, Y) erfolgen.
        </p>
        
        <div class="testing-area">
            <svg class="rect small">
                <use xlink:href="#rectangle-mod" />
            </svg>
            
            <svg class="circle-l small">
                <use xlink:href="#circle-large-mod" />
            </svg>
            
            <svg class="circle-s small">
                <use xlink:href="#circle-small-mod" />
            </svg>
            
            <svg class="octagon small">
                <use xlink:href="#octagon-mod" />
            </svg>
        </div>
    </section>                                   
    
    <section class="attempt attempt-3">
        <h2>Lösungsansatz 3</h2>
        
        <p>
            vector-effect="non-scaling-stroke"<br />
            Funktioniert nicht: beschneidet die stroke-width.<br />
            Funktioniert nicht im IE11. Edge konnte ich nicht testen.
        </p>
        
        <div class="testing-area">
            <svg class="rect small">
                <use xlink:href="#rectangle-non-scaling-stroke" />
            </svg>
            
            <svg class="circle-l small">
                <use xlink:href="#circle-large-non-scaling-stroke" />
            </svg>
            
            <svg class="circle-s small">
                <use xlink:href="#circle-small-non-scaling-stroke" />
            </svg>
            
            <svg class="octagon small">
                <use xlink:href="#octagon-non-scaling-stroke" />
            </svg>
        </div>
    </section>                                                                                                                                                                                                                                                                             
</body>
</html>