About this snippet

Design a spatial computing dock inspired by WebXR interfaces. We calculated mouse proximity using vanilla JavaScript so the icons scale dynamically and smoothly as you hover across the dock.

Size
3.9 KB
Uses
HTML, CSS, JavaScript
Loads
placehold.co
Views
218
<div class="vision-space">
  <div class="vision-dock" id="vision-dock">
    <div class="dock-app">
      <div class="app-icon">
        <svg viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path></svg>
      </div>
      <div class="app-dot"></div>
    </div>
    <div class="dock-app">
      <div class="app-icon">
        <svg viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"></circle><polyline points="12 6 12 12 16 14"></polyline></svg>
      </div>
      <div class="app-dot active"></div>
    </div>
    <div class="dock-app">
      <div class="app-icon">
        <svg viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path></svg>
      </div>
      <div class="app-dot"></div>
    </div>
    <div class="dock-app">
      <div class="app-icon">
        <svg viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2"><rect x="2" y="3" width="20" height="14" rx="2" ry="2"></rect><line x1="8" y1="21" x2="16" y2="21"></line><line x1="12" y1="17" x2="12" y2="21"></line></svg>
      </div>
      <div class="app-dot active"></div>
    </div>
    <div class="dock-app">
      <div class="app-icon">
        <svg viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 2.69l5.66 4.2c.42.31.7.77.7 1.3v8.62a2 2 0 0 1-2 2H7.64a2 2 0 0 1-2-2V8.19c0-.53.28-.99.7-1.3L12 2.69z"></path></svg>
      </div>
      <div class="app-dot"></div>
    </div>
  </div>
</div>
*, *::before, *::after {
  box-sizing: border-box;
}

body {
  font-family: system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
  margin: 0;
  background: url("https://placehold.co/1920x1080/1e293b/0f172a?text=Immersive+Background") center/cover;
  display: flex;
  justify-content: center;
  align-items: flex-end;
  min-height: 100vh;
  padding-bottom: 40px;
}

.vision-space {
  perspective: 1000px;
}

.vision-dock {
  display: flex;
  align-items: flex-end;
  gap: 16px;
  background: rgba(255, 255, 255, 0.15);
  backdrop-filter: blur(30px);
  border: 1px solid rgba(255, 255, 255, 0.3);
  padding: 16px 24px;
  border-radius: 36px;
  box-shadow: 0 30px 60px rgba(0, 0, 0, 0.4), inset 0 1px 1px rgba(255, 255, 255, 0.5);
  transform: rotateX(10deg);
  transition: transform 0.4s ease;
}

.vision-dock:hover {
  transform: rotateX(0deg);
}

.dock-app {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
}

.app-icon {
  width: 56px;
  height: 56px;
  background: rgba(255, 255, 255, 0.9);
  border-radius: 16px;
  display: flex;
  justify-content: center;
  align-items: center;
  color: #0f172a;
  box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2);
  cursor: pointer;
  transition: transform 0.15s cubic-bezier(0.2, 0.8, 0.2, 1);
  will-change: transform;
}

.app-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: transparent;
  transition: background 0.3s;
}

.app-dot.active {
  background: #ffffff;
  box-shadow: 0 0 8px #ffffff;
}
const dock = document.getElementById("vision-dock");
const icons = document.querySelectorAll(".app-icon");

dock.addEventListener("mousemove", function(e) {
  icons.forEach(function(icon) {
    const rect = icon.getBoundingClientRect();
    const centerX = rect.left + rect.width / 2;
    const distance = Math.abs(e.clientX - centerX);
    
    const maxDist = 150;
    let scale = 1;
    
    if (distance < maxDist) {
      scale = 1 + (0.6 * (1 - distance / maxDist));
    }
    
    icon.style.transform = "scale(" + scale + ") translateY(-" + ((scale - 1) * 30) + "px)";
  });
});

dock.addEventListener("mouseleave", function() {
  icons.forEach(function(icon) {
    icon.style.transform = "scale(1) translateY(0)";
  });
});
Esc
↑↓ moveEnter select

Start from a template

Open an .html file, or HTML, CSS, JS, Markdown, Less or TypeScript files. You can also drop them here. Styles and scripts go into their panes.

Share

Source

Keyboard shortcuts

Save