How to change the appearance of an object when clicking?

4

I'm doing a minimalist memory game, to practice HTML and CSS code, but as a good beginner, I can not find how when the user clicks on a letter (not the effect: hover) it shows the back.

In other words, I have the following object:

Stylized with this code;

.cards {
  display: block;
  background-image: url("http://i492.photobucket.com/albums/rr281/neversinned/design/icons/256x256/other/Globe.png"),-webkit-linear-gradient(Royalblue,Royalblue);
   background-image: url("http://i492.photobucket.com/albums/rr281/neversinned/design/icons/256x256/other/Globe.png"),-moz-linear-gradient(Royalblue,Royalblue);
   background-image: url("http://i492.photobucket.com/albums/rr281/neversinned/design/icons/256x256/other/Globe.png"),-o-linear-gradient(Royalblue,Royalblue);
  background-image: url("http://i492.photobucket.com/albums/rr281/neversinned/design/icons/256x256/other/Globe.png"),linear-gradient(Royalblue,Royalblue);
  background-size: 110px, cover;
  background-repeat: no-repeat, no-repeat;
  background-position: center;
  width: 200px;
  height: 255px;
  border: 5px solid white;
  border-radius: 5px;
}
<!DOCTYPE html>
<html>
  <div class="cards">
  </div>
</html>

But I want to click on it to execute this code instead of the other, showing the "back" of the "letter":

.cards {
  display: block;
  background-image: url("http://i492.photobucket.com/albums/rr281/neversinned/design/icons/256x256/other/Globe.png"),-webkit-linear-gradient(Red,Red);
   background-image: url("http://i492.photobucket.com/albums/rr281/neversinned/design/icons/256x256/other/Globe.png"),-moz-linear-gradient(Red,Red);
   background-image: url("http://i492.photobucket.com/albums/rr281/neversinned/design/icons/256x256/other/Globe.png"),-o-linear-gradient(Red,Red);
  background-image: url("http://i492.photobucket.com/albums/rr281/neversinned/design/icons/256x256/other/Globe.png"),linear-gradient(Red,Red);
  background-size: 110px, cover;
  background-repeat: no-repeat, no-repeat;
  background-position: center;
  width: 200px;
  height: 255px;
  border: 5px solid green;
  border-radius: 5px;
}

Does anyone help me?

    
asked by Yisus Craist 27.04.2017 в 02:54
source

4 answers

5

For this case, you will need javascript , which is the one that allows you to give logic to the application. In this case the logic is: When I click on a letter, I want it to be returned .

With regard to css styles, it is used to say how you want it to look, and you can define 2 classes; one for when the card is normal (face down), and the other when it is turned (face up); we'll call it this active . And when you decide to click on an element, add this active class.

If you are going to add a new class to the element, you only need to have the things that vary, and not everything else. In this case

.card.active {    /* Siendo la clase active la que presenta variación */
    background-image: url("http://i492.photobucket.com/albums/rr281/neversinned/design/icons/256x256/other/Globe.png"),-webkit-linear-gradient(Red,Red);
    background-image: url("http://i492.photobucket.com/albums/rr281/neversinned/design/icons/256x256/other/Globe.png"),-moz-linear-gradient(Red,Red);
    background-image: url("http://i492.photobucket.com/albums/rr281/neversinned/design/icons/256x256/other/Globe.png"),-o-linear-gradient(Red,Red);
    background-image: url("http://i492.photobucket.com/albums/rr281/neversinned/design/icons/256x256/other/Globe.png"),linear-gradient(Red,Red);
    border: 5px solid green;
}

And with javascript, you can say:

  • Search all cards: document.querySelectorAll(".card")
  • For each letter, define what to do when clicking

.

document.querySelectorAll("#cards .card").forEach(function(card) {
  card.addEventListener('click', function(evento) {

  });
});
  • And within that block, you define what you want to do, in this case, add or remove a class: this.classList.toggle("active");

