1

I am generating a table of numbers as can be seen in the snippet that follows. The problem I am facing is that when a number (or cell) is clicked, it gets the class black, followed by circle and then number repeatedly.

When the class circle is active; the column with that particular number gets widened slightly by 2px. This happens because of the extra 2px received from the border property of the said class.

Can this somehow be resolved? I would really like the values to be in relative context , for eg. %s, ems etc. and not px or pt.

Classes = ['number', 'black', 'circle'];
$('.td').on('click', function(e) {
  e.preventDefault();
  var $span = $(this).children('span');
  var state = $span.data('state');
  $span.removeClass(Classes[state]);
  state = ++state % 3;
  console.log(state);
  $span.data('state', state).addClass(Classes[state]);
});
* {
  font-size: 1em;
}
#game {
  display: table;
}
.tr {
  display: table-row;
}
.td {
  display: table-cell;
  margin: 1em;
  padding: .5em;
  border: 1px solid black;
  cursor: pointer;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  -moz-user-select: none;
  user-select: none;
}
.number,
.black,
.circle {
  padding: .5em;
  font-weight: bold;
  text-align: center;
  vertical-align: center;
  transition: ease 1s;
}
.black {
  color: white;
  background-color: rgba(50, 50, 50, 0.8);
}
.circle {
  border-radius: 50%;
  border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='game'>
  <div class='tr'>
    <div class='td'><span class='number' data-state='0'>4</span>
    </div>
    <div class='td'><span class='number' data-state='0'>5</span>
    </div>
    <div class='td'><span class='number' data-state='0'>1</span>
    </div>
    <div class='td'><span class='number' data-state='0'>2</span>
    </div>
    <div class='td'><span class='number' data-state='0'>4</span>
    </div>
  </div>
  <div class='tr'>
    <div class='td'><span class='number' data-state='0'>5</span>
    </div>
    <div class='td'><span class='number' data-state='0'>4</span>
    </div>
    <div class='td'><span class='number' data-state='0'>3</span>
    </div>
    <div class='td'><span class='number' data-state='0'>2</span>
    </div>
    <div class='td'><span class='number' data-state='0'>1</span>
    </div>
  </div>
  <div class='tr'>
    <div class='td'><span class='number' data-state='0'>3</span>
    </div>
    <div class='td'><span class='number' data-state='0'>3</span>
    </div>
    <div class='td'><span class='number' data-state='0'>2</span>
    </div>
    <div class='td'><span class='number' data-state='0'>1</span>
    </div>
    <div class='td'><span class='number' data-state='0'>4</span>
    </div>
  </div>
  <div class='tr'>
    <div class='td'><span class='number' data-state='0'>1</span>
    </div>
    <div class='td'><span class='number' data-state='0'>4</span>
    </div>
    <div class='td'><span class='number' data-state='0'>5</span>
    </div>
    <div class='td'><span class='number' data-state='0'>3</span>
    </div>
    <div class='td'><span class='number' data-state='0'>2</span>
    </div>
  </div>
  <div class='tr'>
    <div class='td'><span class='number' data-state='0'>5</span>
    </div>
    <div class='td'><span class='number' data-state='0'>1</span>
    </div>
    <div class='td'><span class='number' data-state='0'>2</span>
    </div>
    <div class='td'><span class='number' data-state='0'>4</span>
    </div>
    <div class='td'><span class='number' data-state='0'>4</span>
    </div>
  </div>
</div>

As an aside, I'd also like a solution (if possible) to the following:

  1. When black state, the parent div on the whole should get the black background.
  2. The circle (as well as the black background of black class) touches the boundaries of the cell it is inside. Can this be dealt with?
hjpotter92
  • 78,589
  • 36
  • 144
  • 183
  • According to [this answer](http://stackoverflow.com/a/6810937/1016716), the solution is to use `box-shadow: 0 0 0 1px black;` instead of the border; I'm not sure if that makes this question a duplicate though. – Mr Lister Sep 24 '15 at 06:46

1 Answers1

2

The change in width and height is because you are adding a border of 1px width when circle class is added. This is not present initially and hence affects the size. To fix it you can add a transparent 1px border as default for the element.

Coming to the other two questions, setting display: inline-block for the span element and doing away with the padding on the td element would get the background color apply to the element in full. The padding on parent would always mean there is a space between it and child content. This space will not get colored when we apply the background to the child div.

Note: I have increased the padding on the child element from 0.5em to 0.5em 1em to adjust for the padding that was removed from the parent.

Classes = ['number', 'black', 'circle'];
$('.td').on('click', function(e) {
  e.preventDefault();
  var $span = $(this).children('span');
  var state = $span.data('state');
  $span.removeClass(Classes[state]);
  state = ++state % 3;
  console.log(state);
  $span.data('state', state).addClass(Classes[state]);
});
* {
  font-size: 1em;
}
#game {
  display: table;
}
.tr {
  display: table-row;
}
.td {
  display: table-cell;
  margin: 1em;
  border: 1px solid black;
  cursor: pointer;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  -moz-user-select: none;
  user-select: none;
}
.number,
.black,
.circle {
  padding: .5em 1em;
  font-weight: bold;
  text-align: center;
  vertical-align: center;
  transition: ease 1s;
  border: 1px solid transparent;
}
.black {
  color: white;
  background-color: rgba(50, 50, 50, 0.8);
}
.circle {
  border-radius: 50%;
  border: 1px solid black;
}
span {
  display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='game'>
  <div class='tr'>
    <div class='td'><span class='number' data-state='0'>4</span>

    </div>
    <div class='td'><span class='number' data-state='0'>5</span>

    </div>
    <div class='td'><span class='number' data-state='0'>1</span>

    </div>
    <div class='td'><span class='number' data-state='0'>2</span>

    </div>
    <div class='td'><span class='number' data-state='0'>4</span>

    </div>
  </div>
  <div class='tr'>
    <div class='td'><span class='number' data-state='0'>5</span>

    </div>
    <div class='td'><span class='number' data-state='0'>4</span>

    </div>
    <div class='td'><span class='number' data-state='0'>3</span>

    </div>
    <div class='td'><span class='number' data-state='0'>2</span>

    </div>
    <div class='td'><span class='number' data-state='0'>1</span>

    </div>
  </div>
  <div class='tr'>
    <div class='td'><span class='number' data-state='0'>3</span>

    </div>
    <div class='td'><span class='number' data-state='0'>3</span>

    </div>
    <div class='td'><span class='number' data-state='0'>2</span>

    </div>
    <div class='td'><span class='number' data-state='0'>1</span>

    </div>
    <div class='td'><span class='number' data-state='0'>4</span>

    </div>
  </div>
  <div class='tr'>
    <div class='td'><span class='number' data-state='0'>1</span>

    </div>
    <div class='td'><span class='number' data-state='0'>4</span>

    </div>
    <div class='td'><span class='number' data-state='0'>5</span>

    </div>
    <div class='td'><span class='number' data-state='0'>3</span>

    </div>
    <div class='td'><span class='number' data-state='0'>2</span>

    </div>
  </div>
  <div class='tr'>
    <div class='td'><span class='number' data-state='0'>5</span>

    </div>
    <div class='td'><span class='number' data-state='0'>1</span>

    </div>
    <div class='td'><span class='number' data-state='0'>2</span>

    </div>
    <div class='td'><span class='number' data-state='0'>4</span>

    </div>
    <div class='td'><span class='number' data-state='0'>4</span>

    </div>
  </div>
</div>

In case you don't want the circle to touch the grid on all sides, make the following changes:

.number, .black, .circle {
  margin: .1em;
  padding: .4em .9em;
}

.black {
  box-shadow: 0 0 0 .1em black;
}
Harry
  • 87,580
  • 25
  • 202
  • 214
  • 1
    Excellent answer as always. I have added another option that I think fits better the last requirement of the OP. – vals Sep 24 '15 at 07:17
  • 1
    Thanks @vals. I actually read/interpreted that point the other way (as in, OP wanted the circle to touch the grid on all sides instead of just 2 as in question). I will let your edit remain though just in case my interpretation was wrong :) – Harry Sep 24 '15 at 07:21