<div class="wrapper clearfix">
  <div class="controls column">
    <fieldset>
      <legend>viewBox</legend>
      <div class="input">
        <label for="#min-x">&lt;min-x&gt;</label> <input type="number" id="min-x" class="viewbox-option" value="0" step="1">
      </div>
      <div class="input">
        <label for="#min-y">&lt;min-y&gt;</label> <input type="number" id="min-y" class="viewbox-option" value="0" step="1">
      </div>
      <label for="#viewBox-width">&lt;width&gt;</label>
      <input type="range" id="viewbox-width" class="viewbox-option" min="100" value="800" max="1600" step="10"><output for="viewbox-width">800</output>
      <label for="#viewbox-height">&lt;height&gt;</label>
      <input type="range" id="viewbox-height" class="viewbox-option" min="100" value="600" max="1200" step="10" data-current-value="300"><output for="viewbox-height">600</output>
    </fieldset>
    <fieldset>
      <legend>preserveAspectRatio</legend>
      <label for="alignment">&lt;align&gt;</label>
      <select class="preserveAspectRatio-options" id="alignment">
        <option value="none">None</option>
        <option value="xMinYMin">xMinYMin</option>
        <option value="xMinYMid">xMinYMid</option>
        <option value="xMinYMax">xMinYMax</option>
        <option value="xMidYMin">xMidYMin</option>
        <option value="xMidYMid" selected>xMidYMid</option>
        <option value="xMidYMax">xMidYMax</option>
        <option value="xMaxYMin">xMaxYMin</option>
        <option value="xMaxYMid">xMaxYMid</option>
        <option value="xMaxYMax">xMaxYMax</option>
      </select>
      <div class="radios">
        <input type="radio" value="meet" name="meetOrSlice" id="meet" checked="checked"><label for="meet" style="margin-right: 1em;">meet</label>
        <input type="radio" value="slice" name="meetOrSlice" id="slice"><label for="slice">slice</label>
      </div>
    </fieldset>
    <input type="checkbox" id="guidelines-visibility"><label for="guidelines-visibility" style="display:inline-block; margin-left: .5em;">Show x &amp; y Guidelines</label>
  </div>
  <div class="svg-container column">
    <svg class="outer" width="800" height="600" viewBox="0 0 800 600">
      <g class="guidelines">
        <path id="midlines" class="separator guideline" stroke-dasharray="2" />
      </g>
      <path class="separator ruler" />
      <svg class="inner" width="800" height="600" viewBox="0 0 800 600" preserveAspectRatio="xMidYMid meet">
        <g id="parrot">
          <path fill="#68A284" d="M98.595 272.797c-41.144 0-77.262-28.608-97.898-71.725 3.832 44.6 25.214 98.16 98.218 98.16 72.024 0 94.49-54.748 98.282-99.631C176.686 243.541 140.206 272.797 98.595 272.797z" />
          <path fill="#5EEA99" d="M196.082 161.237c-20.703 42.64-56.618 70.872-97.487 70.872 -40.322 0-75.837-27.467-96.662-69.153C0.61 170.116 0 177.521 0 185.006c0 5.137 0.222 10.535 0.697 16.066 20.636 43.116 56.754 71.725 97.898 71.725 41.611 0 78.091-29.256 98.603-73.195 0.422-5.018 0.625-9.916 0.625-14.596C197.822 176.919 197.318 168.93 196.082 161.237z" />
          <path fill="#B6382F" d="M98.915 94.931c-63.562 0-90.091 30.654-96.982 68.025 20.824 41.687 56.339 69.153 96.662 69.153 40.869 0 76.784-28.232 97.487-70.872C190.195 124.653 167.334 94.931 98.915 94.931z" />
          <path fill="#B6382F" d="M118.635 0c0.559 3.308-0.557 11.669-8.582 20.761 -3.538 4.004-3.218 3.191-4.57 5.207 -1.356 2.023-3.029 3.832-5.068 5.396 -2.076 1.537-2.77 2.442-6.062 3.158 -0.569-3.316-0.999-3.953-1.232-8.067 -0.139-2.562 0.43-6.148 1.79-8.161 1.368-2.012 2.879-4.152 6.157-6.386C103.149 10.369 115.682 5.588 118.635 0z" />
          <path fill="none" d="M95.193 185.62h-0.008c0.705 0.101 1.417 0.174 2.151 0.194C96.602 185.794 95.893 185.721 95.193 185.62z" />
          <path fill="#B6382F" d="M42.493 82.895l-0.026-0.034c0 0 0.004 0.166 0.004 0.422 -0.117 1.52-0.226 3.046-0.226 4.599 0 0.471 0.045 0.934 0.057 1.407 -0.32 5.711-1.168 14.632-3.651 24.038 -1.752 6.597-4.295 13.434-8.063 19.572 -2.735 4.472-4.901 9.551-6.639 14.786 -6.816 20.509-6.842 43.583-6.842 43.583 1.07 44.281 37.275 109.358 81.81 109.358V185.713v-44.488V31.21C69.3 31.21 45.021 53.936 42.493 82.895zM95.185 185.62h0.008c0.7 0.101 1.409 0.174 2.144 0.194C96.602 185.794 95.89 185.721 95.185 185.62z" />
          <path fill="#EA575B" d="M174.207 148.585c-1.775-5.548-4.021-10.947-6.907-15.687 -3.439-5.646-5.878-11.878-7.604-17.967 -2.954-10.397-3.847-20.393-4.137-26.365 0-0.23 0.026-0.458 0.026-0.686 0-1.032-0.102-2.044-0.155-3.063 -0.022-1.22-0.003-1.957-0.003-1.957l-0.087 0.128c-2.49-29.01-26.777-51.778-56.426-51.778v110.015 44.488 114.913c44.572 0 80.796-65.137 81.806-109.459C180.721 191.167 180.698 168.835 174.207 148.585z" />
          <path fill="#CABA9F" d="M80.822 78.55c-2.656 4.653-5.429 12.289-2.901 16.539l16.07 26.983c1.266 2.134 2.935 3.199 4.604 3.199V60.084C93.127 60.084 82.571 75.489 80.822 78.55z" />
          <path fill="#DDD2C0" d="M103.195 122.072l16.069-26.983c2.535-4.25 0.279-10.875-2.9-16.539 -1.323-2.356-13.207-18.466-17.77-18.466v65.186C100.26 125.271 101.933 124.206 103.195 122.072z" />
          <path fill="#07171B" d="M56.912 70.246c0 5.746 2.878 10.404 6.436 10.404 3.553 0 6.431-4.659 6.431-10.404 0-5.748-2.878-10.403-6.431-10.403C59.791 59.843 56.912 64.499 56.912 70.246z" />
          <path fill="#FFFFFF" d="M63.807 66.213c0 1.541-1.255 2.794-2.795 2.794 -1.545 0-2.796-1.253-2.796-2.794 0-1.544 1.251-2.794 2.796-2.794C62.552 63.419 63.807 64.668 63.807 66.213z" />
          <ellipse fill="#07171B" cx="134.481" cy="70.246" rx="6.433" ry="10.404" />
          <circle fill="#FFFFFF" cx="132.145" cy="66.213" r="2.794" />
          <path fill="#CABA9F" d="M66.542 294.861c0 3.184-2.581 5.765-5.765 5.765l0 0c-3.188 0-5.769-2.581-5.769-5.765v-10.41c0-3.184 2.581-5.764 5.769-5.764l0 0c3.184 0 5.765 2.58 5.765 5.764V294.861z" />
          <path fill="#CABA9F" d="M78.083 294.861c0 3.184-2.584 5.765-5.769 5.765l0 0c-3.187 0-5.772-2.581-5.772-5.765v-10.41c0-3.184 2.585-5.764 5.772-5.764l0 0c3.184 0 5.769 2.58 5.769 5.764V294.861z" />
          <path fill="#CABA9F" d="M89.62 294.861c0 3.184-2.581 5.765-5.769 5.765l0 0c-3.188 0-5.769-2.581-5.769-5.765v-10.41c0-3.184 2.581-5.764 5.769-5.764l0 0c3.188 0 5.769 2.58 5.769 5.764V294.861z" />
          <path fill="#DDD2C0" d="M119.743 294.861c0 3.184-2.581 5.765-5.769 5.765l0 0c-3.188 0-5.769-2.581-5.769-5.765v-10.41c0-3.184 2.581-5.764 5.769-5.764l0 0c3.188 0 5.769 2.58 5.769 5.764V294.861z" />
          <path fill="#DDD2C0" d="M131.28 294.861c0 3.184-2.581 5.765-5.765 5.765l0 0c-3.191 0-5.772-2.581-5.772-5.765v-10.41c0-3.184 2.581-5.764 5.772-5.764l0 0c3.184 0 5.765 2.58 5.765 5.764V294.861z" />
          <path fill="#DDD2C0" d="M142.821 294.861c0 3.184-2.585 5.765-5.773 5.765l0 0c-3.183 0-5.768-2.581-5.768-5.765v-10.41c0-3.184 2.585-5.764 5.768-5.764l0 0c3.188 0 5.773 2.58 5.773 5.764V294.861z" />
          <path fill="#EA575B" d="M125.907 10.497c0.565 3.304-3.541 15.808-7.905 20.605 -1.729 1.899-10.165 10.726-18.8 12.396 -0.569-3.319-1.255-8.693-0.607-11.196 0.682-2.471 2.551-6.471 9.201-9.417C117.434 18.62 121.515 16.084 125.907 10.497z" />
        </g>
        <g class="guidelines">
          <path id="minx" stroke="orange" stroke-width="5" class="guideline" />
          <path id="midmaxx" stroke="orange" stroke-dasharray="1" stroke-width="2" class="guideline" />
          <path id="miny" stroke="#9b59b6" stroke-width="5" class="guideline" />
          <path id="midmaxy" stroke="#9b59b6" stroke-dasharray="1" stroke-width="2" class="guideline" />
        </g>
        <path class="separator ruler" />
      </svg>
    </svg>
  </div>