In this way, a face-down card will look like <div class="card"></div> , while a face-up will look like <div class="card active"></div>

For example:

document.querySelectorAll(".card").forEach(function(card) {
  card.addEventListener('click', function(evento) {
    this.classList.toggle("active");
  });
});
.card {
  display: block;
  background-image: url("http://i492.photobucket.com/albums/rr281/neversinned/design/icons/256x256/other/Globe.png"), -webkit-linear-gradient(Royalblue, Royalblue);
  background-image: url("http://i492.photobucket.com/albums/rr281/neversinned/design/icons/256x256/other/Globe.png"), -moz-linear-gradient(Royalblue, Royalblue);
  background-image: url("http://i492.photobucket.com/albums/rr281/neversinned/design/icons/256x256/other/Globe.png"), -o-linear-gradient(Royalblue, Royalblue);
  background-image: url("http://i492.photobucket.com/albums/rr281/neversinned/design/icons/256x256/other/Globe.png"), linear-gradient(Royalblue, Royalblue);
  background-size: 110px, cover;
  background-repeat: no-repeat, no-repeat;
  background-position: center;
  width: 200px;
  height: 255px;
  border: 5px solid white;
  border-radius: 5px;
}

.card.active {
  url("http://i492.photobucket.com/albums/rr281/neversinned/design/icons/256x256/other/Globe.png"),
  -webkit-linear-gradient(red,
  red);
  background-image: url("http://i492.photobucket.com/albums/rr281/neversinned/design/icons/256x256/other/Globe.png"), -moz-linear-gradient(red, red);
  background-image: url("http://i492.photobucket.com/albums/rr281/neversinned/design/icons/256x256/other/Globe.png"), -o-linear-gradient(red, red);
  background-image: url("http://i492.photobucket.com/albums/rr281/neversinned/design/icons/256x256/other/Globe.png"), linear-gradient(red, red);
  border: 5px solid green;
}
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>

It should be noted, that this is just a way to solve your problem. When you use javascript, you are asking "how" you want to solve your problem. I can think about solving it in this way, another can think about creating a class for each letter, maintain a state for each one and change it, and each one decides which way to use, because it seems simpler, more natural, more efficient, or more maintainable and scalable, etc.

    
answered by 27.04.2017 / 04:45
source
3

Initially you only had the tags of and , then the tag of and you have several answers with solutions in JavaScript. I agree that you should opt for one of those answers to have more functionality ... but just for fun, I'll give an example of how it could be done only with HTML and CSS without the need for JavaScript.

The idea is based on using checkbox and label next to the pseudo-class selector :checked to simulate certain functionality. For this you will need to change the structure of the HTML a bit and add some elements.

Here is the code:

.card-box {
  display: inline-block;
}

.card-box input[type=checkbox] {
  display: none;
}

.card {
  display: block;
  background-image: url("http://i492.photobucket.com/albums/rr281/neversinned/design/icons/256x256/other/Globe.png"), linear-gradient(Royalblue, Royalblue);
  background-size: 110px, cover;
  background-repeat: no-repeat, no-repeat;
  background-position: center;
  width: 200px;
  height: 255px;
  border: 5px solid white;
  border-radius: 5px;
}

:checked + .card {
  background-image: url("http://i492.photobucket.com/albums/rr281/neversinned/design/icons/256x256/other/Globe.png"), linear-gradient(Red, Red);
  background-size: 110px, cover;
  background-repeat: no-repeat, no-repeat;
  background-position: center;
  width: 200px;
  height: 255px;
  border: 5px solid green;
  border-radius: 5px;
}
<div class="card-box">
  <input type="checkbox" id="cb2" />
  <label class="card" for="cb2"></label>
</div>

I'll give you a simple version of a memory game with 3 pairs (without messing up) made with HTML + CSS and without JS. When you pick up a piece, its edge turns red; if you pick up a second chip and it matches the first, the edge of both chips is green to indicate that you found a match.

