tiger
tiger

Reputation: 131

How do I force a SVG to be contained in a div?

I am trying to create a <svg> inside a <div>. I have used overflow: auto; in the #display rule, but the <svg> still goes outside of the <div>. I want the <svg> to appear only inside of the <div> as if the <div> is the display window of <svg>. When the <svg> goes out of the side of <div>, I want to put a scroll bar on the side of the <div> only. I appreciate the help.

$(document).ready(function(){
    $('#testbtm').click(function(){
        var str = '<svg class="hexagon" class="ui-widget-content"   style="position:absolute; left:800; top:800;">\
        <text fill="black" x=75 y=75 style="text-anchor: middle">1</text>\
        <path d="M38 0 L113 0 L150 65 L113 130 L38 130 L0 65 Z" / fill="none" stroke="blue"></svg>'
        var svgElement = $(str);		
        svgElement.children('text').text(1);
        $("#display").append(svgElement);	
    }); //end click	
}); // end ready
#display {
    height: 500px;
    width: 500px;
    border: 1px solid black;
    overflow: auto;
}
<script  src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"> </script>
<div id="display"></div>
<button id="testbtm">test</button>

Upvotes: 5

Views: 8447

Answers (4)

timolawl
timolawl

Reputation: 5564

All you need to do is add position: relative to your #display.

Since you have position: absolute specified, it will look for the closest ancestor positioned (non-static) element. Without #display being a positioned element, it takes the initial containing block, meaning the visible viewport as the anchor to position itself against. This is why you see the <svg> appearing to spill out of the <div>.

Of course, with your current inline styles, your hexagon would appear at the bottom right of the scrollable #display.

Edit: I have moved out the inline style to an external stylesheet specified under your class .hexagon as there seems to be an issue with displaying the number without moving the inline style out. Nevertheless, this gets you your result preserving your offset dimensions while keeping the #display scrollable.

Try out the code below:

$(document).ready(function(){
    $('#testbtm').click(function(){
        var str = '<svg class="hexagon ui-widget-content">\
        <text fill="black" x=75 y=75 style="text-anchor: middle">1</text>\
        <path d="M38 0 L113 0 L150 65 L113 130 L38 130 L0 65 Z" fill="none" stroke="blue"></svg>'
        var svgElement = $(str);		
        svgElement.children('text').text(1);
        $("#display").append(svgElement);	
    }); //end click	
}); // end ready
#display {
    height: 500px;
    width: 500px;
    border: 1px solid black;
    overflow: auto;
  position: relative; /* add this line! */
}

.hexagon {  /* extracted inline style to external stylesheet */
  position: absolute;
  left: 800px;
  top: 800px;
}
<script  src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"> </script>
<div id="display"></div>
<button id="testbtm">test</button>

Upvotes: 3

Jinu Kurian
Jinu Kurian

Reputation: 9416

You gotta give position: relative to your parent element and your left and top values must be in pixel. Reduced width and height for convenience.

$(document).ready(function(){
    $('#testbtm').click(function(){
        var str = '<svg class="hexagon" class="ui-widget-content"   style="position:absolute; left:50%; top:50%; transform: translate(-50%,-50%)">\
        <text fill="black" x=75 y=75 style="text-anchor: middle">1</text>\
        <path d="M38 0 L113 0 L150 65 L113 130 L38 130 L0 65 Z" / fill="none" stroke="blue"></svg>'
        var svgElement = $(str);		
        svgElement.children('text').text(1);
        $("#display").append(svgElement);	
    }); //end click	
}); // end ready
#display {
    height: 250px;
    width: 250px;
    border: 1px solid black;
    overflow: auto;
    position: relative;
}

svg{
  max-width: 100%;
}
<script  src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"> </script>
<div id="display"></div>
<button id="testbtm">test</button>

Upvotes: 4

Naveed Ahmed
Naveed Ahmed

Reputation: 166

I think you are looking to do something like this:

$(document).ready(function(){
    $('#testbtm').click(function(){
        var str = '<svg class="hexagon" class="ui-widget-content">\
        <text fill="black" x=75 y=75 style="text-anchor: middle">1</text>\
        <path d="M38 0 L113 0 L150 65 L113 130 L38 130 L0 65 Z" / fill="none" stroke="blue"></svg>'
        var svgElement = $(str);		
        svgElement.children('text').text(1);
        $("#display").append(svgElement);	
    }); //end click	
}); // end ready
#display {
    height: 500px;
    width: 500px;
    border: 1px solid black;
    overflow: auto;
    position: relative;
}
.hexagon{
    height:150px;
    width:150px;
    position: absolute;
    top:50%;
    left:50%;
    transform:translate(-50%,-50%);
}
<script  src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"> </script>
<div id="display"></div>
<button id="testbtm">test</button>

Here is fiddle goody for you: https://jsfiddle.net/hb796myn/

Upvotes: 0

Paul LeBeau
Paul LeBeau

Reputation: 101830

If you want your SVG to be drawn inside the <div> then you will have to remove the position: absolute that you have set on it.

$(document).ready(function(){
    $('#testbtm').click(function(){
        var str = '<svg class="hexagon" class="ui-widget-content"   width="1000px" height="1000px">\
        <text fill="black" x=75 y=75 style="text-anchor: middle">1</text>\
        <path d="M38 0 L113 0 L150 65 L113 130 L38 130 L0 65 Z" / fill="none" stroke="blue"></svg>'
        var svgElement = $(str);		
        svgElement.children('text').text(1);
        $("#display").append(svgElement);	
    }); //end click	
}); // end ready
#display {
    height: 500px;
    width: 500px;
    border: 1px solid black;
    overflow: auto;
}
<script  src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"> </script>
<div id="display"></div>
<button id="testbtm">test</button>

Upvotes: 0

Related Questions