</div>
<footer>
  Copyright &copy; <a href="http://sarasoueidan.com/" style="color:deepPink">Sara Soueidan</a>. Thank you <a style="color: deepPink" href="https://twitter.com/DmitryBaranovsk">Dmitry Baranovsky</a> for refactoring the demo's code.
</footer>
@import url(
  https://fonts.googleapis.com/css?family=Open + Sans:400italic,
  600italic,
  700italic,
  800italic,
  400,
  600,
  700,
  800
);
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html {
  background-color: #eee;
}
body {
  width: 100vw;
  min-height: 100vh;
  font-family: "Open Sans", sans-serif;
  line-height: 1.5;
  display: flex;
  flex-direction: column;
  align-items: center;
}
p {
  margin: 0.75em 0;
}

.wrapper {
  background-color: #3b3f45;
  flex: 1;
  display: flex;
  width: 100vw;
  min-height: 680px;
}

.svg-container {
  position: relative;
  width: 800px;
  height: 600px;
  margin: 1.8em 0;
}
.controls,
.sidebar {
  padding: 1em;
  color: #fff;
  width: 250px;
}
h2 {
  text-align: center;
  color: #ea575b;
  margin-bottom: 1em;
  font-size: 2.5em;
}
h3 {
  margin-bottom: 1em;
}

