Background:
Building a Memory tile web app as a learning tool for Web Development. Had it initially built and now working on responsive design features. I want the individual tiles laid out on a 6 x 5 board to scale down with smaller screen sizes, in the future I plan on going mobile first and scaling up (live and learn).
Problem:
I was having a problem keeping the 1:1 aspect ratio of the individual tiles as screen size decreased but found a solution to that problem here
The problem that remains is that the tiles/cards/squares use a background-image for the graphic representation of the back of the card and then once clicked on the image to be paired/matched. When I decrease the size of the browser window the background image does not scale, but rather the right and bottom sides are cropped off with the upper left corner being the origin. I've tried numerous attempts to change
background-position: center center;
background-size: cover/contain;
But nothing changes the cropping behavior. This holds true in chrome,FF,Opera web browsers. After an exhaustive search I have found no answers. I began to suspect/theorize that it might have something to do with these elements being inserted into the DOM from JQuery.
As an experiment I added 30 div elements (6 x 5) with the same background-image set in css class="tile" but this time the html elements were hard coded into memory.html vs. inserted into the DOM with JQuery. The background image and square/tile all scale perfectly. This seems to suggest that I have the CSS right, but somehow this image scaling behavior does not work when inserted into the DOM from JQuery. Hope someone else has some insight into this as I've been spinning my wheels for some time now. I'll post my code for reference
$('document').ready(function(){
$('#shuffle').click(memory.shuffle);
$('#deck').change(memory.shuffle);
});
var memory = (function() {
var arrays = {
linux: ['assets/img/linux/linuxDebian', 'assets/img/linux/linuxDebian',
'assets/img/linux/linuxArch', 'assets/img/linux/linuxArch',
'assets/img/linux/linuxUbuntu', 'assets/img/linux/linuxUbuntu',
'assets/img/linux/linuxOpenSuse', 'assets/img/linux/linuxOpenSuse',
'assets/img/linux/linuxNetrunner', 'assets/img/linux/linuxNetrunner',
'assets/img/linux/linuxSliTaz', 'assets/img/linux/linuxSliTaz',
'assets/img/linux/linuxAntiX', 'assets/img/linux/linuxAntiX',
'assets/img/linux/linuxMint', 'assets/img/linux/linuxMint',
'assets/img/linux/linuxKali', 'assets/img/linux/linuxKali',
'assets/img/linux/linuxFreeBsd', 'assets/img/linux/linuxFreeBsd',
'assets/img/linux/linuxGentoo', 'assets/img/linux/linuxGentoo',
'assets/img/linux/linuxRedHat', 'assets/img/linux/linuxRedHat',
'assets/img/linux/linuxBodhi', 'assets/img/linux/linuxBodhi',
'assets/img/linux/linuxCentOS', 'assets/img/linux/linuxCentOS',
'assets/img/linux/linuxElementary', 'assets/img/linux/linuxElementary'
],
seinfeld: ['assets/img/seinfeld/seinfeldBoss', 'assets/img/seinfeld/seinfeldBoss',
'assets/img/seinfeld/seinfeldCastanzaMom', 'assets/img/seinfeld/seinfeldCastanzaMom',
'assets/img/seinfeld/seinfeldCastanza', 'assets/img/seinfeld/seinfeldCastanza',
'assets/img/seinfeld/seinfeldCosmo', 'assets/img/seinfeld/seinfeldCosmo',
'assets/img/seinfeld/seinfeldElaine', 'assets/img/seinfeld/seinfeldElaine',
'assets/img/seinfeld/seinfeldGeorge', 'assets/img/seinfeld/seinfeldGeorge',
'assets/img/seinfeld/seinfeldGroup', 'assets/img/seinfeld/seinfeldGroup',
'assets/img/seinfeld/seinfeldJerry', 'assets/img/seinfeld/seinfeldJerry',
'assets/img/seinfeld/seinfeldNewman', 'assets/img/seinfeld/seinfeldNewman',
'assets/img/seinfeld/seinfeldNewman2', 'assets/img/seinfeld/seinfeldNewman2',
'assets/img/seinfeld/seinfeldSoupNazi', 'assets/img/seinfeld/seinfeldSoupNazi',
'assets/img/seinfeld/seinfeldSteinbrenner', 'assets/img/seinfeld/seinfeldSteinbrenner',
'assets/img/seinfeld/seinfeldUncleLeo', 'assets/img/seinfeld/seinfeldUncleLeo',
'assets/img/seinfeld/seinfeldDecider', 'assets/img/seinfeld/seinfeldDecider',
'assets/img/seinfeld/seinfeldBabu', 'assets/img/seinfeld/seinfeldBabu'
],
starTrek: ['assets/img/starTrek/starTrekWorf', 'assets/img/starTrek/starTrekWorf',
'assets/img/starTrek/starTrekCisco', 'assets/img/starTrek/starTrekCisco',
'assets/img/starTrek/starTrekData', 'assets/img/starTrek/starTrekData',
'assets/img/starTrek/starTrekKirk', 'assets/img/starTrek/starTrekKirk',
'assets/img/starTrek/starTrekSpock', 'assets/img/starTrek/starTrekSpock',
'assets/img/starTrek/starTrekQuark', 'assets/img/starTrek/starTrekQuark',
'assets/img/starTrek/starTrekKira', 'assets/img/starTrek/starTrekKira',
'assets/img/starTrek/starTrekGarok', 'assets/img/starTrek/starTrekGarok',
'assets/img/starTrek/starTrekDax', 'assets/img/starTrek/starTrekDax',
'assets/img/starTrek/starTrekGeordi', 'assets/img/starTrek/starTrekGeordi',
'assets/img/starTrek/starTrekKhan', 'assets/img/starTrek/starTrekKhan',
'assets/img/starTrek/starTrekOdo', 'assets/img/starTrek/starTrekOdo',
'assets/img/starTrek/starTrekBorgQueen', 'assets/img/starTrek/starTrekBorgQueen',
'assets/img/starTrek/starTrekGalDukat', 'assets/img/starTrek/starTrekGalDukat',
'assets/img/starTrek/starTrekSevenOfNine', 'assets/img/starTrek/starTrekSevenOfNine'
]
};//end arrays
/*Global Variables*/
var card_matched = [];
var memory_values = [];
var memory_card_id = [];
var card_matched = [];
var card_previous = [];
var cards_flipped = 0;
var userAttempt = 0;
var cards_flipped = 0;
var gamesPlayed = 0;
var userSelect = "";
var deck = "";
var cardBackGround = "";
/* Randomly sort an array by calculating a value within array
* range and then swaps values by randomly calculated value
*/
Array.prototype.randomizeArray = function() {
var i = this.length;
var j = 0;
var temp = "";
while (--i > 0) {
j = Math.floor(Math.random() * (i + 1));
temp = this[j];
this[j] = this[i];
this[i] = temp;
} // end while
} //end randomizeArray
/* Checks which deck the user has selected to play*/
function deckSelected() {
deck = $('#deck option:selected').val();
} //end deckSelected
/* Sets the deck background to user selected deck*/
function changeBackground() {
switch(deck) {
case 'linux':
$('[id^=card_]').css('background', 'url(assets/img/linux/linux_bg.jpg)');
cardBackGround = 'assets/img/linux/linux_bg.jpg';
break;
case 'seinfeld':
$('[id^=card_]').css('background', 'url(assets/img/seinfeld/seinfeldLogo.jpg)');
cardBackGround = 'assets/img/seinfeld/seinfeldLogo.jpg';
break;
case 'starTrek':
$('[id^=card_]').css('background', 'url(assets/img/starTrek/starTrekLogo.jpg)');
cardBackGround = 'assets/img/starTrek/starTrekLogo.jpg';
break;
} // End Switch
} // End changeBackGround
/*Creates the cards for the memory game after randomizing array selected by user putting each card into its own <div>*/
function shuffle() {
var output = '';
card_previous = [];
card_matched = [];
cards_flipped = 0;
userAttempt = 0;
//call deckSelected to find which deck to shuffle/create
deckSelected();
//shuffle the deck deckSelected returned
arrays[deck].randomizeArray();
/*Now that cards are randomized within the array create the cards for the
game board giving each a unique id and passing (cardId,val) onClick*/
for (var i = 0; i < arrays[deck].length; i++) {
output += '<div class="tile" id="card_' + i + '" onclick="memory.flipCard(this,\'' + arrays[deck][i] + '\')"></div>';
}
//put the newly created cards into the gameboard
document.getElementById('memory-board').innerHTML = output;
//Change the back of card to represent the deck that is being played
changeBackground();
} //End Shuffle
function flipCard(card, val) {
//get passed in cards id
var userSelect = card.id;
/*check to see if passed in card has been previously matched if so alert user to select different card.*/
if ($.inArray(userSelect, card_matched) == -1 && $.inArray(userSelect, card_previous) == -1) {
if (card.innerHTML == "" && memory_values.length < 2) {
card.style.background = 'url(' + val + '.jpg) no-repeat';
card.innerHTML = "";
/*If this is the first card clicked push card value onto the memory_values(stack)
*and push card.id onto memory_card_id(stack)*/
if (memory_values.length == 0) {
memory_values.push(val);
memory_card_id.push(card.id);
card_previous.push(card.id);
userAttempt++;
} //End if
/*if this is the second card clicked push card value onto the memory_values(stack)
*and push card.id onto memory_card_id(stack)*/
else if (memory_values.length == 1) {
memory_values.push(val);
memory_card_id.push(card.id);
userAttempt++;
/*Compare card values on the stack after two have been clicked to see if they are the same card.*/
if (memory_values[0] == memory_values[1]) {
//Value used to later check if all tiles have been flipped
cards_flipped += 2;
/*Add cards matched to array used to safeguard against user picking cards previously matched*/
var temp1 = memory_card_id.pop();
var temp2 = memory_card_id.pop();
card_matched.push(temp1);
card_matched.push(temp2);
temp1 = "";
temp2 = "";
/*Clear out arrays(stack) because cards were a match to get array ready for next user selection*/
memory_values = [];
memory_card_id = [];
/*Check to see if all cards have been flipped if so alert user and generate new board*/
if (cards_flipped == arrays[deck].length) {
//stop timer & calculate attempts call get player score and pass (name, time , attempts)
alert("Congratulations!! This round took " + userAttempt / 2 + " attempts");
document.getElementById('memory-board').innerHTML = "";
shuffle();
} //End if
} //End if
else {
//If cards were not a match flip them back over
function flipCardBack() {
var card_1 = document.getElementById(memory_card_id[0]);
var card_2 = document.getElementById(memory_card_id[1]);
card_1.style.background = 'url(' + cardBackGround + ') no-repeat';
card_1.innerHTML = "";
card_2.style.background = 'url(' + cardBackGround + ') no-repeat';
card_2.innerHTML = "";
card_previous = [];
memory_values = [];
memory_card_id = [];
} //End flipCardBack
setTimeout(flipCardBack, 700);
} //End else
} //End else if
} //End if
} //End if
else {
alert("This card has previously been selected, please choose a different tile.");
} //End else
} //End flipCard
var public = {
shuffle: shuffle,
flipCard: flipCard,
arrays: arrays,
deckSelected: deckSelected,
changeBackground: changeBackground
};
return public;
})();
/* http://meyerweb.com/eric/tools/css/reset/
v2.0 | 20110126
License: none (public domain)
*/
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
/*
===========================================================
Base
===========================================================
*/
h1 {
font-size: 45px;
}
h2 {
font-size: 35px;
}
h3 {
text-align: center;
font-size: 20px;
margin-bottom: 2px;
}
h4 {
text-align: center;
}
fieldset {
display: block;
margin-left: 2px;
margin-right: 2px;
padding-top: 0.35em;
padding-bottom: 0.625em;
padding-left: 0.75em;
padding-right: 0.75em;
border: 2px groove (internal value);
}
/*
===========================================================
Layout
===========================================================
*/
.header-main {
text-align: center;
padding: 8px 0 8px 0;
}
.container {
max-width: 960px;
padding-top: 10px;
margin: 0 auto;
background-color: gray;
}
.col-1-3 {
float: left;
width: 33%;
}
#memory-board {
height: 960px;
clear: both;
}
.game-controls {
overflow: auto;
border-top: 3px black solid;
border-bottom: 3px black solid;
}
/*
===========================================================
Component
===========================================================
*/
.btn {
height: 52px;
}
.btn-left {
margin: 5px 0px 5px 4px;
}
.btn-right {
float: right;
margin: 5px 0px 0px 5px;
}
.leaderboard {
margin-top: 2px;
}
.userInput {
float: left;
margin: 5px 4px 5px 10px;
}
/*
===========================================================
State Rules
===========================================================
*/
.tile {
float: left;
position: relative;
width: 15.666%;
padding-bottom: 15.666%;
margin-left: 0.7%;
margin-top: 0.7%;
background-position: center center;
background-repeat: no-repeat;
background-size: cover;
background-image: url(../img/card_bg.jpg);
border: 1px solid #000;
cursor: pointer;
}
/*
===========================================================
Responsive
===========================================================
*/
<!DOCTYPE html>
<html lang="en-US">
<head>
<title>Memory Tile Game</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width", initial-scale="1.0">
<link rel="stylesheet" type="text/css" href="assets/css/main.css">
<script rel="text/javascript" src="assets/js/jquery-2.1.4.min.js"></script>
</head>
<body>
<header class="container header-main">
<h1>Popular Culture </h1>
<h2>Memory Tiles Game</h2>
</header>
<section class="container game-controls">
<div class="col-1-3">
<input type="text" class="userInput" id="playerName" placeholder="Enter Player Name Here">
<input type="text" class="userInput" id="playerPassword" placeholder="Enter Password Here">
<button type="button" class="btn btn-left">Login</button>
<button type="button" class="btn btn-left">Register</button>
</div>
<div class="col-1-3 leaderboard">
<h3>LeaderBoard</h3>
<h4>1st Place : Dexter Morgan</h4>
<h4>Linux Distro : 20 Attempts</h4>
</div>
<div class="col-1-3">
<select class="btn btn-right" id="deck" name="decks">
<option value="Deck To Play">Deck To Play</option>
<option value="linux">Linux Distro</option>
<option value="seinfeld">Seinfeld</option>
<option value="starTrek">Star Trek</option>
</select>
<button type="button" class="btn btn-right" id="shuffle">Shuffle Deck</button>
<button type="button" class="btn btn-right">Leaderboard</button>
</div>
</section>
<section class="container" id="memory-board"></section>
<script src="assets/js/tiles.js"></script>
</body>
</html>
Thanks for taking the time to view my post. Apologies if I included more code than necessary ... this being my first stack overflow post.