【问题标题】:How to change only the default cursor?如何仅更改默认光标?
【发布时间】:2023-01-14 09:07:37
【问题描述】:

我的网站有一个自定义光标图像,但仅适用于 default 状态。在其余情况下(特别是text)我想要预定义的。

但是如果我以这种方式定义自定义光标......

html {
  cursor: url('path/to/custom/cursor.svg') 0 0, default;
}

至少text状态丢失了(不是pointer,但我怀疑其他人也丢失了)我的段落、文本跨度、标题等现在显示我的自定义光标而不是预定义的文本选择器。

当然,我可以为某些元素重新定义样式......

p, span, ol, ul, h1, h2, h3, h4 {
  cursor: text;
}

但textstatus 并没有真正链接到某些 html 标签,它出现在有一个不受其他修饰符影响的文本节点时。例如,我如何定位一个仅包含文本的 div,但排除仅包含特定颜色、背景等的另一个 div 的 div?

正如我所见 in this question 没有办法直接定位文本节点,所以我想知道是否有一种侵入性较小的方法来定义自定义光标只要在预定义的默认光标出现的情况下,仍然显示每个修改状态的所有预定义光标(text、scroll 等)

先感谢您。

示例 1:如果定义了 html 游标,则全部被覆盖:

html {
  cursor: all-scroll;
}
Lorem ipsum dolor sit amet

示例 2:如果我们尝试重新定义一些元素,我们现在有误报......

html {
  cursor: all-scroll;
}

/* Dillema: Which elements should be redefined to target predefined text status?? */
div {
  cursor: text;
}
<div>Lorem ipsum dolor sit amet</div>
<div style="width: 100px; height: 100px; background-color: red;"></div>

【问题讨论】:

  • 你能提供一个minimum working example吗?
  • @ACarter 我使用all-scroll 添加了几个 sn-ps 作为示例而不是自定义图像,因为毕竟这与自定义图像无关。但我不确定这是否澄清了这个问题。
  • 谢谢,所以你希望光标只在文本上方时改变,对吗?
  • html { 高度:100%; }
  • @ACarter 我真正想要的是光标只要default 光标出现的情况发生了变化。我不知道哪种方法会更好:尝试以“默认”情况为目标以仅定义它们,或者之后尝试以文本(和卷轴等)为目标以将它们重新定义为它们的预定义游标。

标签: css


【解决方案1】:

这是关于 cursor css 属性的 mdn 文档:

https://developer.mozilla.org/en-US/docs/Web/CSS/cursor

cursor CSS 属性设置鼠标光标,如果有的话,显示什么时候 鼠标指针在一个元素上。

光标设置应告知用户鼠标操作 可以在当前位置进行,包括:文本选择, 激活帮助或上下文菜单、复制内容、调整表格大小、 等等。您可以使用关键字指定游标的类型, 或加载特定图标以使用(带有可选的后备图像和 强制关键字作为最后的后备)。

很明显,当鼠标指针悬停在具有这种样式的元素上时,此类属性会影响光标。因此,要影响根伞下的每个元素,为整个 &lt;html&gt; 元素设置样式就足够了,但确保可见高度覆盖实际视口也很重要!

这就是为什么使用 html { height: 100% } 作为解决方案的原因。

然后你说:

“......至少文本状态丢失了(不是指针,但我怀疑其他人也丢失了)并且我的段落,文本跨度,标题等现在显示我的自定义光标而不是预定义的文本选择器。”

应该注意的是,html 文档始终有一个根元素,即&lt;html&gt;。任何文本内容始终是 textNode,您在页面中找到它的任何位置始终是某个节点的内容,最坏的情况是它是 body 元素中的子节点。到目前为止,我所说的可能是忽略来自 content css 属性的文本(但让我们假装它不存在)。

所以当然你不能为文本本身设置样式,但你可以为包含它的元素设置样式,因为总是有这样一个元素,因此总是有一个选择器可以用来设置给定文本的样式,该文本肯定会包含在某个元素中你可以解决。唯一担心的是你不能将样式仅限于文本,但仅限于所有的您要设置样式的元素的内容。

现在唯一需要知道的是,某些元素将具有某些 css 属性的默认值,这些默认值将覆盖在父元素上设置的任何值。这是因为 css specificity 的工作原理以及某些属性是如何从祖先那里继承的。

我制作了一个包含多种 html 元素类型的演示。

