我尝试在我的网页上做一个选项菜单,就像Gooogle著名的选项菜单一样,使用React:
我调查了很多地方,但我不知道如何做到这一点,我使用CSS香草样式。
kuhbmx9i1#
这是SeboFE创建的codepen code,它是JavaScript代码,但您可以在react中运行它,没有问题。实际上,我确实创建了一个空的react项目,并添加了此笔码,它工作正常。我把代码上传到GetHub了,如果你想看的话.
HTML代码:
<header class="header-grid"> <div id="menu-container" class='menu-container' data-is-closed="true"> <div id="menu-btn" class="menu-btn circle-hover pointer"> <abbr class="clear-df-abbr" title="Google applications"> <svg viewBox="0 0 24 24"> <path d="M6,8c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM12,20c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM6,20c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM6,14c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM12,14c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM16,6c0,1.1 0.9,2 2,2s2,-0.9 2,-2 -0.9,-2 -2,-2 -2,0.9 -2,2zM12,8c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM18,14c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM18,20c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2z"></path> </svg> </abbr> </div> <div id="menu" class="menu"> <div class="icons-container"> <a href="#" class='link bg-hover'> <i class="google-icons avatar-icon"></i> <span>Account</span> </a> <a href="#" class='link bg-hover'> <i class="google-icons search-icon"></i> <span>Search</span> </a> <a href="#" class='link bg-hover'> <i class="google-icons maps-icon"></i> <span>Maps</span> </a> <a href="#" class='link bg-hover'> <i class="google-icons youtube-icon"></i> <span>YouTube</span> </a> <a href="#" class='link bg-hover'> <i class="google-icons play-icon"></i> <span>Play</span> </a> <a href="#" class='link bg-hover'> <i class="google-icons news-icon"></i> <span>News</span> </a> <a href="#" class='link bg-hover'> <i class="google-icons gmail-icon"></i> <span>Gmail</span> </a> <a href="#" class='link bg-hover'> <i class="google-icons meet-icon"></i> <span>Meet</span> </a> <a href="#" class='link bg-hover'> <i class="google-icons contacts-icon"></i> <span>Contacts</span> </a> <a href="#" class='link bg-hover'> <i class="google-icons drive-icon"></i> <span>Drive</span> </a> <a href="#" class='link bg-hover'> <i class="google-icons calendar-icon"></i> <span>Calendar</span> </a> <a href="#" class='link bg-hover'> <i class="google-icons translator-icon"></i> <span>Translator</span> </a> <a href="#" class='link bg-hover'> <i class="google-icons photos-icon"></i> <span>Photos</span> </a> <a href="#" class='link bg-hover'> <i class="google-icons duo-icon"></i> <span>Duo</span> </a> <a href="#" class='link bg-hover'> <i class="google-icons chrome-icon"></i> <span>Chrome</span> </a> <a href="#" class='link bg-hover'> <i class="google-icons shopping-icon"></i> <span>Shopping</span> </a> </div> <div class="divider"></div> <div class="icons-container"> <a href="#" class='link bg-hover'> <i class="google-icons docs-icon"></i> <span>Docs</span> </a> <a href="#" class='link bg-hover'> <i class="google-icons sheets-icon"></i> <span>Sheets</span> </a> <a href="#" class='link bg-hover'> <i class="google-icons presentation-icon"></i> <span>Presentations</span> </a> <a href="#" class='link bg-hover'> <i class="google-icons books-icon"></i> <span>Books</span> </a> <a href="#" class='link bg-hover'> <i class="google-icons blogger-icon"></i> <span>Blogger</span> </a> <a href="#" class='link bg-hover'> <i class="google-icons hangout-icon"></i> <span>Hangouts</span> </a> <a href="#" class='link bg-hover'> <i class="google-icons keep-icon"></i> <span>Keep</span> </a> <a href="#" class='link bg-hover'> <i class="google-icons jamboard-icon"></i> <span>Jamboard</span> </a> <a href="#" class='link bg-hover'> <i class="google-icons earth-icon"></i> <span>Earth</span> </a> <a href="#" class='link bg-hover'> <i class="google-icons collections-icon"></i> <span>Collections</span> </a> <a href="#" class='link bg-hover'> <i class="google-icons art-culture-icon"></i> <span>Art and culture</span> </a> <a href="#" class='link bg-hover'> <i class="google-icons ads-icon"></i> <span>Google Ads</span> </a> <a href="#" class='link bg-hover'> <i class="google-icons podcasts-icon"></i> <span>Podcasts</span> </a> </div> <div class="more-btn-container"> <button class="more-btn pointer">More from Google</button> </div> </div> </div> </header>
JS代码:
document.addEventListener("DOMContentLoaded", main); function main() { document.addEventListener("click", handleBgClick); const menuContainer = document.querySelector("#menu-container"); const isMenuClosedAttrName = 'data-is-closed'; const menuBtn = document.querySelector("#menu-btn"); const menu = document.querySelector("#menu"); menuBtn.addEventListener("click", toggleMenu); menuBtn.addEventListener("click", preventDefault); menu.addEventListener("click", preventDefault); function preventDefault(e) { e.preventDefault(); } function toggleMenu(e) { const isMenuClosed = menuContainer.getAttribute(isMenuClosedAttrName); if (isMenuClosed === 'true') { openMenu(); } else { closeMenu(); } } function openMenu() { menu.scrollTop = 0; menuContainer.setAttribute(isMenuClosedAttrName, 'false'); } function closeMenu() { menuContainer.setAttribute(isMenuClosedAttrName, 'true'); } // Click on background closes menu. function handleBgClick(e) { const wentEventNotThroughMenu = !e.path.includes(menu); const wentEventNotThroughMenuBtn = !e.path.includes(menuBtn); if (wentEventNotThroughMenu && wentEventNotThroughMenuBtn) { closeMenu(); } } }
CSS代码:
body { padding-top:3rem; box-sizing: border-box; color: #202124; font-family: "Google Sans", Roboto, RobotoDraft, Helvetica, Arial, sans-serif; font-size: 14px; letter-spacing: 0.09px; line-height: 18px; overflow: hidden; text-overflow: ellipsis; } :root { --menu-width: auto; --menu-height: 448px; --hover-bg-color: #e8f0fe; --active-bg-color: #d5e0f2; } .clear-df-abbr{ text-decoration: none; } .header-grid { display: grid; justify-items: center; } .menu-container { width: 100px; position: relative; } .menu { position: absolute; top: 150px; left: 50%; transform: translateX(-50%); width: var(--menu-width); height: var(--menu-height); background-color: white; overflow-y: scroll; border: 1px solid rgba(0, 0, 0, 0.2); border-radius: 8px; box-shadow: 0 1px 2px 0 rgba(60, 64, 67, 0.3), 0 2px 6px 2px rgba(60, 64, 67, 0.15); } .menu-btn > svg { text-align: center; height: 48px; width: 48px; position: relative; display: block; color: #5f6368; } [data-is-closed="false"] .menu-btn:before { content: ""; background-color: rgba(60,64,67, 0.2); border-radius: 50%; position: absolute; left: 0; top: 0; width: 100%; height: 100%; transform: scale(1.5); display: block; z-index: -10; } [data-is-closed="true"] .menu { display: none; } .icons-container { display: grid; grid-template-columns: repeat(3, 1fr); justify-items: center; gap: 1.5rem; padding: 20px 16px 20px 20px; } .divider { height: 1px; background-color: #e8eaed; } .link { height: 84px; width: 84px; text-decoration: none; color: initial; position: relative; text-align: center; display: inline-block; z-index: 10; } .link > span { white-space: nowrap; overflow: hidden; width: 76px; display: inline-block; text-overflow: ellipsis; } .bg-hover:hover:before { content: ""; background-color: var(--hover-bg-color); border-radius: 8px; position: absolute; left: 0; top: 0; width: 100%; height: 100%; transform: scale(1.1); display: block; z-index: -10; } [data-is-closed="true"] .circle-hover:hover:before{ content: ""; background-color: rgba(60,64,67,0.08); border-radius: 50%; position: absolute; left: 0; top: 0; width: 100%; height: 100%; transform: scale(1.5); display: block; z-index: -10; } .bg-hover:hover:active:before { background-color: var(--active-bg-color); } .pointer { cursor: pointer; } .google-icons { display: inline-block; height: 64px; vertical-align: top; width: 64px; background-image: url("https://ssl.gstatic.com/gb/images/p1_799229b0.png"); background-size: 64px 2962px; } .avatar-icon { background-position: 0 -2691px; } .search-icon { background-position: 0 -690px; } .gmail-icon { background-position: 0 -1449px; } .drive-icon { background-position: 0 -1380px; } .docs-icon { background-position: 0 -2622px; } .sheets-icon { background-position: 0 -276px; } .presentation-icon { background-position: 0 -1242px; } .calendar-icon { background-position: 0 -2829px; } .chat.icon { background-position: 0 -345px; } .meet-icon { background-position: 0 -2001px; } .sites-icon { background-position: 0 -621px; } .contacts-icon { background-position: 0 -1518px; } .discuss-icon { background-position: 0 -1104px; } .youtube-icon { background-position: 0 -1863px; } .play-icon { background-position: 0 -1035px; } .maps-icon { background-position: 0 -138px; } .news-icon { background-position: 0 -414px; } .photos-icon { background-position: 0 -2760px; } .translator-icon { background-position: 0 -828px; } .duo-icon { background-position: 0 -2346px; } .chrome-icon { background-position: 0 -1725px; } .books-icon { background-position: 0 -2415px; } .art-culture-icon { background-position: 0 -1173px; } .ads-icon { background-position: 0 -552px; } .blogger-icon { background-position: 0 -966px; } .shopping-icon { background-position: 0 -2208px; } .hangout-icon { background-position: 0 -1794px; } .keep-icon { background-position: 0 -897px; } .jamboard-icon { background-position: 0 -1932px; } .earth-icon { background-position: 0 -2277px; } .collections-icon { background-position: 0 -759px; } .podcasts-icon { background-position: 0 -1311px; } /* ----------------- MORE BUTTON -------------- */ .more-btn-container { text-align: center; position: relative; } .more-btn { width: 55%; background-color: white; border: 1px solid #dadce0; border-radius: 4px; color: #1a73e8; font: 500 14px/16px "Google Sans", Roboto, RobotoDraft, Helvetica, Arial, sans-serif; margin: 16px 0 20px 0; padding: 10px 24px; } .more-btn:hover { background-color: var(--hover-bg-color); border-color: var(--active-bg-color); } .more-btn:active { outline: 0; background-color: var(--active-bg-color); } .more-btn:focus { outline: 0; } .more-btn:focus:active { background-color: #ecf3fe; border-color: transparent; box-shadow: 0 1px 2px 0 rgba(60, 64, 67, 0.3), 0 2px 6px 2px rgba(60, 64, 67, 0.15); } /* ----------------- SCROLLBAR -------------- */ ::-webkit-scrollbar { width: 16px; } ::-webkit-scrollbar-thumb { background: #dadce0; background-clip: padding-box; border: 4px solid transparent; border-radius: 8px; box-shadow: none; min-height: 50px; } ::-webkit-scrollbar-track { background: none; border: none; }
w51jfk4q2#
组成部分:
import React from 'react'; export function App(props) { const data = [ { title: 'Maps', imageSrc: '/public/yourimage.png' }, { title: 'Drive', imageSrc: '/public/yourimage.png' }, { title: 'Docs', imageSrc: '/public/yourimage.png' }, { title: 'Mail', imageSrc: '/public/yourimage.png' }, { title: 'Contact', imageSrc: '/public/yourimage.png' }, { title: 'Maps', imageSrc: '/public/yourimage.png' }, { title: 'Drive', imageSrc: '/public/yourimage.png' }, { title: 'Docs', imageSrc: '/public/yourimage.png' }, { title: 'Mail', imageSrc: '/public/yourimage.png' }, { title: 'Contact', imageSrc: '/public/yourimage.png' }, { title: 'Maps', imageSrc: '/public/yourimage.png' }, { title: 'Drive', imageSrc: '/public/yourimage.png' }, { title: 'Docs', imageSrc: '/public/yourimage.png' }, { title: 'Mail', imageSrc: '/public/yourimage.png' }, { title: 'Contact', imageSrc: '/public/yourimage.png' }, ]; return ( <div> <div className="widget"> {data.map((data, i) => <div key={i} className="item"> <img src={data.imageSrc} alt={data.title} /> <h1>{data.title}</h1> </div> )} </div> </div> ); }
CSS:
.widget{ width: 300px; height: 500px; background-color: #fff; border-radius: 10px; position: absolute; top: 20px; right: 20px; display: flex; grid-gap: 1rem; flex-wrap: wrap; overflow: scroll; } .item{ display: flex; flex-direction: column; align-items: center; /* justify-content: start; */ }
可以相应地更改高度和宽度。
2条答案
按热度按时间kuhbmx9i1#
这是SeboFE创建的codepen code,它是JavaScript代码,但您可以在react中运行它,没有问题。
实际上,我确实创建了一个空的react项目,并添加了此笔码,它工作正常。
我把代码上传到GetHub了,如果你想看的话.
HTML代码:
JS代码:
CSS代码:
w51jfk4q2#
组成部分:
CSS:
可以相应地更改高度和宽度。