Search code examples
cssd3.jssvgmedia-queries

Keep SVG centred while using media queries


I have a page where I've drawn several SVGs using d3.js. While building up the SVG graphics, I specified fixed heights & widths (which represent the max heights/widths that I wanted). This worked fine and with the CSS, everything was centred on the page, as I wanted. However, I also wanted the SVGs to scale when the screen width was below the fixed width.

To tackle the scaling issue, I removed the height and width attributes from the SVG and instead used viewBox (giving 0 0 <width> <height>, and preserveAspectRatio. Cool - now everything scales to the full width of the page, i.e. like width = 100% in CSS.

So then I added my media queries. And they work - the max width of the SVGs is preserved, and below that they scale.
But: as soon as the MQs are active, the SVGs and their containing divs are aligned left. I've spent a long time fiddling with the CSS and also googling around and I didn't manage to solve it.

Here's my code (some things slightly simplified). Can anyone help?

HTML:

<div class="overall-container">

<div class="svg-container">
  <h2>Smaller SVG</h2>
  <svg id="ebu-cb"
      version="1.1"
      baseProfile="full"
      viewBox="0 0 768 576"
      preserveAspectRatio="xMinYMin meet"
      xmlns="http://www.w3.org/2000/svg">
  </svg>
</div>  

<div class="lg-svg-container">
  <h2>Larger SVG</h2>
  <svg id="smpte-cb-hd"
      version="1.1"
      baseProfile="full"
      viewBox="0 0 1280 720"
      preserveAspectRatio="xMinYMin meet"
      shape-rendering="crispEdges"
      xmlns="http://www.w3.org/2000/svg">
  </svg>
</div>

</div>

CSS:

body {
  text-align: center;
}

svg {
  border: 2px solid black;
  margin: 0 auto;
}

div {
  margin-bottom: 3rem;
}

Media query: (works, but suddenly the divs with the SVGs are left aligned??? No difference if I add the media query inline of the SVG.)

@media only screen and (min-width: 750px) {
  .svg-container {
    max-width: 768px;
  }
  .lg-svg-container {
    max-width: 1280px;
  }

I added all sorts of CSS options for central alignment, but I couldn't budge the placement :( I feel that I'm missing the obvious here (or maybe I should have a slightly different setup?) and I would really appreciate some help.

Note: the SVGs are generated in my JS file. I'm drawing them with the widths and heights specified in the viewBox attributes for each.


Solution

  • Explanation:

    The svg containers you have were never center aligned in the first place.

    When the media queries were inactive ie. when you did not give a max-width to the containers, they only looked like they were centered because they took 100% width but as a matter of fact they were never centered.

    You could notice that only when adding a max-width and reducing the width of the containers.

    Reason and Solution:

    You actually never gave it any property to center align. You need to give it now like so by adding margin: auto property:

    @media only screen and (min-width: 750px) {
      .svg-container {
        max-width: 768px;
        margin: auto;
      }
      .lg-svg-container {
        max-width: 1280px;
        margin: auto;
      }
    }