使用CSS定位水平滚动条

问题描述 投票:0回答:5

macOS 为触控板用户隐藏滚动条,这导致我的用户不知道他们可以水平滚动结果集。我正在尝试使用 CSS 仅定位水平滚动条,以便我可以使它们永久可见。

我可以使用 CSS 覆盖滚动条的视觉行为:

::-webkit-scrollbar{
    -webkit-appearance: none;
    width: 7px;
}
::-webkit-scrollbar-thumb{
    border-radius: 4px;
    background-color: rgba(0,0,0,.5);
    box-shadow: 0 0 1px rgba(255,255,255,.5);
}

https://jsfiddle.net/ypk62h8v/1/

但是当我尝试应用 :horizontal 伪元素时,它不起作用(Mac/Chrome):

HTML:

<div class="frame" style="">
    <div style="width:500px;height:500px;">
    SCROLLABLE
    </div>
</div>

CSS:

.frame {
    overflow-y: auto;
    overflow-x: auto;
    border: 1px solid black;
    height: 3em;
    width: 10em;
    line-height: 1em;
}

::-webkit-scrollbar:horizontal {
    -webkit-appearance: none;
    width: 7px;
}
::-webkit-scrollbar-thumb:horizontal {
    border-radius: 4px;
    background-color: rgba(0,0,0,.5);
    box-shadow: 0 0 1px rgba(255,255,255,.5);
}

https://jsfiddle.net/ypk62h8v/

html css macos scrollbar overflow
5个回答
0
投票

没有像 :horizontal 这样的直接 CSS 选择器,您可以使用它来专门定位水平滚动条进行自定义,就像您可以在不指定方向的情况下定位滚动条一样。

所以,如果你想实现这一点,你应该使用以下 CSS 和 JavaScript 代码:

// Add a class to the frame when the content overflows horizontally
const frame = document.querySelector('.frame');
const content = document.querySelector('.content');

frame.addEventListener('scroll', () => {
    if (content.scrollWidth > frame.offsetWidth) {
        frame.classList.add('has-horizontal-scroll');
    } else {
        frame.classList.remove('has-horizontal-scroll');
    }
});
.frame {
    overflow-y: auto;
    overflow-x: auto;
    border: 1px solid black;
    height: 3em;
    width: 10em;
    line-height: 1em;
}

.frame::-webkit-scrollbar {
    width: 7px;
    height: 7px;
}

.frame::-webkit-scrollbar-thumb {
    border-radius: 4px;
    background-color: rgba(0, 0, 0, .5);
    box-shadow: 0 0 1px rgba(255, 255, 255, .5);
}

.frame::-webkit-scrollbar-thumb:vertical {
    background-color: rgba(0, 0, 0, .5); /* Adjust vertical scrollbar appearance */
}


.frame.has-horizontal-scroll::-webkit-scrollbar-thumb:horizontal {
    background-color: rgba(0, 0, 0, .5); /* Adjust horizontal scrollbar appearance */
}
<div class="frame" style="">
    <div class="content" style="width:500px;height:500px;">
        SCROLLABLE
    </div>
</div>


0
投票

使用 溢出:滚动 代替 溢出:自动


0
投票

您的代码已设置良好且工作正常 您刚刚删除了 Overflow-y: auto-hidden 更改中的 ':horizontal' 和 .frame 类;这样所有这些设备都可以工作。

.frame {
    overflow-y: hidden; // change auto to hidden
}

::-webkit-scrollbar{
    -webkit-appearance: none;
    width: 7px;
}
::-webkit-scrollbar-thumb{
    border-radius: 4px;
    background-color: rgba(0,0,0,.5);
    box-shadow: 0 0 1px rgba(255,255,255,.5);
}

0
投票

你已经非常接近做你想做的事了。不幸的是,据我所知,没有一种本地方法可以完全实现您想要的目标。为了设置任一滚动条的样式,您需要覆盖 DOM,并告诉浏览器您要使用自定义样式。

完成此操作后,您可以直接定位

:horizontal
类。

如果这是我的项目,并且我有很多水平溢出的容器,我将创建一个特殊的容器类,例如

.horizontal-container
,它将覆盖 DOM,并应用样式以确保水平滚动条可见。能够在 X 轴和 Y 轴上滚动(除非它像 Figma 画布样式交互)是糟糕的 UX,所以我不会太担心垂直滚动不可见。

另外

您可以添加像我的第二个片段一样的微妙动画,以向用户表明右侧还有其他内容。

.frame {
  border: 1px solid black;
  height: 5em;
  width: 15em;
  line-height: 1em;
  
  overflow: auto;
}