Not having JS prevents us from including a more complex logic and that has some drawbacks:

  • users must flip the tiles manually if there is no match and they could cheat (although you could say that this is more realistic to look more like the board game: P);
  • can not take turns or punctuation (really yes it could be but only in some cases and it would be something complex);
  • the size of the game would grow with the number of chips (a simple solution could be made with SCSS / SASS, but the generated CSS would grow considerably).

Here is a demo:

input {
  display:none;  
}

.card {
  width:104px;
  height:104px;
  display:inline-block;
  border-radius:3px;
  background:#336699;
  margin:5px;
  position:relative;
  overflow:hidden;
}

.card img {
  opacity:0;
  border-radius:3px;
  border:2px solid red;
}

#c0:checked ~ [for=c0] img, #c1:checked ~ [for=c1] img, #c2:checked ~ [for=c2] img,
#c3:checked ~ [for=c3] img, #c4:checked ~ [for=c4] img, #c5:checked ~ [for=c5] img {  
  opacity:1;
}

input[data-match=m0]:checked ~ input[data-match=m0]:checked ~ label[data-match=m0] img,
input[data-match=m1]:checked ~ input[data-match=m1]:checked ~ label[data-match=m1] img,
input[data-match=m2]:checked ~ input[data-match=m2]:checked ~ label[data-match=m2] img {
  border:2px solid green !important;
}
<input type="checkbox" id="c0" data-match="m0" />
<input type="checkbox" id="c1" data-match="m0" />
<input type="checkbox" id="c2" data-match="m1" />
<input type="checkbox" id="c3" data-match="m1" />
<input type="checkbox" id="c4" data-match="m2" />
<input type="checkbox" id="c5" data-match="m2" />
<label class="card" for="c0" data-match="m0"><img src="http://placehold.it/100?text=1" alt="" /></label>
<label class="card" for="c1" data-match="m0"><img src="http://placehold.it/100?text=1" alt="" /></label>
<label class="card" for="c2" data-match="m1"><img src="http://placehold.it/100?text=2" alt="" /></label>
<label class="card" for="c3" data-match="m1"><img src="http://placehold.it/100?text=2" alt="" /></label>
<label class="card" for="c4" data-match="m2"><img src="http://placehold.it/100?text=3" alt="" /></label>
<label class="card" for="c5" data-match="m2"><img src="http://placehold.it/100?text=3" alt="" /></label>
    
answered by 27.04.2017 в 12:57
1

It is necessary to know JavaScript, this allows us to interact with the website. I leave you a functional example using JS + CSS, I hope it's useful.

 var posicioncarta = 1; //1=Carta boca abajo / 0=Carta boca arriba
	  function Click() {
	  	if (posicioncarta==1){
	  		document.getElementById('carta').className='card2';
	  		posicioncarta=0;
	  	}
	  	else{
	  		document.getElementById('carta').className='cards';
	  		posicioncarta=1;	
	  	}
	  }
.cards {
			  display: block;
			  background-image: url("http://i492.photobucket.com/albums/rr281/neversinned/design/icons/256x256/other/Globe.png"),-webkit-linear-gradient(Royalblue,Royalblue);
			   background-image: url("http://i492.photobucket.com/albums/rr281/neversinned/design/icons/256x256/other/Globe.png"),-moz-linear-gradient(Royalblue,Royalblue);
			   background-image: url("http://i492.photobucket.com/albums/rr281/neversinned/design/icons/256x256/other/Globe.png"),-o-linear-gradient(Royalblue,Royalblue);
			  background-image: url("http://i492.photobucket.com/albums/rr281/neversinned/design/icons/256x256/other/Globe.png"),linear-gradient(Royalblue,Royalblue);
			  background-size: 110px, cover;
			  background-repeat: no-repeat, no-repeat;
			  background-position: center;
			  width: 200px;
			  height: 255px;
			  border: 5px solid white;
			  border-radius: 5px;
			}
	.card2{
			  display: block;
			  background-image: url("http://i492.photobucket.com/albums/rr281/neversinned/design/icons/256x256/other/Globe.png"),-webkit-linear-gradient(Red,Red);
			   background-image: url("http://i492.photobucket.com/albums/rr281/neversinned/design/icons/256x256/other/Globe.png"),-moz-linear-gradient(Red,Red);
			   background-image: url("http://i492.photobucket.com/albums/rr281/neversinned/design/icons/256x256/other/Globe.png"),-o-linear-gradient(Red,Red);
			  background-image: url("http://i492.photobucket.com/albums/rr281/neversinned/design/icons/256x256/other/Globe.png"),linear-gradient(Red,Red);
			  background-size: 110px, cover;
			  background-repeat: no-repeat, no-repeat;
			  background-position: center;
			  width: 200px;
			  height: 255px;
			  border: 5px solid green;
			  border-radius: 5px;
			}
