3D翻转立方体边框间隙及按钮适配的CSS修改咨询
Got it, let's tackle your cube issues step by step. The root problem here is that when you shrink the cube from 200px to 170px, you didn't adjust the 3D translation values to match the new half-size of the cube. That misalignment causes those annoying border gaps. Plus, we'll tweak the face styling to make buttons fit perfectly.
Key Issues & Fixes
3D Translation Misalignment:
For a cube of sizeNpx, each face needs to be translated forward byN/2px to sit flush against the cube's edges. When you went from 200px (half = 100px) to 170px (half = 85px), all thetranslateZ()values stayed at 100px—this pushes faces too far out, creating gaps.Button Fit:
The originalline-height: 200pxforces vertical centering for text but breaks button layout. Switching to flexbox will let any content (buttons included) center perfectly without hardcoded values.
Modified Complete Code
HTML (updated with buttons for testing):
<div class="scene"> <div class="cube"> <div class="cube__face cube__face--front"><button>Front</button></div> <div class="cube__face cube__face--back"><button>Back</button></div> <div class="cube__face cube__face--right"><button>Right</button></div> <div class="cube__face cube__face--left"><button>Left</button></div> <div class="cube__face cube__face--top"><button>Top</button></div> <div class="cube__face cube__face--bottom"><button>Bottom</button></div> </div> </div> <p class="radio-group"> <label> <input type="radio" name="rotate-cube-side" value="front" checked /> front </label> <label> <input type="radio" name="rotate-cube-side" value="right" /> right </label> <label> <input type="radio" name="rotate-cube-side" value="back" /> back </label> <label> <input type="radio" name="rotate-cube-side" value="left" /> left </label> <label> <input type="radio" name="rotate-cube-side" value="top" /> top </label> <label> <input type="radio" name="rotate-cube-side" value="bottom" /> bottom </label> </p>
CSS (modified values marked with comments):
* { box-sizing: border-box; } body { font-family: sans-serif; } .scene { width: 170px; /* Updated from 200px */ height: 170px; /* Updated from 200px */ border: 1px solid #CCC; margin: 80px; perspective: 400px; } .cube { width: 170px; /* Updated from 200px */ height: 170px; /* Updated from 200px */ position: relative; transform-style: preserve-3d; transform: translateZ(-85px); /* Half of 170px, updated from -100px */ transition: transform 1s; } .cube.show-front { transform: translateZ(-85px) rotateY( 0deg); /* Updated translateZ */ } .cube.show-right { transform: translateZ(-85px) rotateY( -90deg); /* Updated translateZ */ } .cube.show-back { transform: translateZ(-85px) rotateY(-180deg); /* Updated translateZ */ } .cube.show-left { transform: translateZ(-85px) rotateY( 90deg); /* Updated translateZ */ } .cube.show-top { transform: translateZ(-85px) rotateX( -90deg); /* Updated translateZ */ } .cube.show-bottom { transform: translateZ(-85px) rotateX( 90deg); /* Updated translateZ */ } .cube__face { position: absolute; width: 170px; /* Updated from 200px */ height: 170px; /* Updated from 200px */ border: 2px solid black; /* Removed line-height: 200px */ font-size: 16px; /* Adjusted for buttons */ font-weight: bold; color: white; display: flex; /* Added for flex centering */ align-items: center; /* Center vertically */ justify-content: center; /* Center horizontally */ } .cube__face--front { background: hsla( 0, 100%, 50%, 0.7); } .cube__face--right { background: hsla( 60, 100%, 50%, 0.7); } .cube__face--back { background: hsla(120, 100%, 50%, 0.7); } .cube__face--left { background: hsla(180, 100%, 50%, 0.7); } .cube__face--top { background: hsla(240, 100%, 50%, 0.7); } .cube__face--bottom { background: hsla(300, 100%, 50%, 0.7); } .cube__face--front { transform: rotateY( 0deg) translateZ(85px); /* Half of 170px, updated from 100px */ } .cube__face--right { transform: rotateY( 90deg) translateZ(85px); /* Updated translateZ */ } .cube__face--back { transform: rotateY(180deg) translateZ(85px); /* Updated translateZ */ } .cube__face--left { transform: rotateY(-90deg) translateZ(85px); /* Updated translateZ */ } .cube__face--top { transform: rotateX( 90deg) translateZ(85px); /* Updated translateZ */ } .cube__face--bottom { transform: rotateX(-90deg) translateZ(85px); /* Updated translateZ */ } label { margin-right: 10px; } /* Optional: Style buttons to fit nicely */ .cube__face button { padding: 8px 16px; border: none; border-radius: 4px; font-weight: bold; cursor: pointer; }
JavaScript (no changes needed):
var cube = document.querySelector('.cube'); var radioGroup = document.querySelector('.radio-group'); var currentClass = ''; function changeSide() { var checkedRadio = radioGroup.querySelector(':checked'); var showClass = 'show-' + checkedRadio.value; if ( currentClass ) { cube.classList.remove( currentClass ); } cube.classList.add( showClass ); currentClass = showClass; } // set initial side changeSide(); radioGroup.addEventListener( 'change', changeSide );
How It Works
- 3D Alignment: By updating all
translateZ()values to 85px (half of 170px), each face now sits exactly at the cube's edge, eliminating border gaps during rotation. - Button Fit: Using flexbox for
.cube__faceensures buttons (or any content) are perfectly centered and don't overflow the face. The optional button styling makes them look clean and proportional.
Try this code out—your 170px cube will rotate without gaps, and buttons will fit flawlessly on each face!
内容的提问来源于stack exchange,提问作者The_flash