p {
  margin: 0;
}

/* You first need to target all scrollbars to override the DOM */
::-webkit-scrollbar {
    -webkit-appearance: auto;
}

/* Then you can target the :horizontal class on it's own */
::-webkit-scrollbar-thumb:horizontal {
    border-radius: 20px;
    background-color: rgba(255,0,0,.5);
    box-shadow: 0 0 1px rgba(255,255,255,.5);
}
<div class="frame" style="">
  <div style="width:500px;height:500px;">
    <p>SCROLLABLE, SCROLLABLE, SCROLLABLE, SCROLLABLE, SCROLLABLE, SCROLLABLE, SCROLLABLE, SCROLLABLE, SCROLLABLE, SCROLLABLE, SCROLLABLE, SCROLLABLE, SCROLLABLE, SCROLLABLE, SCROLLABLE, SCROLLABLE, SCROLLABLE, 
    </p> 
  </div>
</div>

动画

这比我实际做的更戏剧化,但它只是一个例子。

.frame {
  overflow-y: auto;
  overflow-x: auto;
  border: 1px solid black;
  height: 7em;
  width: 15em;
  line-height: 1em;
  position: relative;
}

.frame::after {
  content: "";
  height: 100%;
  width: 4rem;
  position: absolute;
  /* Turn this on to see the animation more clearly 
    background: red;
  */
  background: linear-gradient(90deg, rgba(255,255,255,0) 0%, rgba(255,255,255,1) 100%);
  top: 0;
  left: calc(100% - 2rem);
  animation: bounce 4s infinite ease-in-out;
}

@keyframes bounce {
  0% {
    transform: translateX(-2rem);
  }
  50% {
    transform: translateX(2rem);
  }
    100% {
    transform: translateX(-2rem);
  }
}

p {
  margin: 0;
}
<div class="frame" style="">
  <div style="width:500px;height:500px;">
    <p>SCROLLABLE, SCROLLABLE, SCROLLABLE, SCROLLABLE, SCROLLABLE, SCROLLABLE, SCROLLABLE, SCROLLABLE, SCROLLABLE, SCROLLABLE, SCROLLABLE, SCROLLABLE, SCROLLABLE, SCROLLABLE, SCROLLABLE, SCROLLABLE, SCROLLABLE, 
    </p> 
  </div>
</div>


-2
投票

我知道您正在尝试专门使用 :horizontal 伪元素来定位水平滚动条。不幸的是,据我所知,基于 webkit 的浏览器(如 Chrome 和 Safari)不支持 :horizontal 和 :vertical 伪元素。

但是,您仍然可以通过定位整个滚动条区域和拇指来实现使水平滚动条永久可见的目标,而不使用 :horizontal 伪元素。以下是如何修改 CSS 来实现这一目标:

/* Apply styles to the entire scrollbar area */
::-webkit-scrollbar {
    -webkit-appearance: none;
    width: 7px;
    background-color: rgba(0,0,0,.2); /* Set background color */
}

/* Apply styles to the scrollbar thumb */
::-webkit-scrollbar-thumb {
    border-radius: 4px;
    background-color: rgba(0,0,0,.5);
    box-shadow: 0 0 1px rgba(255,255,255,.5);
}

这将同时针对水平和垂直滚动条,但它仍然会使水平滚动条可见。不幸的是,在基于 webkit 的浏览器中,没有单独针对水平滚动条的直接伪元素定位。

要使用 JavaScript 使水平滚动条对特定元素永久可见,您可以按照以下步骤操作:

// Get the element with class "frame"
const frame = document.querySelector('.frame');

// Add a scroll event listener to the frame
frame.addEventListener('scroll', () => {
    // Check if the current scroll position is at the maximum horizontal scroll
    const isAtMaxScroll = frame.scrollLeft === frame.scrollWidth - frame.clientWidth;

    // If at maximum scroll, apply the custom style to the scrollbar
    if (isAtMaxScroll) {
        frame.style.overflowX = 'scroll';  // Display the horizontal scrollbar
        frame.style.overflowY = 'auto';    // Display the vertical scrollbar
    } else {
        frame.style.overflowX = 'auto';    // Hide the horizontal scrollbar
    }
});
.frame {
    overflow-y: auto;
    overflow-x: auto;
    border: 1px solid black;
    height: 3em;
    width: 10em;
    line-height: 1em;
}

.content {
    width: 500px;
    height: 500px;
}
<div class="frame">
    <div class="content">
        SCROLLABLE
    </div>
</div>

© www.soinside.com 2019 - 2024. All rights reserved.