Styling an element that is not a child of the element used in the selector

Asked

Viewed 51 times

1

I have the code below where I want to, by clicking on the toogle (which is a input[type=checkbox]), another element, which is a class of another div, below, be stylized. In the following code, I make an attempt using the general brother operator ~ that is not working, I think it is because the class .ringDireita is not daughter of the div buttons, although it is "declared" below it.

What’s wrong with using selectors or what else can be done?

body {
  margin: 5px;
  padding: 0;
  background: #262626;
}

#botoes {
  position: absolute;
  width: 100px;
  color: #fff;
  margin: 5px;
}

#botoes input[type=checkbox]::before {
  content: '';
  position: absolute;
  width: 40px;
  height: 40px;
  top: 0;
  left: 0;
  border-radius: 50%;
  background: #000;
  transition: .1s;
  transform: scale(1.1);
  box-shadow: 0 0px 15px #ffffff;
}

#botoes input[type=checkbox] {
  position: relative;
  background: #b9b9c8;
  width: 80px;
  height: 40px;
  border: none;
  float: right;
  border-radius: 20px;
  -webkit-appearance: none;
  margin-bottom: 15%;
  outline: none;
}

#botoes input:checked[type=checkbox]::before {
  left: 40px;
}

#botoes input:checked[type=checkbox] {
  background: dodgerBlue;
}

.ringDireita {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 150px;
  height: 150px;
  background: transparent;
  border: 3px solid #3c3c3c;
  border-radius: 50%;
  box-shadow: 0 0 20px rgba(0, 0, 0, .5);
}

.ringDireita::before {
  content: '';
  position: absolute;
  top: -3px;
  left: -3px;
  width: 100%;
  height: 100%;
  border: 3px solid transparent;
  border-top: 3px solid #fff000;
  border-right: 3px solid #fff000;
  border-radius: 50%;
  animation: animateCircleDireita 2s linear infinite;
}

.ringEsquerda {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 120px;
  height: 120px;
  background: transparent;
  border: 3px solid #3c3c3c;
  border-radius: 50%;
  box-shadow: 0 0 20px rgba(0, 0, 0, .5);
}

.ringEsquerda::before {
  content: '';
  position: absolute;
  top: -3px;
  left: -3px;
  width: 100%;
  height: 100%;
  border: 3px solid transparent;
  border-bottom: 3px solid #fff;
  border-right: 3px solid #fff;
  border-radius: 50%;
  animation: animateCircleEsquerda 2s linear infinite;
}

.ringCentro {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 70px;
  height: 70px;
  background: transparent;
  border: 3px solid #3c3c3c;
  border-radius: 50%;
  box-shadow: 0 0 20px rgba(0, 0, 0, .5);
}

.ringCentro::before {
  content: '';
  position: absolute;
  top: -3px;
  left: -3px;
  width: 100%;
  height: 100%;
  border: 3px solid transparent;
  border-bottom: 3px solid #4000ff;
  border-right: 3px solid #4000ff;
  border-radius: 50%;
  animation: animateCircleCentro 2s linear infinite;
}

span.direita {
  display: block;
  position: absolute;
  top: calc(50% - 2px);
  left: 50%;
  width: 50%;
  height: 4px;
  background: transparent;
  transform-origin: left;
  animation: animateDireita 2s linear infinite;
}

span.direita::before {
  content: '';
  position: absolute;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #fff000;
  top: -8px;
  right: -8px;
  box-shadow: 0 0 20px #fff000, 0 0 40px #fff000, 0 0 60px #fff000, 0 0 80px #fff000, 0 0 0 3px rgba(255, 255, 0, .3), 0 0 0 5px rgba(255, 255, 0, .1);
}

span.esquerda {
  display: block;
  position: absolute;
  top: calc(50% - 2px);
  left: 50%;
  width: 50%;
  height: 4px;
  background: transparent;
  transform-origin: left;
  animation: animateEsquerda 2s linear infinite;
}

span.esquerda::before {
  content: '';
  position: absolute;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #fff;
  top: -8px;
  right: -8px;
  box-shadow: 0 0 20px #fff, 0 0 40px #fff, 0 0 60px #fff, 0 0 80px #fff, 0 0 0 3px rgba(255, 255, 255, .3), 0 0 0 5px rgba(255, 255, 255, .1);
}

span.centro {
  display: block;
  position: absolute;
  top: calc(50% - 2px);
  left: 50%;
  width: 50%;
  height: 4px;
  background: transparent;
  transform-origin: left;
  animation: animateCentro 2s linear infinite;
}

span.centro::before {
  content: '';
  position: absolute;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #4000ff;
  top: -8px;
  right: -8px;
  box-shadow: 0 0 20px #4000ff, 0 0 40px #4000ff, 0 0 60px #4000ff, 0 0 80px #4000ff, 0 0 0 3px rgba(0, 0, 255, .3), 0 0 0 5px rgba(0, 0, 255, .1);
}