另外还有两个按钮:

  • Toggle custom cursor on html - 这将切换 css 类 在html 元素上自定义.customcursor(该规则在文档中预定义为.customcursor{cursor: all-scroll !important;})
  • Toggle custom cursor on * - 这将添加/删除一个 css 规则,该规则将 cursor css 属性设置为全部DOM 中的元素(*{cursor: all-scroll !important; .. 我这样做的原因是让 css 负责选择所有元素,而不是将 js 与 querySelectorAll 一起使用)

值得指出的是,我使用 !important 来表明它不足以覆盖那些不从父级继承的元素类型的 cursor 属性。

当您将 customcursor 设置为 html 时,您会看到除了表单元素之外,几乎所有元素都进行了自定义。

当您设置以所有元素为目标的规则时,它会影响一切,并且光标将是您在整个页面视口上悬停时唯一看到的光标。

//create the empty stylesheet on document loaded
var styleSheet;
document.addEventListener('DOMContentLoaded',()=>{
  const styleEl = document.createElement('style');  
  document.head.appendChild(styleEl);  
  styleSheet = styleEl.sheet;
});

function toggleCustomCursorOnBody(btn){  
  const cb = btn.querySelector('input');   
  document.querySelector('html').classList.toggle('customcursor');
  cb.checked = !cb.checked;  
}

function toggleCssRuleOnAllElements(btn){
  const cb = btn.querySelector('input');     
  if(!cb.checked)
    addCssRule();
  else
    removeCssRule();
  cb.checked = !cb.checked;  
}

function addCssRule(){    
  styleSheet.insertRule('*{cursor: all-scroll !important;}', 0);
}

function removeCssRule(){
   styleSheet.deleteRule(0);
}
html {    
  border: solid 18px purple; /*<--this is to show the size of the element we are setting cursor for! */
  background: lightgoldenrodyellow;      
  height: calc(100% - 36px);  /*<--this was what I pointed out in comments */
}

.customcursor{
  cursor: all-scroll !important;
}

/*the following just to give consistence to the page elements*/

.toggles{
  margin: 0 auto 1em auto;  
}

.toggle{
  cursor: pointer;
  padding: .5em 1em;
}

.toggle > input[type="checkbox"]{
  pointer-events: none;
}

body{
  font-size: 18px;
  text-align: center;
}

*{
  box-sizing: box-model;
  border: dotted 1px lightgray;
}

.container,
form
{  
  display: flex;
  flex-wrap: wrap;
  justify-content: space-around;
  gap: 2vmin;
}

body > .container{
  margin-top: 2vh;
}

.container > h1,
.container > h2,
.container > h3,
.container > h4,
.container > h5,
.container > h6
{
  margin: 0;
  max-height: 10vh;
}

.container > h1{
  background: rgba(204, 204, 204, 1);
}

.container > h2{
  background: rgba(204, 204, 204, 0.9);
}

.container > h3{
  background: rgba(204, 204, 204, 0.8);
}

.container > h4{
  background: rgba(204, 204, 204, 0.7);
}

.container > h5{
  background: rgba(204, 204, 204, 0.6);
}

.container > h6{
  background: rgba(204, 204, 204, 0.5);
}

.container > p{
  background-color: lime;
  font-size: 2rem;
  margin: 0;
}

.container > ol{
  background-color: cyan;
  font-size: 1rem;
  padding: .5em 1em .5em 1.5em;
  margin: 0;
  height: fit-content;
}

.container > a{
  background: antiquewhite;
  font-size: 2rem;
  height: fit-content;
  margin: 0;
}

.container > div:not(.container):not(.unstyled) {  
  width: 20vw;
  height: 5vh;
  
  background: dodgerblue;
  color: white;
  padding: 1em; 
  font-weight: 600;
  font-size: 1.5rem;
  
  display: flex;
  justify-content: center;
  align-items: center;
}

.container > span {
  width: 20vw;
  height: 5vh;
  
  background: cadetblue;
  color: white;
  padding: 1em; 
  font-weight: 600;
  font-size: 1.5rem;
  
  display: flex;
  justify-content: center;
  align-items: center;
}


.container > textarea{  
  width: 15ch;
  height: 10vh;
}

.container > label{
  outline: solid 1px gray;
  padding: .2em 1em;
  background: gray;
  color: white;
  max-height: 1em;
}

.container > select{
  max-height: 2em;
}

.container > input{
}

.container > input[type="text"]{
  width: 15ch;
  max-height: 1em;
  font-size: 1rem;
  padding: .5rem .5rem; 
}

.unstyled input[type="checkbox"]{  
  position: relative;
  width: 2em;
  height: 2em;    
}

.unstyled input[type="checkbox"] + label{  
}
<body>

<div class="toggles">
  <button id="toggle1" class="toggle" onclick="toggleCustomCursorOnBody(this);">
    Toggle custom cursor on &lt;html&gt;
    <input type="checkbox">
  </button>

  <button id="toggle2" class="toggle" onclick="toggleCssRuleOnAllElements(this);">
    Toggle custom cursor on *
    <input type="checkbox">
  </button>
</div>

[THIS IS A TEXT NODE HAVING FONT SIZE FROM BODY]

<div class="container">
    
  <div class="container">
    <h1>&lt;h1&gt;</h1>
    <h2>&lt;h2&gt;</h2>
    <h3>&lt;h3&gt;</h3>
    <h4>&lt;h4&gt;</h4>
    <h5>&lt;h5&gt;</h5>
    <h6>&lt;h6&gt;</h6>
  </div>  
  
  <div class="container">
    <p>&lt;p&gt;</p>
    <ol>
      <li>&lt;ol&gt; &lt;li&gt;</li>
      <li>&lt;ol&gt; &lt;li&gt;</li>
      <li>&lt;ol&gt; &lt;li&gt;</li>
    </ol>  
    <a href="#">&lt;a&gt;</a>
  </div>      

  <div class="container">
    <div>&lt;div&gt;</div>  
    <span>&lt;span&gt;</span>
  </div>
      
  <form class="container">
    <label>&lt;label&gt;</label>
    
    <input type="text" value="<input type=text>">
    
    <textarea>&lt;textarea&gt;</textarea>  
    
    <div class="unstyled">
      <input type="checkbox">    
      <label>&lt;input cb&gt;</label>
    </div>

    <select>
      <option disabled selected>&lt;select&gt;...</option>
      <option value="1">Option1</option>
      <option value="2">Option2</option>
      <option value="3">Option3</option>
    </select>  
    
    <fieldset>
      <legend>&lt;legend&gt;</legend>
      <div>
        <input type="radio" checked>
        <label>&lt;radio&gt;</label>
      </div>
      <div>
        <input type="radio" checked>
        <label>&lt;radio&gt;</label>
      </div>
      <div>
        <input type="radio" checked>
        <label>&lt;radio&gt;</label>
      </div>
    </fieldset>
    
  </form>
  
</div>

</body>

【讨论】:

    猜你喜欢
    • 2020-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-17
    • 1970-01-01
    • 2017-03-09
    • 2011-05-02
    • 1970-01-01
    相关资源
    最近更新 更多