label {
  display: block;
  margin-top: 1.5em;
  color: #ddd;
}
.radios label {
  display: inline-block;
  margin-left: 0.25em;
}
select {
  border: 1px solid transparent;
  background-color: #eee;
  color: #1b1f25;
  border-radius: 3px;
  padding: 0.5em;
  margin: 0.5em 0;
  width: 100%;
  cursor: pointer;
  font-family: "Open Sans", sans-serif;
  font-weight: 500;
}
select option:nth-of-type(even) {
  background-color: #fff;
}
.input {
  width: 48.5%;
  display: inline-block;
}
.input input {
  max-width: 50px;
  font-size: 1.05em;
  font-weight: 400;
}
.outer {
  overflow: scroll;
}
input {
  background-color: #eee;
  padding: 0.1em;
  border: 2px solid transparent;
  color: #1b1f25;
  border-radius: 3px;
  max-width: 100%;
  margin-top: 0.5em;
  display: inline-block;
  font-family: "Open Sans", sans-serif;
  font-weight: 600;
}
input[type="text"]:required {
  border: 2px solid #ff3e5a;
}
output {
  width: 40px;
  color: #2cb2ba;
}
input[type="range"] {
  display: inline-block;
  margin-bottom: 1em;
  margin-right: 0.2em;
  width: 135px;
  background: none !important;

  -webkit-appearance: none;
  -moz-appearance: none;
}

