Search code examples
htmlcsscss-gridcentering

Centering SVGs in a grid cell


I see how one can position an item inside a grid cell such that it appears in any of the four corners. To summarize, the cell itself receives the styling position: relative;, and each of the items gets styled as position: absolute;, top: 0;, and left: 0;, replacing top and left as appropriate.

Here I'd like to style three SVG images at the center left, center-center, and the center-right of a grid cell.

Using the following three stylings

/* center left */
vertical-align: middle;
left: 0;

/* center-center */
text-align: center;
vertical-align: middle;

/* center right */
vertical-align: middle;
right: 0;

is ineffective. Why?

body { margin: 40px; }
.header {
    grid-area: header;
    height: 100px;
    position: relative;
    background-color: #999;
}
.content {
    grid-area: content;
    height: 200px;
}
.wrapper {
    display: grid;
    grid-gap: 10px;
    grid-template-columns: 800px;
    grid-template-areas:
        "header"
        "content";
    background-color: #fff;
    color: #444;
}
.box {
    background-color: #444;
    color: #fff;
    border-radius: 5px;
    padding: 50px;
    font-size: 150%;
}

.centerleft {
    vertical-align: middle;
    left: 0;
}
.centercenter {
    text-align: center;
    vertical-align: middle;
}
.centerright {
    vertical-align: middle;
    right: 0;
}
.circle {
    height: 50px;
    stroke: black; fill: cyan;
}
<div class="wrapper">
    <div class="box header">
        <svg xmlns="http://www.w3.org/2000/svg"
            class="centerleft circle"
            viewBox="0 0 100 100">
            <circle class="mycircle" cx="50" cy="50" r="45"/>
        </svg>
        <svg xmlns="http://www.w3.org/2000/svg"
            class="centercenter circle"
            viewBox="0 0 100 100">
            <circle class="mycircle" cx="50" cy="50" r="45"/>
        </svg>
        <svg xmlns="http://www.w3.org/2000/svg"
            class="centerright circle"
            viewBox="0 0 100 100">
            <circle class="mycircle" cx="50" cy="50" r="45"/>
        </svg>
    </div>
    <div class="box content">
        Content
    </div>
</div>

Since the same cell has three items with different stylings, variations on

grid-item {
    display: flex;
    align-items: center;
    justify-content: center;
}

as described here did not help.


Solution

  • This can be easily achieved by using flex. Added style to box selector

    body { margin: 40px; }
    .header {
        grid-area: header;
        height: 100px;
        position: relative;
        background-color: #999;
    }
    .content {
        grid-area: content;
        height: 200px;
    }
    .wrapper {
        display: grid;
        grid-gap: 10px;
        grid-template-columns: 800px;
        grid-template-areas:
            "header"
            "content";
        background-color: #fff;
        color: #444;
    }
    .box {
        background-color: #444;
        color: #fff;
        border-radius: 5px;
        padding: 50px;
        font-size: 150%;
        display: flex;
        display: -webkit-flex;
        justify-content: space-between;
        -webkit-justify-content: space-between;
    }
    
    .centerleft {
        vertical-align: middle;
        left: 0;
    }
    .centercenter {
        text-align: center;
        vertical-align: middle;
    }
    .centerright {
        vertical-align: middle;
        right: 0;
    }
    .circle {
        height: 50px;
        stroke: black; fill: cyan;
    }
    <div class="wrapper">
        <div class="box header">
            <svg xmlns="http://www.w3.org/2000/svg"
                class="centerleft circle"
                viewBox="0 0 100 100">
                <circle class="mycircle" cx="50" cy="50" r="45"/>
            </svg>
            <svg xmlns="http://www.w3.org/2000/svg"
                class="centercenter circle"
                viewBox="0 0 100 100">
                <circle class="mycircle" cx="50" cy="50" r="45"/>
            </svg>
            <svg xmlns="http://www.w3.org/2000/svg"
                class="centerright circle"
                viewBox="0 0 100 100">
                <circle class="mycircle" cx="50" cy="50" r="45"/>
            </svg>
        </div>
        <div class="box content">
            Content
        </div>
    </div>