纯CSS onClick事件复选框hack问题

3

我有一个用HTML+CSS画的机器人,并使用“background-color”进行颜色填充,我希望在点击时更改它的部件颜色。我知道可以用几行JS/Jquery代码很容易实现,但我想要一个纯CSS的解决方案。我一直在尝试实现复选框hack,但遗憾地失败了(请参见CSS部分中的“#recolor:checked > .torso”部分)。附上代码。

body{
 background-color: rgba(0, 0, 0, 0.788);
}

h1 {
 text-align: center;
 font-family: 'Roboto', sans-serif;
 margin-left: 50px;
 color: whitesmoke;
}

.robots {
 display: flex;
 flex-flow: column wrap;
 justify-content: center;
 align-items: center;
 margin-left: 100px;
}

nav{
 position: fixed;
 top: 75px;
 left: 20px;
 margin: 0px 50px 0px 20px;
        width: 300px;
 color: blanchedalmond;
}

ul{
 list-style: none;
}

.head, 
.left_arm, 
.torso, 
.right_arm, 
.left_leg, 
.right_leg {
 background-color: #5f93e8;
}

#recolor:checked > .torso {
 background-color: chartreuse;
}


.head { 
 width: 200px; 
 margin: 0 auto; 
 height: 150px; 
 border-radius: 200px 200px 0 0; 
 margin-bottom: 10px;
} 

.eyes {
 display:flex;
}

.head:hover {
 width: 300px;
    transition: 1s ease-in-out;
}


.upper_body { 
 width: 300px; 
 height: 150px;
 display: flex; 
} 

.left_arm, .right_arm { 
 width: 40px; 
 height: 125px;
 border-radius: 100px; 
} 

.left_arm { 
 margin-right: 10px; 
} 

.left_arm:hover {
 -webkit-transform: rotate(120deg);
    -moz-transform: rotate(120deg);
    -o-transform: rotate(120deg);
    -ms-transform: rotate(120deg);
    transform: rotate(120deg);
}

.right_arm { 
 margin-left: 10px; 
} 

.torso { 
 width: 200px; 
 height: 200px;
 border-radius: 0 0 50px 50px; 
} 

.lower_body { 
 width: 200px; 
 height: 200px;
 margin: 0 auto;
 display: flex;
} 

.left_leg, .right_leg { 
 width: 40px; 
 height: 120px;
 border-radius: 0 0 100px 100px;  
} 

.left_leg { 
 margin-left: 45px; 
} 

.left_leg:hover {
 -webkit-transform: rotate(20deg);
    -moz-transform: rotate(20deg);
    -o-transform: rotate(20deg);
    -ms-transform: rotate(20deg);
 transform: rotate(20deg);
}

.right_leg:hover {
 -webkit-transform: rotate(-20deg);
    -moz-transform: rotate(-20deg);
    -o-transform: rotate(-20deg);
    -ms-transform: rotate(-20deg);
 transform: rotate(-20deg);
}

.right_leg { 
 margin-left: 30px; 
}

.left_eye, .right_eye { 
 width: 20px; 
 height: 20px; 
 border-radius: 15px; 
 background-color: white;  
} 

.left_eye { 
 position: relative; 
 top: 100px; 
 left: 40px; 
} 

.right_eye { 
 position: relative; 
 top: 100px; 
 left: 120px; 
}
<!DOCTYPE html>
<html>
<head>
 <title>RoboPage</title>
 <link rel="stylesheet" type="text/css" href="style.css">
 <link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">
</head>
<body>
 <header>
 <h1>Robot Friend</h1>
 </header>
 <nav class="tutorial">
  <h2>Usage tutorial</h2>
  <ul class="tips">
   <li>Hover over robot's left arm for him to greet you!</li>
   <li>Click and hold on bot's body for him to change color</li>
   <li>Hover over bot's legs for him to make a tap dance</li>
  </ul>
 </nav>
 <div class="robots">
  <div class="android"> 
   <label for="recolor">
   <input type="checkbox" id="recolor">
   <div class="head"> 
    <div class="eyes"> 
     <div class="left_eye"></div> 
     <div class="right_eye"></div>
    </div> 
   </div> 
   <div class="upper_body"> 
    <div class="left_arm"></div> 
    <div class="torso"></div> 
       <div class="right_arm"></div> 
   </div> 
   <div class="lower_body"> 
    <div class="left_leg"></div> 
    <div class="right_leg"></div> 
   </div>  
  </label>  
  </div>
 </div>
</body>
</html>


1
你还有另一个问题,那就是在hover时旋转元素(腿、臂),这可能会导致元素无法控制地抖动。你可以通过不让旋转的目标成为激活旋转的对象来解决这个问题,正如这个视频所解释的那样:https://youtu.be/8kK-cA99SA0?t=946 - Rickard Elimää
1个回答

3
您正在选择#recolor:checked > .torso,这意味着任何一个被选中的#recolor直接子元素的.torso。这将类似于以下内容:
<input type="checkbox" id="recolor"><div class="torso"></div></input>

但那不是你的结构,而且它也是无效的(input不能有子元素)。你有一个输入框,然后紧接着它,你有一个.head,然后是一个.upper_body和里面的一个.torso

你的选择器应该是:#recolor:checked ~ .upper_body > .torso

这意味着任何一个.torso是直接子元素(>)的.upper_body的兄弟元素(~),它们都会受到选中的输入框的影响。

在这种情况下,你必须使用~,而不是+,因为.upper_body是输入框的兄弟元素,但它不是紧挨着它的。


非常感谢您提供的解决方案(天啊,它起作用了!)和解释!想到我在学习编程的第一周就为这个问题苦恼了两天... 也许您可以指导我去哪里寻找更多关于多层选择器的见解,就像您提供的那个一样?MDN、W3 和 CSS tricks 都有很好的解释,但只适用于简单的“单级”选择器,比如 A+B、A>B。 然而,当我需要选择一个位于其他几个元素内部并且还带有某些“:属性”的元素时,我就完全迷失了。 - Kekuy
1
@Kekuy 我现在脑海中想不出什么。只需谷歌搜索“css复杂选择器”,你就会找到很多相关内容。 一旦你对组合器(后代“ ”,子元素“>”,相邻兄弟“+”和通用兄弟“~”)有了很好的理解,你就可以通过链接它们来实现很多功能。https://www.w3schools.com/css/css_combinators.asp https://www.w3schools.com/cssref/css_selectors.asp https://learn.shayhowe.com/advanced-html-css/complex-selectors/祝你好运! - ezakto
好的,知道了!至少现在我知道该找什么了。不知道这个现象有自己的名字(虽然应该猜到了,呵呵)。再次感谢你的帮助! - Kekuy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接