input:focus {
  border: 2px solid #2cb2ba;
  outline: none;
}
input[type="range"]::-webkit-slider-runnable-track {
  width: 135px;
  height: 5px;
  background-color: #eee;
  border: none;
  border-radius: 3px;
}
input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  border: none;
  height: 20px;
  width: 20px;
  border-radius: 50%;
  background: #2cb2ba;
  margin-top: -8px;
}

input[type="range"]::-moz-range-track {
  width: 135px;
  height: 5px;
  background-color: #eee;
  border: none;
  border-radius: 3px;
}
input[type="range"]::-moz-range-thumb {
  border: none;
  height: 20px;
  width: 20px;
  border-radius: 50%;
  background: #2cb2ba;
}

input[type="range"]::-ms-track {
  width: 135px;
  height: 20px;
  background-color: #eee;
  border: none;
  border-radius: 10px;
  color: transparent;
}

input[type="range"]::-ms-thumb {
  border: none;
  height: 20px;
  width: 20px;
  border-radius: 50%;
  background: #2cb2ba;
}
fieldset {
  padding: 0 1em 1em;
  margin-bottom: 1em;
  border-radius: 3px;
}
legend {
  color: #fff;
}
svg {
  position: absolute;
}
svg.outer {
  background-color: white;
  border: 1px solid #ddd;
}
.inner .separator {
  stroke: #4cd2da;
  stroke-width: 2;
}
.outer > .separator {
  stroke: #aaa;
  stroke-width: 1;
}
.inner .labels {
  fill: #4cd2da;
  stroke: #2cb2ba;
  stroke-width: 1;
}
.outer > .labels {
  fill: #ccc;
}

.cheatsheet {
  background-color: white;
  padding: 1em;
  margin: 1em auto;
  width: 1300px;
}

.plain {
  margin-top: 1em;
  color: #0077aa;
  font-size: 0.9em;
}
dl {
  margin: 1em 0;
}
dt {
  font-weight: bolder;
  margin: 0.5em 0;
}
dd {
  padding-left: 1em;
}

.guide-trigger {
  background-color: #2cb2ba;
  color: white;
  padding: 0.5em 1em;
  border-radius: 5px;
  border: none;
  font-size: 1.5em;
  color: #eee;
  font-family: "Open Sans", sans-serif;
  text-align: center;
  display: block;
  width: 100%;
  cursor: pointer;
  margin-bottom: 14em;
  -webkit-transition: background-color 0.2s linear;
  transition: background-color 0.2s linear;
}
.guide-trigger:hover {
  background-color: transparent;
}
button {
  border: 2px solid transparent;
}
button:active,
button:focus {
  border: 2px solid #2cb2ba;
  outline: none;
}
footer {
  text-align: center;
}
header {
  width: 1300px;
  background-color: white;
  padding: 0.5em 1em;
  margin: 0 auto 1em;
}
header a {
  color: #bb4347;
  font-weight: bold;
}
.ad-wrapper {
  background-color: #f5f5f5;
  border: 1px solid #eee;
  padding-bottom: 0.5em;
  margin-bottom: 2em;
}
.ad-wrapper a {
  border-bottom: none !important;
  margin: 0 auto;
}
.ad-wrapper a:hover {
  border-bottom: none !important;
}
.one .bsa_it_ad {
  font-family: inherit;
  padding: 0.5em 0.5em 0 0.5em;
  background: transparent;
  margin: 0;
  border: none !important;
  text-align: center;
  width: 100%;
  color: #333;
}

