Reputation: 111
I have a grid layout that scales in size in the main content area of a page. which works well enough, currenly its set to 30x30 cells just for testing though this will change depending on page settings. My CSS for this is:
#gameBoard {
height: 100%;
width: 100%;
aspect-ratio: 1 / 1;
display: grid;
background: #101020;
grid-template: repeat(30, 1fr) / repeat(30, 1fr);
padding: 0;
}
#gameBoard .mscell {
cursor: pointer;
position: relative;
background-color: #d1d1d1;
border-width: 3px;
border-style: solid;
border-color: white #9e9e9e #9e9e9e white;
}
#gameBoard .mscell:hover {
background-color: #eaeaea;
}
#gameBoard .mscell.revealed {
cursor: pointer;
position: relative;
background-color: #cacaca;
border: 1px solid #aeaeae;
}
#gameBoard .mscell.boom {
background-color: red;
}
#gameBoard .mscell svg {
border: 0;
padding: 0;
margin: 0;
/* width: 100%;
height: 100%; */
}
My problem is that I want to add content to certain cells like a color coded number or an image and have this number scale to the size of the cell (which will vary both with page setting and browser window size)... and figured the most simple way to do this would be with SVG... Though at this point I am very open to other options!
I created a file for the SVG numbers:
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<symbol id="num_1" viewBox="0 0 24 24" fill="none">
<path d="M12 20V4L9 7" stroke="#292929" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
</symbol>
<symbol id="num_2" viewBox="0 0 24 24" fill="none">
<path d="M8 8C8 6.97631 8.39052 5.95262 9.17157 5.17157C10.7337 3.60947 13.2663 3.60947 14.8284 5.17157C16.3905 6.73366 16.3905 9.26632 14.8284 10.8284L9.17157 16.4853C8.42143 17.2354 8 18.2528 8 19.3137L8 20L16 20" stroke="#292929" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
</symbol>
<symbol id="num_3" viewBox="0 0 24 24" fill="none">
<path d="M8 19.0004C8.83566 19.6281 9.87439 20 11 20C13.7614 20 16 17.7614 16 15C16 12.2386 13.7614 10 11 10L16 4H8" stroke="#292929" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
</symbol>
<symbol id="num_4" viewBox="0 0 24 24" fill="none">
<path d="M10 4L8.47845 11.6078C8.23093 12.8453 9.17752 14 10.4396 14H16M16 14V8M16 14V20" stroke="#292929" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
</symbol>
<symbol id="num_5" viewBox="0 0 24 24" fill="none">
<path d="M8 19.0004C8.83566 19.6281 9.87439 20 11 20C13.7614 20 16 17.7614 16 15C16 12.2386 13.7614 10 11 10C9.87439 10 8.83566 10.3719 8 10.9996L9 4H16" stroke="#292929" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
</symbol>
<symbol id="num_6" viewBox="0 0 24 24" fill="none">
<path d="M13 4L7.77313 12.3279M17 15C17 17.7614 14.7614 20 12 20C9.23858 20 7 17.7614 7 15C7 12.2386 9.23858 10 12 10C14.7614 10 17 12.2386 17 15Z" stroke="#292929" stroke-width="2.5" stroke-linecap="round"/>
</symbol>
<symbol id="num_7" viewBox="0 0 24 24" fill="none">
<path d="M8 4H16L10 20" stroke="#292929" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
</symbol>
<symbol id="num_8" viewBox="0 0 24 24" fill="none">
<circle cx="12" cy="15" r="5" stroke="#292929" stroke-width="2.5" stroke-linejoin="round"/>
<circle cx="12" cy="7" r="3" stroke="#292929" stroke-width="2.5" stroke-linejoin="round"/>
</symbol>
<symbol id="num_9" viewBox="0 0 24 24" fill="none">
<path d="M11 20L16.2269 11.6721M7 9C7 6.23858 9.23858 4 12 4C14.7614 4 17 6.23858 17 9C17 11.7614 14.7614 14 12 14C9.23858 14 7 11.7614 7 9Z" stroke="#292929" stroke-width="2.5" stroke-linecap="round"/>
</symbol>
<symbol id="num_0" viewBox="0 0 24 24" fill="none">
<path d="M12 20C14.7614 20 17 17.7614 17 15V9C17 6.23858 14.7614 4 12 4C9.23858 4 7 6.23858 7 9V15C7 17.7614 9.23858 20 12 20Z" stroke="#292929" stroke-width="2.5" stroke-linejoin="round"/>
</symbol>
</svg>
...and am writing them into the appropriate cell as needed with:
c.innerHTML=`<svg class="msNum"><use href="/img/icons.svg#num_${cv}"></use></svg>`
I tried doing this with width & height set in css for the svg to 100% and for some reason the cells and and any svg they contain size to 300x300px... which is a size that doesn't seem to relate to anything else, with the nested use element redering at 37.5x200 for number one.
Removing the width and height from css, the cells still resize to 300x300, but with the svg sized at 300x150 with the image rendered half size at the same aspect ratio, the use element now sizes to 18.75x100 according to the dev console.
On the other hand if I set the height and width of the SVG in my script, effectively hardcoding it (I chose 13 here just because my cells were rendering just over 13px square) using:
c.innerHTML=`<svg class="msNum" width="13" height="13"><use href="/img/icons.svg#num_${cv}"></use></svg>`
Then the cells again resize after content is added changing from approx 16.16x16.16 to 16.16x24, gaining height even though the svg is sized at 13x13 according to the console with no border, margin or padding, centered vertically in the cell. So the grid cells get taller even though the content is smaller! (This changes to the grid cells becoming 24x29 with the svg sized to 22x27 if I reintroduce the 100% height and width sizing in the css...)
So basically I am making a total mess of it... and something odd is happening with the sizing I don't understand.
How can I get the SVG to scale to 100% of the cell (or smaller and centered) size without changing the size of the cell and without hardcoding all the sizes? I do really want to avoid hardcoding the sizes, to keep the grid as large as possible in whatever browser window.
Upvotes: 0
Views: 96
Reputation: 76
your code for inserting the SVG should look like this:
c.innerHTML = `<svg class="msNum" viewBox="0 0 24 24"><use href="/img/icons.svg#num_${cv}"></use></svg>`;
Setting the SVG to display: block
ensures that any extra space around the SVG is removed and it behaves like a block-level element, fixing the height and display issues you were encountering.
Updated CSS for SVG:
#gameBoard .mscell svg {
display: block;
width: 100%; /* Ensures the SVG scales with the cell */
height: 100%;
}
Upvotes: 0
Reputation: 22365
Some tricks you can use :
const
board = document.querySelector('#gameBoard')
, htmlFrag = htmlCod => new Range().createContextualFragment(htmlCod)
, rows = 7
, cols = 5
, numCells = rows * cols
, numMines = 4
, cellList = []
;
board.style.setProperty('--nb_Rows', rows);
board.style.setProperty('--nb_Cols', cols);
for (let i = 0; i < numCells; i++)
{
let cell = board.appendChild(document.createElement('div'));
cell.id = `cell_${i}`;
}
for (let n = 1; n<11; n++)
{
board.querySelector(`#cell_${n*2}`).append(htmlFrag(`<svg viewBox="0 0 24 24"><use xlink:href="#num_${n%10}"/></svg>`));
}
#gameBoard {
--nb_Rows : 2;
--nb_Cols : 2;
width : 100%;
display : grid;
background : #101020;
grid-template : repeat(var(--nb_Cols), 1fr) / repeat(var(--nb_Rows), 1fr);
padding : 0;
}
#gameBoard>div {
aspect-ratio : 1 / 1;
cursor : pointer;
position : relative;
background-color : #d1d1d1;
border-width : 3px;
border-style : solid;
border-color : white #9e9e9e #9e9e9e white;
font-size : 0;
}
#gameBoard>div:hover {
background-color : #eaeaea;
}
#gameBoard>div:has(svg) {
border : none;
background-color : whitesmoke;
}
svg {
fill : none;
}
symbol * {
stroke-width : 2.5;
stroke-linecap : round;
stroke-linejoin : round;
}
.noDisplay { display:none; }
<div id="gameBoard"></div>
<svg class="noDisplay">
<symbol id="num_1" viewBox="0 0 24 24"><path d="M12 20V4L9 7" stroke="#292929"/></symbol>
<symbol id="num_2" viewBox="0 0 24 24"><path d="M8 8C8 6.97631 8.39052 5.95262 9.17157 5.17157C10.7337 3.60947 13.2663 3.60947 14.8284 5.17157C16.3905 6.73366 16.3905 9.26632 14.8284 10.8284L9.17157 16.4853C8.42143 17.2354 8 18.2528 8 19.3137L8 20L16 20" stroke="#292929"/></symbol>
<symbol id="num_3" viewBox="0 0 24 24"><path d="M8 19.0004C8.83566 19.6281 9.87439 20 11 20C13.7614 20 16 17.7614 16 15C16 12.2386 13.7614 10 11 10L16 4H8" stroke="#292929" /></symbol>
<symbol id="num_4" viewBox="0 0 24 24"><path d="M10 4L8.47845 11.6078C8.23093 12.8453 9.17752 14 10.4396 14H16M16 14V8M16 14V20" stroke="#292929"/></symbol>
<symbol id="num_5" viewBox="0 0 24 24"><path d="M8 19.0004C8.83566 19.6281 9.87439 20 11 20C13.7614 20 16 17.7614 16 15C16 12.2386 13.7614 10 11 10C9.87439 10 8.83566 10.3719 8 10.9996L9 4H16"stroke="#292929"/></symbol>
<symbol id="num_6" viewBox="0 0 24 24"><path d="M13 4L7.77313 12.3279M17 15C17 17.7614 14.7614 20 12 20C9.23858 20 7 17.7614 7 15C7 12.2386 9.23858 10 12 10C14.7614 10 17 12.2386 17 15Z" stroke="#292929" /></symbol>
<symbol id="num_7" viewBox="0 0 24 24"><path d="M8 4H16L10 20" stroke="#292929"/></symbol>
<symbol id="num_8" viewBox="0 0 24 24"><circle cx="12" cy="15" r="5" stroke="#292929"/><circle cx="12" cy="7" r="3" stroke="#292929"/></symbol>
<symbol id="num_9" viewBox="0 0 24 24"><path d="M11 20L16.2269 11.6721M7 9C7 6.23858 9.23858 4 12 4C14.7614 4 17 6.23858 17 9C17 11.7614 14.7614 14 12 14C9.23858 14 7 11.7614 7 9Z" stroke="#292929"/></symbol>
<symbol id="num_0" viewBox="0 0 24 24"><path d="M12 20C14.7614 20 17 17.7614 17 15V9C17 6.23858 14.7614 4 12 4C9.23858 4 7 6.23858 7 9V15C7 17.7614 9.23858 20 12 20Z" stroke="#292929"/></symbol>
</svg>
Upvotes: 1
Reputation: 111
Ok so the answer, courtesy of herrstrietzel was to add the viewbox information to the inserted code, this allowed the SVG to scale with the div properly, as (he said) the viewbox information in not copied from the svg definition.
I also had an additional issue that was resolved by adding display: block;
to my CSS for the SVG, this removed the additional height added around the SVG and removed the remaining display issues. (this was also the issue when hardcoding the width and height).
Upvotes: 0