
| <!DOCTYPE html> |
| <html lang="en" > |
| <head> |
| <meta charset="UTF-8"> |
| <title>搜索框设计</title> |
| <link rel="stylesheet" href="./style.css"> |
| </head> |
| <body> |
| <div class="search-overlay"></div> |
| <div class="scroll-cont"> |
| <div class="content"> |
| <div class="search"> |
| <div class="search_bg"></div> |
| <div class="search_box"> |
| <input type="text" class="search_input" placeholder="Search"/> |
| <div class="search_line"></div> |
| <div class="search_close"></div> |
| </div> |
| </div> |
| </div> |
| </div> |
| |
| <script src="./script.js"></script> |
| </body> |
| </html> |
复制
| (function() { |
| var $searchOverlay = document.querySelector(".search-overlay"); |
| var $search = document.querySelector(".search"); |
| var $clone, offsetX, offsetY; |
| |
| $search.addEventListener("click", function() { |
| var $original = this; |
| $clone = this.cloneNode(true); |
| |
| $searchOverlay.classList.add("s--active"); |
| |
| $clone.classList.add("s--cloned", "s--hidden"); |
| $searchOverlay.appendChild($clone); |
| |
| var triggerLayout = $searchOverlay.offsetTop; |
| |
| var originalRect = $original.getBoundingClientRect(); |
| var cloneRect = $clone.getBoundingClientRect(); |
| |
| offsetX = originalRect.left - cloneRect.left; |
| offsetY = originalRect.top - cloneRect.top; |
| |
| $clone.style.transform = "translate("+ offsetX +"px, "+ offsetY +"px)"; |
| $original.classList.add("s--hidden"); |
| $clone.classList.remove("s--hidden"); |
| |
| var triggerLayout = $searchOverlay.offsetTop; |
| |
| $clone.classList.add("s--moving"); |
| |
| $clone.setAttribute("style", ""); |
| |
| $clone.addEventListener("transitionend", openAfterMove); |
| }); |
| |
| function openAfterMove() { |
| $clone.classList.add("s--active"); |
| $clone.querySelector("input").focus(); |
| |
| addCloseHandler($clone); |
| $clone.removeEventListener("transitionend", openAfterMove); |
| }; |
| |
| function addCloseHandler($parent) { |
| var $closeBtn = $parent.querySelector(".search_close"); |
| $closeBtn.addEventListener("click", closeHandler); |
| }; |
| |
| |
| function closeHandler(e) { |
| $clone.classList.remove("s--active"); |
| e.stopPropagation(); |
| |
| var $cloneBg = $clone.querySelector(".search_bg"); |
| |
| $cloneBg.addEventListener("transitionend", moveAfterClose); |
| }; |
| |
| function moveAfterClose(e) { |
| e.stopPropagation(); |
| |
| $clone.classList.add("s--moving"); |
| $clone.style.transform = "translate("+ offsetX +"px, "+ offsetY +"px)"; |
| $clone.addEventListener("transitionend", terminateSearch); |
| }; |
| |
| function terminateSearch(e) { |
| $search.classList.remove("s--hidden"); |
| $clone.remove(); |
| $searchOverlay.classList.remove("s--active"); |
| }; |
| }()); |
复制
| *, *:before, *:after { |
| box-sizing: border-box; |
| margin: 0; |
| padding: 0; |
| } |
| |
| html, body { |
| height: 100%; |
| background-image: url(https://source.unsplash.com/6ZZh8kOyW-4); |
| background-size: cover; |
| } |
| |
| .search-overlay { |
| z-index: -1000; |
| overflow: hidden; |
| position: fixed; |
| left: 0; |
| top: 0; |
| width: 100%; |
| height: 100%; |
| } |
| |
| .search-overlay.s--active { |
| z-index: 9999; |
| } |
| |
| .scroll-cont { |
| position: relative; |
| height: 100%; |
| overflow-y: auto; |
| } |
| |
| .content { |
| padding: 50px; |
| } |
| |
| .search { |
| position: relative; |
| margin: 0 auto 50px; |
| width: 100px; |
| height: 100px; |
| perspective: 1000px; |
| } |
| |
| .search:not(.s--active) { |
| cursor: pointer; |
| } |
| |
| .search.s--hidden { |
| opacity: 0; |
| } |
| |
| .search.s--cloned { |
| position: absolute; |
| left: 50%; |
| top: 50%; |
| right: auto; |
| bottom: auto; |
| margin-left: -58px; |
| margin-top: -58px; |
| margin-right: 0; |
| margin-bottom: 0; |
| } |
| |
| .search.s--moving { |
| transition: transform 0.4s cubic-bezier(0.56, -0.49, 0.58, 0.9); |
| } |
| |
| .search_bg { |
| position: absolute; |
| left: 50%; |
| top: 50%; |
| width: 100%; |
| height: 100%; |
| border-radius: 50%; |
| background: rgba(236, 83, 83, 0.8); |
| transition: all 0.6s ease; |
| transform: translate3d(-50%, -50%, 0); |
| will-change: transform; |
| } |
| |
| .search.s--active .search_bg { |
| transform: translate3d(-50%, -50%, 0) scale(48); |
| } |
| |
| .search_box { |
| position: absolute; |
| left: 50%; |
| top: 50%; |
| width: 40px; |
| height: 40px; |
| border: 4px solid #fff; |
| border-radius: 25px; |
| transform: translate(-50%, -50%); |
| transition: all 0.45s ease; |
| } |
| |
| .search.s--active .search_box { |
| width: 510px; |
| height: 100px; |
| border-radius: 50px; |
| } |
| |
| .search_input { |
| width: 100%; |
| height: 100%; |
| background: transparent; |
| border: none; |
| outline: none; |
| pointer-events: none; |
| opacity: 0; |
| color: #fff; |
| font-size: 40px; |
| transition: opacity 0s; |
| } |
| |
| .search_input::-moz-placeholder { |
| color: rgba(255, 255, 255, 0.4); |
| } |
| |
| .search_input:-ms-input-placeholder { |
| color: rgba(255, 255, 255, 0.4); |
| } |
| |
| .search_input::placeholder { |
| color: rgba(255, 255, 255, 0.4); |
| } |
| |
| .search.s--active .search_input { |
| padding: 23px 90px 23px 40px; |
| pointer-events: auto; |
| opacity: 1; |
| transition: opacity 0.18s 0.48s; |
| } |
| |
| .search_line { |
| position: absolute; |
| left: 50%; |
| top: 50%; |
| width: 20px; |
| height: 4px; |
| border-radius: 2px; |
| background: #fff; |
| transform-origin: 0 50%; |
| transform: translate(12px, 12px) rotate(45deg); |
| transition: all 0.48s; |
| } |
| |
| .search_line:before { |
| content: ""; |
| position: absolute; |
| left: 0; |
| bottom: 0; |
| width: inherit; |
| height: inherit; |
| background: inherit; |
| border-radius: inherit; |
| transform: rotate(90deg); |
| opacity: 0; |
| transition: opacity 0.3s; |
| } |
| |
| .search.s--active .search_line:before { |
| opacity: 1; |
| transition: opacity 0.3s 0.42s; |
| } |
| |
| .search.s--active .search_line { |
| width: 36px; |
| height: 6px; |
| transform: translate(180px, 11px) rotate(-45deg); |
| } |
| |
| .search_close { |
| position: absolute; |
| right: 0; |
| top: 0; |
| width: 30px; |
| height: 30px; |
| pointer-events: none; |
| } |
| |
| .search.s--active .search_close { |
| right: 44px; |
| top: 33px; |
| pointer-events: auto; |
| cursor: pointer; |
| } |
复制