1

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

Grid of responsive squares

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.

Community
  • 1
  • 1
Pacific27
  • 25
  • 3
  • If you could post a runable sample that would help immensely, as it's pretty hard to know for sure if we can't run the code. Just looking at the code it strikes me that in the javascript you set the css property 'background' to the image url. Background is shorthand for all background related properties, so setting that may be overriding your css 'background-position' property. – Rob Louie Oct 07 '15 at 20:44
  • Thanks for your response. Uploaded the missing CSS code. Will look into your suggestion that setting the css property in javascript may be overriding background-position. Still needs folders with actual background images to run not sure if/how to upload those. They are 150px X 150px images found in the folders specified in code. – Pacific27 Oct 07 '15 at 22:18
  • You could host the images on an image hosting site then just change the urls. You wouldn't necessarily need to do that for the entire app, if loading just one or two of the images lets us reproduce the issue you could leave it at that. If we can actually see the issue happening I'm positive someone can solve this for you. – Rob Louie Oct 07 '15 at 22:22
  • @RobLouie You are correct. The css shorthand 'background' property I used to set the background-image with JQuery must of been overriding the 'background-position' property (and any other 'background' properties for that matter). When I changed card.style.background to card.style.backgroundImage in js file and removed no-repeat as it doesn't apply to the background-image css property the background images began to scale correctly. Thank you again for taking the time from your day to give me a hand. Now back to the documentation to figure out how to accept your answer as solved – Pacific27 Oct 07 '15 at 23:19
  • I have to actually make it an answer instead of a comment, then you can mark it. – Rob Louie Oct 08 '15 at 00:10

1 Answers1

0

The setting of the shorthand background property is overriding any other background css you had set, effectively removing all background styles except the image.

Rob Louie
  • 2,462
  • 1
  • 19
  • 24