<div class="cards" id="carta" onclick="Click()"></div>

The example is very simple and it is understood that it is to exemplify the functionality of JavaScript in order to achieve the result. The solution is not the most optimal (as resources) since we are loading the images again and again, a better option would be to have both images loaded from the beginning and play their visibility attributes to hide one and show another. / p>     

answered by 27.04.2017 в 04:30
0

Another way could be.

Your HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link rel="stylesheet" href="style.css">
    <title>Document</title>
</head>
<body>
    <div class="cards">

    </div>
<script src="script.js">

</script>
</body>
</html>

Your Css

.cards {
  display: block;
  background-image: url("http://i492.photobucket.com/albums/rr281/neversinned/design/icons/256x256/other/Globe.png"),-webkit-linear-gradient(Royalblue,Royalblue);
   background-image: url("http://i492.photobucket.com/albums/rr281/neversinned/design/icons/256x256/other/Globe.png"),-moz-linear-gradient(Royalblue,Royalblue);
   background-image: url("http://i492.photobucket.com/albums/rr281/neversinned/design/icons/256x256/other/Globe.png"),-o-linear-gradient(Royalblue,Royalblue);
  background-image: url("http://i492.photobucket.com/albums/rr281/neversinned/design/icons/256x256/other/Globe.png"),linear-gradient(Royalblue,Royalblue);
  background-size: 110px, cover;
  background-repeat: no-repeat, no-repeat;
  background-position: center;
  width: 200px;
  height: 255px;
  border: 5px solid red;
  border-radius: 5px;
} 

Now the javascript

// Esta función es la encargada de ver si un array tiene un valor en especifico.
function existe( array, valor ) {  
    var largo = array.length;
    for (var i = 0; i < largo; i++) {
        if ( array[i] === valor ) {
            return 1;
            break;
        }
    }
    return 0;
}


// Es llamada cada vez que se hace clip y verifica si se ha hecho clip sobre nuestra Tarjeta 
// si es así llama a la función cambioEstilos.  
function llamaUnaFuncion( e ) {         
    if ( existe( e.target.classList, 'cards' ) ) {
            cambioEstilos( e.target ); // Llamada a la función cambioEstilos.
    }

}


// Cada vez que es llamada cambia los estilos que están especificado dentro de ella.  
function cambioEstilos( card ) {    
    if(card.style.borderColor !== "green") {
        card.style.backgroundImage = 'url("http://i492.photobucket.com/albums/rr281/neversinned/design/icons/256x256/other/Globe.png"),linear-gradient(black,black)';
        card.style.border = '5px solid green';
    } else {
        card.style.backgroundImage = 'url("http://i492.photobucket.com/albums/rr281/neversinned/design/icons/256x256/other/Globe.png"),linear-gradient(Royalblue,Royalblue)';
        card.style.border = '5px solid red';
    }       

}

// Esta función se mantiene en escucha al evento click. Y es la que inicia todo.   
addEventListener( 'click', llamaUnaFuncion );
    
answered by 27.04.2017 в 04:59