.one .bsa_it_p {
  display: none !important;
  clear: both;
}
.one .bsa_it_ad .bsa_it_i {
  padding: 0;
  margin: 5px auto !important;
  display: inline-block;
  float: none !important;
}
.one .bsa_it_ad .bsa_it_i img {
  padding: 0;
  border: none;
}
.one .bsa_it_ad .bsa_it_t {
  padding: 6px 0;
  margin-top: 10px;
}
.one .bsa_it_ad .bsa_it_d {
  padding: 0;
  font-size: 11px;
  color: #333;
}
.one .bsa_it_p {
  display: none;
}
#bsap_aplink,
#bsap_aplink:hover {
  display: block;
  font-size: 10px;
  margin: 0 1em 0;
  text-align: center;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: grey;
  border-bottom: none;
}

footer {
  padding: 1em;
  background-color: rgba(0, 0, 0, 0.8);
  color: #fff;
  width: 100vw;
}
var outerSVG = document.querySelector(".outer");
var innerSVG = document.querySelector(".inner");
var svgns = "http://www.w3.org/2000/svg";

function makeRulers(svgElement, distance, units) {
  var vb = svgElement.getAttribute("viewBox").split(" "),
    svgWidth = vb[2],
    nbOfWSeparators = svgWidth / distance,
    nbOfWUnits = svgWidth / units,
    svgHeight = vb[3],
    nbOfHSeparators = svgHeight / distance,
    nbOfHUnits = svgHeight / units,
    pathstring = "",
    path = svgElement.querySelectorAll(".ruler"),
    i,
    g = document.createElementNS(svgns, "g");

  for (i = 0; i < path.length; i++) {
    if (path[i].parentNode == svgElement) {
      path = path[i];
      break;
    }
  }
  for (i = 0; i <= nbOfWUnits; i++) {
    pathstring += "M" + i * units + ",0v15";
  }
  for (i = 0; i <= nbOfWSeparators; i++) {
    pathstring += "M" + i * distance + ",0v30";
    var value = document.createElementNS(svgns, "text");
    value.setAttribute("x", i * distance - 15);
    value.setAttribute("y", 43);
    value.textContent = i * distance;
    g.appendChild(value);
  }
  for (i = 0; i <= nbOfHUnits; i++) {
    pathstring += "M0," + i * units + "h15";
  }

  for (i = 0; i <= nbOfHSeparators; i++) {
    pathstring += "M0," + i * distance + "h30";
    var value = document.createElementNS(svgns, "text");
    value.setAttribute("x", 30);
    value.setAttribute("y", i * distance + 5);
    value.textContent = i * distance;
    g.appendChild(value);
  }

  g.setAttribute("class", "labels");
  g.setAttribute("font-size", "16px");
  path.setAttribute("d", pathstring);
  svgElement.appendChild(g);
}

makeRulers(outerSVG, 100, 10);
makeRulers(innerSVG, 100, 10);

// preserveAspectRatio Controls
var aligmentOptions = document.querySelector(".preserveAspectRatio-options"),
  meetOrSlice = "meet",
  alignment = "xMidYMid",
  sliceOption = document.getElementById("slice"),
  meetOption = document.getElementById("meet");

sliceOption.onclick = function () {
  if (this.checked) meetOrSlice = "slice";
  setPreserveAspectRatio();
};
meetOption.onclick = function () {
  if (this.checked) meetOrSlice = "meet";
  setPreserveAspectRatio();
};

aligmentOptions.onchange = function () {
  alignment = this.options[this.selectedIndex].value;
  setPreserveAspectRatio();
};

function setPreserveAspectRatio() {
  innerSVG.setAttribute("preserveAspectRatio", alignment + " " + meetOrSlice);
}

var vbGuidelinesVisibility = document.getElementById("guidelines-visibility");
//when the checkbox is clicked
vbGuidelinesVisibility.onclick = function () {
  //get all the currently available guidelines
  var guidelines = document.querySelectorAll(".guidelines");
  if (this.checked) {
    guidelines[0].style.display = "";
    guidelines[1].style.display = "";
    drawXandYLines();
  } else {
    guidelines[0].style.display = "none";
    guidelines[1].style.display = "none";
  }
};
//viewBox input Controls
var vbMinX = document.getElementById("min-x"),
  vbMinY = document.getElementById("min-y"),
  vbWidth = document.getElementById("viewbox-width"),
  vbHeight = document.getElementById("viewbox-height");

