HTML+CSS+JS 自定义下拉菜单

效果演示

20-自定义下拉菜单.gif

实现了一个下拉菜单的动画效果,包括一个主按钮和一个下拉菜单列表。点击主按钮会展开下拉菜单列表,同时箭头会旋转,列表项会逐渐显示出来。鼠标悬停在列表上时,会出现一个浮动图标。整个下拉菜单的样式比较简洁,使用了黑色和灰色的背景色,以及白色和淡灰色的文字和图标颜色。动画效果使用了 CSS 的过渡和变换属性。

Code

HTML
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>自定义下拉菜单</title>
    <link rel="stylesheet" href="./20-自定义下拉菜单.css">
</head>

<body>
    <div class="dropdown-container">
        <button class="dropdown-button main-button">
            <span class="dropdown-title-icon">
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024">
                    <path
                        d="M937.4 423.9c-84 0-165.7-27.3-232.9-77.8v352.3c0 179.9-138.6 325.6-309.6 325.6S85.3 878.3 85.3 698.4c0-179.9 138.6-325.6 309.6-325.6 17.1 0 33.7 1.5 49.9 4.3v186.6c-15.5-6.1-32-9.2-48.6-9.2-76.3 0-138.2 65-138.2 145.3 0 80.2 61.9 145.3 138.2 145.3 76.2 0 138.1-65.1 138.1-145.3V0H707c0 134.5 103.7 243.5 231.6 243.5v180.3l-1.2 0.1"
                        p-id="1556"></path>
                </svg>
            </span>
            <span class="dropdown-title text-truncate">抖音</span>
            <span class="dropdown-arrow">
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
                    <path
                        d="M7.247 11.14 2.451 5.658C1.885 5.013 2.345 4 3.204 4h9.592a1 1 0 0 1 .753 1.659l-4.796 5.48a1 1 0 0 1-1.506 0z" />
                </svg>
            </span>
        </button>
        <div class="dropdown-list-container">
            <div class="dropdown-list-wrapper">
                <ul class="dropdown-list"></ul>
                <div class="floating-icon" aria-hidden="true"></div>
            </div>
        </div>
    </div>
</body>
<script src="./20-自定义下拉菜单.js"></script>
</html>
CSS
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

:root {
    --rotate-arrow: 0;
    --dropdown-height: 0;
    --list-opacity: 0;
    --translate-value: 0;
    --floating-icon-size: 26;
    --floating-icon-top: 0;
    --floating-icon-left: 0;
}

html {
    font-size: 80%;
}

body {
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    background-color: #222429;
    padding: 1.5rem;
    line-height: 1.4rem;
}

button {
    border: none;
    background-color: transparent;
    cursor: pointer;
    outline: none;
}

svg {
    width: 1.6rem;
    height: 1.6rem;
}

.text-truncate {
    text-overflow: ellipsis;
    overflow: hidden;
    white-space: nowrap;
}

.dropdown-container {
    margin-top: 30vh;
    display: flex;
    flex-direction: column;
    width: 100%;
    max-width: 34rem;
}

.dropdown-title-icon,
.dropdown-arrow {
    display: inline-flex;
}

.dropdown-title {
    margin: 0 auto 0 1.8rem;
}

.dropdown-button {
    font-weight: 400;
    font-size: 1.7rem;
    display: flex;
    align-items: center;
    padding: 0 1.8rem;
}