@keyframes animateCircleDireita {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

@keyframes animateCircleEsquerda {
  0% {
    transform: rotate(360deg);
  }
  100% {
    transform: rotate(0deg);
  }
}

@keyframes animateCircleCentro {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

@keyframes animateDireita {
  0% {
    transform: rotate(45deg);
  }
  100% {
    transform: rotate(405deg);
  }
}

@keyframes animateEsquerda {
  0% {
    transform: rotate(315deg);
  }
  100% {
    transform: rotate(-45deg);
  }
}

@keyframes animateCentro {
  0% {
    transform: rotate(135deg);
  }
  100% {
    transform: rotate(495deg);
  }
}
<html lang="pt-br">

<head>
  <title>Teste de pontos circulantes</title>
  <link rel="stylesheet" href="CSS/style.css">
</head>

<body>
  <div id="botoes">
    Hidden Rings
    <input type="checkbox"> Collision Rings
    <input type="checkbox">
  </div>
  <div class="ringDireita">
    <span class="direita"></span>
  </div>
  <div class="ringEsquerda">
    <span class="esquerda"></span>
  </div>
  <div class="ringCentro">
    <span class="centro"></span>
  </div>
</body>

</html>

1 answer

1


Your thinking is right! When you put the selector ~ in a input:checkbox that is inside the one container, regardless of the state of that checkbox (checked or not) you cannot reach an element that is outside that container, or an element that is not the son or brother of that inpud:chekbox

To solve this question you can use a label with the attribute for="meuid" to achieve a input:chekbox:id="meuid" that is hidden outside that container. In case I used two Ids #hide and #coli in two inputs with display:none before all elements, so I can use the selector ~ to reach any element that comes after these inputs. And by clicking on label I can reach the inputs and changes them to checked or not.

In this example I made a Btn to hide the Rings and another Btn to hide the Polka Dots. I left a comment in the code for you to better understand.

body
{
	margin:5px; padding:0; background:#262626;
}
#botoes
{
	position:absolute;
	width:100px;
	color:#fff;
	margin:5px;	
}
#botoes label::before
{
	content:'';
	position:absolute;
	width:40px;
	height:40px;
	top:0;
	left:0;
	border-radius:50%;
	background:#000;
	transition:.1s;
	transform:scale(1.1);
	box-shadow: 0 0px 15px #ffffff;
	
}
/* esconde os inputs com display:none */
#hide,
#coli 
{
    display: none;
}

/* aqui vc usa na verdade o label, e não o input */
#botoes label 
{	
position:relative;
background:#b9b9c8;
width:80px;	
height:40px;
border:none;
float:right;
border-radius:20px;
-webkit-appearance:none;
margin-bottom:15%;
outline:none;	
cursor: pointer;
}

/* seleciona apenas a labrl com o atributo for correpondente */
#hide:checked ~ #botoes [for="hide"]::before,
#coli:checked ~ #botoes [for="coli"]::before
{
	left:40px;
}

#hide:checked ~ #botoes [for="hide"],
#coli:checked ~ #botoes [for="coli"]
{
	background:dodgerBlue;
}


#hide:checked ~ .ringDireita::before,
#hide:checked ~ .ringEsquerda::before,
#hide:checked ~ .ringCentro::before
{
	border:3px solid transparent;
}
#coli:checked ~ .ringDireita > span,
#coli:checked ~ .ringEsquerda > span,
#coli:checked ~ .ringCentro > span
{
	opacity: 0;
}


.ringDireita
{
	position:absolute;
	top:50%;
	left:50%;
	transform:translate(-50%,-50%);
	width:150px;
	height:150px;
	background:transparent;
	border:3px solid #3c3c3c;
	border-radius:50%;
	box-shadow:0 0 20px rgba(0,0,0,.5);
}

.ringDireita::before
{
	content:'';
	position:absolute;
	top:-3px; 
	left:-3px;
	width:100%;
	height:100%;
	border:3px solid transparent;
	border-top:3px solid #fff000;
	border-right:3px solid #fff000;
	border-radius:50%;
	animation:animateCircleDireita 2s linear infinite;
}
.ringEsquerda
{
	position:absolute;
	top:50%;
	left:50%;
	transform:translate(-50%,-50%);
	width:120px;
	height:120px;
	background:transparent;
	border:3px solid #3c3c3c;
	border-radius:50%;
	box-shadow:0 0 20px rgba(0,0,0,.5);
}
.ringEsquerda::before
{
	content:'';
	position:absolute;
	top:-3px; 
	left:-3px;
	width:100%;
	height:100%;
	border:3px solid transparent;
	border-bottom:3px solid #fff;
	border-right:3px solid #fff;
	border-radius:50%;
	animation:animateCircleEsquerda 2s linear infinite;
}
.ringCentro
{
	position:absolute;
	top:50%;
	left:50%;
	transform:translate(-50%,-50%);
	width:70px;
	height:70px;
	background:transparent;
	border:3px solid #3c3c3c;
	border-radius:50%;
	box-shadow:0 0 20px rgba(0,0,0,.5);
}
.ringCentro::before
{
	content:'';
	position:absolute;
	top:-3px; 
	left:-3px;
	width:100%;
	height:100%;
	border:3px solid transparent;
	border-bottom:3px solid #4000ff;
	border-right:3px solid #4000ff;
	border-radius:50%;
	animation:animateCircleCentro 2s linear infinite;
}
span.direita
{
	display:block;
	position:absolute;
	top:calc(50% - 2px);
	left:50%;
	width:50%;
	height:4px;
	background:transparent;
	transform-origin:left;
	animation: animateDireita 2s linear infinite;
}
span.direita::before
{
	content:'';
	position:absolute;
	width:16px;
	height:16px;
	border-radius:50%;
	background:#fff000;
	top:-8px;
	right:-8px;
	box-shadow:	0 0 20px #fff000,
	0 0 40px #fff000,
	0 0 60px #fff000,
	0 0 80px #fff000,
	0 0 0 3px rgba(255,255,0,.3),
	0 0 0 5px rgba(255,255,0,.1);
}
span.esquerda
{
	display:block;
	position:absolute;
	top:calc(50% - 2px);
	left:50%;
	width:50%;
	height:4px;
	background:transparent;
	transform-origin:left;
	animation: animateEsquerda 2s linear infinite; 
	
}

span.esquerda::before
{
	content:'';
	position:absolute;
	width:16px;
	height:16px;
	border-radius:50%;
	background:#fff;
	top:-8px;
	right:-8px;
	box-shadow:	0 0 20px #fff,
	0 0 40px #fff,
	0 0 60px #fff,
	0 0 80px #fff,
	0 0 0 3px rgba(255,255,255,.3),
	0 0 0 5px rgba(255,255,255,.1);
}
span.centro
{
	display:block;
	position:absolute;
	top:calc(50% - 2px);
	left:50%;
	width:50%;
	height:4px;
	background:transparent;
	transform-origin:left;
	animation: animateCentro 2s linear infinite; 
	
}

span.centro::before
{
	content:'';
	position:absolute;
	width:16px;
	height:16px;
	border-radius:50%;
	background:#4000ff;
	top:-8px;
	right:-8px;
	box-shadow:	0 0 20px #4000ff,
	0 0 40px #4000ff,
	0 0 60px #4000ff,
	0 0 80px #4000ff,
	0 0 0 3px rgba(0,0,255,.3),
	0 0 0 5px rgba(0,0,255,.1);
}


@keyframes animateCircleDireita
{
	0%
	{
		transform:rotate(0deg);
	}
	100%
	{
		transform:rotate(360deg);
	}
}	
@keyframes animateCircleEsquerda
{
	0%
	{
		transform:rotate(360deg);
	}
	100%
	{
		transform:rotate(0deg);
	}
}	
@keyframes animateCircleCentro
{
	0%
	{
		transform:rotate(0deg);
	}
	100%
	{
		transform:rotate(360deg);
	}
}	

@keyframes animateDireita
{
	0%
	{
		transform:rotate(45deg);
	}
	100%
	{
		transform:rotate(405deg);
	}
}	
@keyframes animateEsquerda
{
	0%
	{
		transform:rotate(315deg);
	}
	100%
	{
		transform:rotate(-45deg);
	}
}	
@keyframes animateCentro
{
	0%
	{
		transform:rotate(135deg);
	}
	100%
	{
		transform:rotate(495deg);
	}
}	
<!-- os inputs devem vir antes dos elementos que vc quer atingir com ~ -->
<input hidden id="hide" type="checkbox">
<input hidden id="coli" type="checkbox">

<div id="botoes">
    Hidden Rings
    <!-- agora é uma label e não o input -->
    <label for="hide"></label>
    Collision Rings
    <label for="coli"></label>
</div>

<div class="ringDireita">
    <span class="direita"></span>
</div>
<div class="ringEsquerda">
    <span class="esquerda"></span>
</div>
<div class="ringCentro">
    <span class="centro"></span>
</div>

  • hugocsl. Good solution. I even thought of the label somehow (pq we can make external reference with it by the for) just did not know how. If I understand correctly, I can use selector ' with element of any container since the reference element, in case the input, is not "locked" in another container, even if that other container is above, is that it? In your case, it worked because the input was in the <body> container, let’s say "unlocked", and can be used in refer. by any element below, okay? If I put your input inside any div, it would not work the reference, ok?

  • @Fernandes perfect, you got it right. If you lock the input inside a container it cannot reach anyone else, only the one below it and inside the same container. That’s it, that’s why it says the trickiness of throwing the input out of the container and checking it with the label using the id of the for :)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.