var vbMinXvalue = vbMinX.value,
  vbMinYvalue = vbMinY.value,
  vbWidthValue = vbWidth.value,
  vbHeightValue = vbHeight.value;

vbMinX.addEventListener("blur", resetInput, false);
vbMinY.addEventListener("blur", resetInput, false);

function resetInput() {
  if (!this.value) this.value = 0;
  setViewboxAttributeValue();
}

vbMinX.addEventListener("change", vbMinXHandler, false);
vbMinX.addEventListener("input", vbMinXHandler, false);

function vbMinXHandler() {
  setViewboxAttributeValue();
  updateRulers();

  vbMinXvalue = this.value;
  if (vbGuidelinesVisibility.checked) drawXandYLines();
}

vbMinY.addEventListener("change", vbMinYHandler, false);
vbMinY.addEventListener("input", vbMinYHandler, false);

function vbMinYHandler() {
  setViewboxAttributeValue();
  updateRulers();

  vbMinYvalue = this.value;
  if (vbGuidelinesVisibility.checked) drawXandYLines();
}

vbWidth.addEventListener("change", vbWidthHandler, false);
vbWidth.addEventListener("input", vbWidthHandler, false);

function vbWidthHandler() {
  updateRangeOutput(this);
  setViewboxAttributeValue();
  updateRulers();
  vbWidthValue = this.value;
  if (vbGuidelinesVisibility.checked) drawXandYLines();
}

vbHeight.addEventListener("change", vbHeightHandler, false);
vbHeight.addEventListener("input", vbHeightHandler, false);

function vbHeightHandler() {
  updateRangeOutput(this);
  setViewboxAttributeValue();
  updateRulers();
  vbHeightValue = this.value;
  if (vbGuidelinesVisibility.checked) drawXandYLines();
}

var midlines = document.getElementById("midlines"),
  minx = document.getElementById("minx"),
  midmaxx = document.getElementById("midmaxx"),
  miny = document.getElementById("miny"),
  midmaxy = document.getElementById("midmaxy");
function drawXandYLines() {
  var vb = outerSVG.getAttribute("viewBox").split(" "),
    svgWidth = vb[2],
    svgHeight = vb[3],
    midx = +vbMinXvalue + vbWidthValue / 2,
    maxx = +vbMinXvalue + +vbWidthValue,
    midy = +vbMinYvalue + vbHeightValue / 2,
    maxy = +vbMinYvalue + +vbHeightValue;
  midlines.setAttribute(
    "d",
    "M" +
      [svgWidth / 2, 0, svgWidth / 2, svgHeight] +
      "M" +
      [0, svgHeight / 2, svgWidth, svgHeight / 2]
  );
  minx.setAttribute("d", "M" + [vbMinXvalue, 0, vbMinXvalue, vbHeightValue]);
  midmaxx.setAttribute(
    "d",
    "M" + [midx, 0, midx, vbHeightValue] + "M" + [maxx, 0, maxx, vbHeightValue]
  );
  miny.setAttribute("d", "M" + [0, vbMinYvalue, vbWidthValue, vbMinYvalue]);
  midmaxy.setAttribute(
    "d",
    "M" + [0, midy, vbWidthValue, midy] + "M" + [0, maxy, vbWidthValue, maxy]
  );
}

function updateRangeOutput(self) {
  self.nextSibling.textContent = self.value;
}

function updateRulers() {
  //remove all previously added text
  var labels = innerSVG.querySelector(".labels");
  labels.parentNode.removeChild(labels);
  //redraw lines according to new viewBox width and height values
  makeRulers(innerSVG, 100, 10);
}
function setViewboxAttributeValue() {
  var viewBoxValue =
    vbMinX.value +
    " " +
    vbMinY.value +
    " " +
    vbWidth.value +
    " " +
    vbHeight.value;
  innerSVG.setAttribute("viewBox", viewBoxValue);
}

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.