.dropdown-button svg {
    fill: #b1b8ca;
    transition: all 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

.dropdown-button svg,
.dropdown-button span {
    pointer-events: none;
}

.dropdown-button:hover,
.dropdown-button:focus {
    color: #fff;
}

.dropdown-button:hover svg,
.dropdown-button:focus svg {
    fill: #fff;
}

.main-button {
    height: 5.2rem;
    background-color: #333740;
    color: #b1b8ca;
    border-radius: 1.4rem;
    border: 0.1rem solid #494d59;
    transition: all 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

.main-button:focus {
    border: 0.1rem solid #2c62f6;
    box-shadow: 0 0 0 0.2rem rgba(44, 98, 246, 0.4);
}

.main-button .dropdown-arrow {
    margin-left: 1.8rem;
    transform: rotate(var(--rotate-arrow));
    transition: transform 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

.list-button {
    height: 4.6rem;
    color: #b1b8ca;
    overflow: hidden;
    cursor: none;
    transition: color 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

.dropdown-list-container {
    overflow: hidden;
    max-height: var(--dropdown-height);
    transition: max-height 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

.dropdown-list-wrapper {
    margin-top: 1rem;
    padding: 1rem;
    background-color: #333740;
    border-radius: 1.4rem;
    border: 0.1rem solid #494d59;
    position: relative;
}

ul.dropdown-list {
    position: relative;
    list-style-type: none;
}

ul.dropdown-list::before {
    content: "";
    position: absolute;
    top: 0;
    right: 0;
    left: 0;
    z-index: 0;
    opacity: 0;
    height: 4.6rem;
    background-color: #2b2e34;
    border-radius: 1.4rem;
    pointer-events: none;
    transform: translateY(var(--translate-value));
    transition: all 0.4s linear;
}

li.dropdown-list-item {
    display: flex;
    flex-direction: column;
    position: relative;
    z-index: 1;
    opacity: var(--list-opacity);
    transition: opacity 0.8s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

.floating-icon {
    width: calc(var(--floating-icon-size) * 1px);
    height: calc(var(--floating-icon-size) * 1px);
    position: absolute;
    left: var(--floating-icon-left);
    top: var(--floating-icon-top);
    background-color: #494d59;
    border-radius: 1rem;
    pointer-events: none;
    opacity: 0;
    z-index: 2;
    display: inline-flex;
    justify-content: center;
    align-items: center;
    transition: opacity 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

.floating-icon svg {
    fill: #fff;
}

ul.dropdown-list:hover::before,
ul.dropdown-list:hover ~ .floating-icon {
    opacity: 1;
}
JavaScript
const root=document.documentElement;
const dropdown_title_icon=document.querySelector(".dropdown-title-icon");
const dropdown_title=document.querySelector(".dropdown-title");
const dropdown_list=document.querySelector(".dropdown-list");
const main_button=document.querySelector(".main-button");
const floating_icon=document.querySelector(".floating-icon");

const icons={
    "百度":
        "M226.8 535.7c96.8-20.8 83.6-136.4 80.6-161.7-4.8-39-50.6-107.2-112.8-101.8-78.3 7-89.8 120.2-89.8 120.2-10.5 52.3 25.4 164.1 122 143.3z m102.7 201.1c-2.9 8.2-9.1 28.9-3.7 47 10.8 40.6 46.1 42.4 46.1 42.4h50.7V702.4h-54.2c-24.5 7.3-36.3 26.3-38.9 34.4z m76.8-395c53.5 0 96.6-61.5 96.6-137.6 0-76-43.1-137.5-96.6-137.5-53.4 0-96.6 61.5-96.6 137.5 0 76.1 43.2 137.6 96.6 137.6z m230.2 9.1c71.4 9.3 117.4-67 126.4-124.8 9.3-57.6-36.8-124.7-87.3-136.2-50.7-11.6-113.9 69.5-119.7 122.4-6.8 64.8 9.3 129.4 80.6 138.6z m175 339.6S701 605 636.5 512.6c-87.4-136.3-211.7-80.8-253.2-11.6-41.4 69.3-105.8 113.1-115 124.7-9.3 11.5-133.5 78.5-105.9 200.9C189.9 949 286.8 946.8 286.8 946.8s71.3 7 154.2-11.5c82.8-18.4 154.1 4.6 154.1 4.6s193.4 64.7 246.4-60c52.8-124.8-30-189.4-30-189.4z m-331 185.6H354.8c-54.3-10.9-76-47.9-78.7-54.2-2.7-6.4-18.1-36.2-9.9-86.9 23.5-76 90.4-81.4 90.4-81.4h66.9v-82.3l57 0.9v303.9z m234.3-0.9H570c-56.1-14.4-58.7-54.3-58.7-54.3v-160l58.7-1v143.8c3.6 15.3 22.7 18.2 22.7 18.2h59.6v-161h62.5v214.3z m204.8-427.3c0-27.6-22.9-110.9-108.1-110.9-85.3 0-96.7 78.6-96.7 134.1 0 53 4.5 127.1 110.5 124.6 106-2.3 94.3-120 94.3-147.8z m0 0",
    "微信":
        "M308.73856 119.23456C23.65696 170.15296-71.37024 492.23936 155.392 639.66464c12.43392 7.99232 12.43392 7.104-6.21824 62.76096l-15.98464 47.65952 57.43104-30.784 57.43104-30.78656 30.49216 7.40096c31.96928 7.99232 72.82432 13.61664 100.0576 13.61664l16.28416 0-5.62688-21.61152c-44.70016-164.5952 109.82912-327.71072 310.8352-327.71072l27.2384 0-5.62432-19.53792C677.59616 186.43456 491.392 86.67136 308.73856 119.23456zM283.87072 263.40352c30.1952 20.4288 31.97184 64.5376 2.95936 83.48416-47.06816 30.78656-102.1312-23.38816-70.45632-69.57056C230.28736 256.59648 263.74144 249.78688 283.87072 263.40352zM526.62016 263.40352c49.73568 33.45408 12.43392 110.71744-43.22304 89.40288-40.25856-15.39328-44.99712-70.75072-7.40096-90.5856C490.79808 254.22848 513.88928 254.81984 526.62016 263.40352zM636.44928 385.37216c-141.2096 25.7536-239.19872 132.91776-233.57184 256.06656 7.40096 164.89472 200.71168 278.56896 386.32448 227.65312l21.90592-5.92128 46.1824 24.8704c25.4592 13.9136 46.77376 23.97696 47.36512 22.79168 0.59392-1.47968-4.43648-19.24352-10.95168-39.6672-14.79936-45.59104-15.09632-42.33472 4.73856-56.54272C1121.64864 654.464 925.67552 332.97408 636.44928 385.37216zM630.82496 518.28992c12.4288 8.28928 18.944 29.01248 13.61408 44.1088-11.24864 32.26624-59.49952 34.63424-72.52992 3.55328C557.10976 530.13248 597.9648 496.97536 630.82496 518.28992zM828.57472 521.84576c19.53792 18.64704 16.2816 50.32448-6.51264 62.16448-34.93376 17.76128-71.63904-17.76128-53.58336-51.80416C780.32128 510.2976 810.81344 504.97024 828.57472 521.84576z",
    "抖音":
        "M937.4 423.9c-84 0-165.7-27.3-232.9-77.8v352.3c0 179.9-138.6 325.6-309.6 325.6S85.3 878.3 85.3 698.4c0-179.9 138.6-325.6 309.6-325.6 17.1 0 33.7 1.5 49.9 4.3v186.6c-15.5-6.1-32-9.2-48.6-9.2-76.3 0-138.2 65-138.2 145.3 0 80.2 61.9 145.3 138.2 145.3 76.2 0 138.1-65.1 138.1-145.3V0H707c0 134.5 103.7 243.5 231.6 243.5v180.3l-1.2 0.1",
    "哔哩哔哩":
        "M306.005333 117.632L444.330667 256h135.296l138.368-138.325333a42.666667 42.666667 0 0 1 60.373333 60.373333L700.330667 256H789.333333A149.333333 149.333333 0 0 1 938.666667 405.333333v341.333334a149.333333 149.333333 0 0 1-149.333334 149.333333h-554.666666A149.333333 149.333333 0 0 1 85.333333 746.666667v-341.333334A149.333333 149.333333 0 0 1 234.666667 256h88.96L245.632 177.962667a42.666667 42.666667 0 0 1 60.373333-60.373334zM789.333333 341.333333h-554.666666a64 64 0 0 0-63.701334 57.856L170.666667 405.333333v341.333334a64 64 0 0 0 57.856 63.701333L234.666667 810.666667h554.666666a64 64 0 0 0 63.701334-57.856L853.333333 746.666667v-341.333334A64 64 0 0 0 789.333333 341.333333zM341.333333 469.333333a42.666667 42.666667 0 0 1 42.666667 42.666667v85.333333a42.666667 42.666667 0 0 1-85.333333 0v-85.333333a42.666667 42.666667 0 0 1 42.666666-42.666667z m341.333334 0a42.666667 42.666667 0 0 1 42.666666 42.666667v85.333333a42.666667 42.666667 0 0 1-85.333333 0v-85.333333a42.666667 42.666667 0 0 1 42.666667-42.666667z",
    "淘宝":
        "M168.5 273.7a68.7 68.7 0 1 0 137.4 0 68.7 68.7 0 1 0-137.4 0z m730 79.2s-23.7-184.4-426.9-70.1c17.3-30 25.6-49.5 25.6-49.5L396.4 205s-40.6 132.6-113 194.4c0 0 70.1 40.6 69.4 39.4 20.1-20.1 38.2-40.6 53.7-60.4 16.1-7 31.5-13.6 46.7-19.8-18.6 33.5-48.7 83.8-78.8 115.6l42.4 37s28.8-27.7 60.4-61.2h36v61.8H372.9v49.5h140.3v118.5c-1.7 0-3.6 0-5.4-0.2-15.4-0.7-39.5-3.3-49-18.2-11.5-18.1-3-51.5-2.4-71.9h-97l-3.4 1.8s-35.5 159.1 102.3 155.5c129.1 3.6 203-36 238.6-63.1l14.2 52.6 79.6-33.2-53.9-131.9-64.6 20.1 12.1 45.2c-16.6 12.4-35.6 21.7-56.2 28.4V561.3h137.1v-49.5H628.1V450h137.6v-49.5H521.3c17.6-21.4 31.5-41.1 35-53.6l-42.5-11.6c182.8-65.5 284.5-54.2 283.6 53.2v282.8s10.8 97.1-100.4 90.1l-60.2-12.9-14.2 57.1S882.5 880 903.7 680.2c21.3-200-5.2-327.3-5.2-327.3z m-707.4 18.3l-45.4 69.7 83.6 52.1s56 28.5 29.4 81.9C233.8 625.5 112 736.3 112 736.3l109 68.1c75.4-163.7 70.5-142 89.5-200.7 19.5-60.1 23.7-105.9-9.4-139.1-42.4-42.6-47-46.6-110-93.4z"
};

// 下拉列表项
const list_items=["百度","微信","抖音","哔哩哔哩","淘宝"];

const iconTemplate=(path)=>{
    return `
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024">
            <path d="${path}"></path>
        </svg>
    `;
}

const listItemTemplate=(text,translate_value)=>{
    return `
        <li class="dropdown-list-item">
            <button class="dropdown-button list-button" data-translate-value="${translate_value}%">
                <span class="text-truncate">${text}</span>
            </button>
        </li>
    `;
}

const renderListItems=()=>{
    dropdown_list.innerHTML+=list_items.map((item,index)=>{
        return listItemTemplate(item,100*index);
    }).join("");
}

window.addEventListener("load",()=>{
    renderListItems();
})

const setDropdownProps=(deg,ht,opacity)=>{
    root.style.setProperty("--rotate-arrow",deg!==0?deg+"deg":0);
    root.style.setProperty("--dropdown-height",ht!==0?ht+"rem":0);
    root.style.setProperty("--list-opacity",opacity);
}

main_button.addEventListener("click",()=>{
    const list_wrapper_sizes=3.5;
    const dropdown_open_height=4.6*list_items.length+list_wrapper_sizes;
    const curr_dropdown_height=root.style.getPropertyValue("--dropdown-height")||0;
    curr_dropdown_height==="0"?setDropdownProps(180,dropdown_open_height,1):setDropdownProps(0,0,0);
})

dropdown_list.addEventListener("mouseover",(e)=>{
    const translate_value=e.target.dataset.translateValue;
    root.style.setProperty("--translate-value",translate_value);
})

dropdown_list.addEventListener("click",(e)=>{
    const clicked_item_text=e.target.innerText.toLowerCase().trim();
    const clicked_item_icon=icons[clicked_item_text];
    dropdown_title_icon.innerHTML=iconTemplate(clicked_item_icon);
    dropdown_title.innerHTML=clicked_item_text;
    setDropdownProps(0,0,0);
})

dropdown_list.addEventListener("mousemove",(e)=>{
    const icon_size=root.style.getPropertyValue("--floating-icon-size")||0;
    const x=e.clientX-dropdown_list.getBoundingClientRect().x;
    const y=e.clientY-dropdown_list.getBoundingClientRect().y;
    const targetText=e.target.innerText.toLowerCase().trim();
    const hover_item_text=icons[targetText];
    floating_icon.innerHTML=iconTemplate(hover_item_text);
    root.style.setProperty("--floating-icon-left",x-icon_size/2+"px");
    root.style.setProperty("--floating-icon-top",y-icon_size/2+"px");
})

实现思路拆分

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

这段代码是设置所有元素的外边距和内边距为0,并且使用border-box盒模型。

:root {
    --rotate-arrow: 0;
    --dropdown-height: 0;
    --list-opacity: 0;
    --translate-value: 0;
    --floating-icon-size: 26;
    --floating-icon-top: 0;
    --floating-icon-left: 0;
}

这段代码是定义了一些CSS变量,用于后面的样式中。

html {
    font-size: 80%;
}

这段代码是设置HTML元素的字体大小为80%。

body {
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    background-color: #222429;
    padding: 1.5rem;
    line-height: 1.4rem;
}

这段代码是设置body元素的高度为100%,并且使用flex布局,使其垂直居中。同时设置了背景色、内边距和行高。

button {
    border: none;
    background-color: transparent;
    cursor: pointer;
    outline: none;
}

这段代码是设置按钮元素的样式,去掉边框、背景色和轮廓线,并且设置光标为手型。

svg {
    width: 1.6rem;
    height: 1.6rem;
}

这段代码是设置SVG元素的宽度和高度为1.6rem。

.text-truncate {
    text-overflow: ellipsis;
    overflow: hidden;
    white-space: nowrap;
}

这段代码是定义了一个CSS类,用于截断文本并显示省略号。

.dropdown-container {
    margin-top: 30vh;
    display: flex;
    flex-direction: column;
    width: 100%;
    max-width: 34rem;
}

这段代码是设置下拉菜单容器的样式,包括垂直方向的外边距、使用flex布局、宽度和最大宽度。

.dropdown-title-icon,
.dropdown-arrow {
    display: inline-flex;
}

这段代码是设置下拉菜单标题图标和箭头的样式,使用inline-flex布局。

.dropdown-title {
    margin: 0 auto 0 1.8rem;
}

这段代码是设置下拉菜单标题的样式,包括左外边距和居中对齐。

.dropdown-button {
    font-weight: 400;
    font-size: 1.7rem;
    display: flex;
    align-items: center;
    padding: 0 1.8rem;
}

这段代码是设置下拉菜单按钮的样式,包括字体粗细、字体大小、使用flex布局、垂直居中和内边距。

.dropdown-button svg,
.dropdown-button span {
    pointer-events: none;
}

这段代码是设置下拉菜单按钮中的SVG图标和文本不响应鼠标事件。

.dropdown-button svg {
    fill: #b1b8ca;
    transition: all 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

这段代码是设置下拉菜单按钮中的SVG图标的填充颜色,并且设置过渡效果。

.dropdown-button:hover,
.dropdown-button:focus {
    color: #fff;
}

这段代码是设置下拉菜单按钮在鼠标悬停或获得焦点时的文本颜色。

.dropdown-button:hover svg,
.dropdown-button:focus svg {
    fill: #fff;
}

这段代码是设置下拉菜单按钮在鼠标悬停或获得焦点时的SVG图标填充颜色。

.main-button {
    height: 5.2rem;
    background-color: #333740;
    color: #b1b8ca;
    border-radius: 1.4rem;
    border: 0.1rem solid #494d59;
    transition: all 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

这段代码是设置下拉菜单主按钮的样式,包括高度、背景色、文本颜色、圆角和边框,并且设置过渡效果。

.main-button:focus {
    border: 0.1rem solid #2c62f6;
    box-shadow: 0 0 0 0.2rem rgba(44, 98, 246, 0.4);
}

这段代码是设置下拉菜单主按钮在获得焦点时的边框和阴影效果。

.main-button .dropdown-arrow {
    margin-left: 1.8rem;
    transform: rotate(var(--rotate-arrow));
    transition: transform 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

这段代码是设置下拉菜单主按钮中的箭头的样式,包括左外边距和旋转效果,并且设置过渡效果。

.list-button {
    height: 4.6rem;
    color: #b1b8ca;
    overflow: hidden;
    cursor: none;
    transition: color 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

这段代码是设置下拉菜单列表项的样式,包括高度、文本颜色、隐藏溢出内容和禁用鼠标光标。

.dropdown-list-container {
    overflow: hidden;
    max-height: var(--dropdown-height);
    transition: max-height 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

这段代码是设置下拉菜单列表容器的样式,包括隐藏溢出内容和设置最大高度,并且设置过渡效果。

.dropdown-list-wrapper {
    margin-top: 1rem;
    padding: 1rem;
    background-color: #333740;
    border-radius: 1.4rem;
    border: 0.1rem solid #494d59;
    position: relative;
}

这段代码是设置下拉菜单列表的样式,包括上外边距、内边距、背景色、圆角和边框,并且设置相对定位。

ul.dropdown-list {
    position: relative;
    list-style-type: none;
}

这段代码是设置下拉菜单列表的样式,包括相对定位和去掉列表项的默认样式。

ul.dropdown-list::before {
    content: "";
    position: absolute;
    top: 0;
    right: 0;
    left: 0;
    z-index: 0;
    opacity: 0;
    height: 4.6rem;
    background-color: #2b2e34;
    border-radius: 1.4rem;
    pointer-events: none;
    transform: translateY(var(--translate-value));
    transition: all 0.4s linear;
}

这段代码是设置下拉菜单列表的伪元素样式,包括绝对定位、透明度、高度、背景色、圆角、不响应鼠标事件和垂直方向的平移效果,并且设置过渡效果。

li.dropdown-list-item {
    display: flex;
    flex-direction: column;
    position: relative;
    z-index: 1;
    opacity: var(--list-opacity);
    transition: opacity 0.8s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

这段代码是设置下拉菜单列表项的样式,包括使用flex布局、相对定位、层级、透明度和过渡效果。

.floating-icon {
    width: calc(var(--floating-icon-size) * 1px);
    height: calc(var(--floating-icon-size) * 1px);
    position: absolute;
    left: var(--floating-icon-left);
    top: var(--floating-icon-top);
    background-color: #494d59;
    border-radius: 1rem;
    pointer-events: none;
    opacity: 0;
    z-index: 2;
    display: inline-flex;
    justify-content: center;
    align-items: center;
    transition: opacity 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

这段代码是设置下拉菜单列表项中的浮动图标的样式,包括宽度、高度、绝对定位、左上角位置、背景色、圆角、不响应鼠标事件、透明度、层级、使用inline-flex布局、垂直居中和过渡效果。

.floating-icon svg {
    fill: #fff;
}

这段代码是设置下拉菜单列表项中的浮动图标中的SVG图标的填充颜色。

ul.dropdown-list:hover::before,
ul.dropdown-list:hover ~ .floating-icon {
    opacity: 1;
}

这段代码是设置下拉菜单列表在鼠标悬停时的伪元素和浮动图标的透明度为1,以显示出来。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/704221.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

vue3第三十九节(TS中的高级类型,分类以及使用注意事项)

前言&#xff1a;为什么需要使用高级类型&#xff0c;正常的类型不能满足日常的业务需求&#xff0c;对于复杂的数据结构、函数签名、类型转换&#xff0c;我们需要使用高级类型来处理&#xff0c;常用的高级类型包含以下几种&#xff1a; 常用的类型定义&#xff1a; 基本类…

理解 GPIO 的推挽与开漏

在日常的嵌入式开发过程当中&#xff0c;GPIO可以说是接触最多的外设了。小到点亮一个LED灯&#xff0c;大到模拟总线通讯&#xff0c;都必不可少地需要用到GPIO资源。而对于GPIO的两大输出模式 ——推挽输出和开漏输出&#xff0c;你是否真正理解了呢&#xff1f; 首先我们看…

HCIA14 DHCP 实验

动态主机配置协议 DHCP&#xff08;Dynamic Host Configuration Protocol&#xff09;由 RFC 2131 定义&#xff0c;采用客户端/服务器通信模式&#xff0c;由客户端&#xff08;DHCP Client&#xff09;向服务器&#xff08;DHCP Server&#xff09;提出配置申请&#xff0c;服…

哈希应用——布隆过滤器

布隆过滤器的提出 场景一&#xff1a;在注册账号设置昵称的时候&#xff0c;为了保证每个用户昵称的唯一性&#xff0c;系统必须检测你输入的昵称是否被使用过&#xff0c;这本质就是一个key的模型&#xff0c;我们只需要判断这个昵称被用过&#xff0c;还是没被用过。 场景二&…

声学气膜馆:高品质声效与灵活应用的完美结合—轻空间

声学气膜馆是一种结合气膜建筑和声学优化的新型场馆。这种建筑形式不仅可以快速搭建和灵活使用&#xff0c;还能提供出色的声学效果&#xff0c;非常适合用于音乐演出、体育比赛、会议展览等多种场合。 气膜建筑的声学优势 气膜建筑利用空气压力支撑膜材&#xff0c;形成稳定的…

计算机图形学入门09:深度缓存

在前面知道了怎么将一个三角形显示到屏幕上&#xff0c;那么如果有很多三角形&#xff0c;各自距离相机的远近也不一样&#xff0c;并且三角形会相互遮挡。也就是三维空间中有很多物体&#xff0c;通常近处的物体会遮挡住远处的物体&#xff0c;那么在计算机渲染中该如何处理呢…

第十四篇——互信息:相关不是因果,那相关是什么?

目录 一、背景介绍二、思路&方案三、过程1.思维导图2.文章中经典的句子理解3.学习之后对于投资市场的理解4.通过这篇文章结合我知道的东西我能想到什么&#xff1f; 四、总结五、升华![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/499cd9af2ea14cbf8d12813f6f…

Linux命令详解(2)

文本处理是Linux命令行的重要应用之一。通过一系列强大的命令&#xff0c;用户可以轻松地对文本文件进行编辑、查询和转换。 cat&#xff1a; 这个命令用于查看文件内容。它可以一次性显示整个文件&#xff0c;或者分页显示。此外&#xff0c;cat 还可以用于合并多个文件的内容…

超全分析MybatisPlus中的MetaObjectHandler全局字段填充的基本知识(附Demo及实战)

目录 前言1. 源码及API2. Demo架构3. 全局字段填充&#xff08;实战&#xff09;4. 局部字段不填充&#xff08;实战&#xff09; 前言 对于Java的相关知识推荐阅读&#xff1a; java框架 零基础从入门到精通的学习路线 附开源项目面经等&#xff08;超全&#xff09;【Java项…

nginx ws长连接配置

nginx ws长连接配置 http根节点下配上 map $http_upgrade $connection_upgrade {default upgrade; close;}如下&#xff1a; server服务节点下&#xff0c;后端接口的代理配置 proxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connec…

电脑意外出现user32.dll丢失的八种修复方法,有效解决user32.dll文件丢失

遇到与 user32.dll 相关的错误通常是因为该文件已损坏、丢失、或者与某些软件冲突。今天这篇文章寄给大家介绍八种修复user32.dll丢失的方法&#xff0c;下面是一步步的详细教程来解决这个问题。 1. 重新启动电脑 第一步总是最简单的&#xff1a;重新启动你的电脑。许多小问题…

52.Python-web框架-Django - 多语言编译-fuzzy错误

目录 1.起因 2.原因 3.解决方法 3.1手动移除fuzzy标记 3.2重新生成po文件&#xff0c;并检查是否还存在fuzzy标记 3.3重新编译生成mo文件 1.起因 在Django的国际化和本地化过程中&#xff0c;当你发现某些字段仅显示msgid&#xff0c;而不显示msgstr时&#xff0c;可能是…

Python爬虫实战(实战篇)—18获取【小红书】首页信息写入Excel(仅用于学习-附完整版代码)

文章目录 专栏导读背景1、分析首页页面2、分析获取信息2-1,获取:笔记类型2-2,获取:标题2-3,获取:用户信息2-4,获取:用户ID2-5,获取:用户头像2-6,获取:文章连接完整代码总结专栏导读 文章名称链接Python爬虫实战(实战篇)—16获取【百度热搜】数据—写入Ecel(附完整…

日常销售数据分析为什么重要?三个维度全面分析日常销售数据

在当今电子商务的浪潮席卷全球的时代&#xff0c;网店如雨后春笋般涌现&#xff0c;并且竞争日趋激烈。在这样一个充满挑战与机遇的环境中&#xff0c;如何洞察市场动向&#xff0c;把握消费者需求&#xff0c;实现销售业绩的稳步增长&#xff0c;成为每一位电商运营者必须面对…

2024.6.12 作业 xyt

今日课堂练习&#xff1a;vector构造函数 #include <iostream> #include <vector> using namespace std;void printVector(vector<int> &v) {vector<int>::iterator iter;for(iterv.begin(); iter ! v.end(); iter){cout << *iter <<…

扩散模型会成为深度学习的下一个前沿领域吗?

文章目录 一、说明二、 第 1 部分&#xff1a;了解扩散模型2.1 什么是扩散模型2.2 正向扩散2.3 反向扩散 三、他们的高成本四、扩散模型的用处五、为什么扩散模型如此出色六、第 2 部分&#xff1a;使用扩散模型生成6.1 用于自然语言处理和 LLM 的文本扩散6.2 音频视频生成6.3 …

【APP移动端自动化测试】第一节.环境配置和adb调试工具

文章目录 前言一、Java环境搭建二、AndroidSDK环境搭建三、Android模拟器安装四、adb调试工具基本介绍 4.1 adb构成和基本原理 4.2 adb获取包名&#xff0c;界面名 4.3 adb文件传输 4.4 adb获取app启动时间 4.5 adb获取手机日志 4.6 adb其他有关…

空间搜索geohash概述;redis的geo命令

概述 通常在一些2C业务场景中会根据用户的位置来搜索一些内容。通常提供位置搜索的都是直接通过redis/mongodb/es等中间件实现的。 但是这些中间件又是怎么实现位置搜索的呢&#xff1b; 查了一番资料&#xff0c;发现背后一个公共的算法Geohash。 搜索的时候可以根据距离对…

「C系列」C 指针及其应用案例

文章目录 一、C 指针1. 指针的定义2. 指针的初始化3. 指针的解引用4. 指针的运算5. 动态内存分配6. 指针的NULL初始化7. 指针作为函数参数和返回值8. 指针数组和数组指针9. 多级指针 二、C语言中有哪些内置的指针操作符三、常见应用案例1. 交换两个变量的值2. 数组与指针3. 字符…

SwiftUI中自定义Shape与AnimateableData的使用

上一篇文章主要介绍了一下在SwiftUI中如何自定义Shape&#xff0c;本篇文章主要介绍Shape中的 一个关键的属性AnimatableData&#xff0c;它用于定义可以被动画化的数据。通过实现 Animatable 协议&#xff0c;可以让自定义视图或图形响应动画变化。 AnimatableData 是 Animata…