【问题标题】:How to 'disable collisions' without position:absolute in CSS如何在没有位置的情况下“禁用碰撞”:CSS 中的绝对值
【发布时间】:2020-09-21 03:28:24
【问题描述】:

背景资料


我正在处理 HTML(Pug) 和 CSS(SASS) 中的水平菜单。我想让它每当你点击一个图标时,它就会突出显示。这是我想要的近似值:
[像我想要的菜单一样来自 https://codepen.io/ainalem/pen/pXrVmQ][1]

问题

我想使用一个单独的元素(称为 .bg-block),它将位于所选元素的后面。

别开始取笑我了……

听起来像初学者的问题,对吧?
position: absolute

完成!没问题,而且可能是您学习的第一件事!但是如果你不能使用 position: absolute 怎么办?

进入正题...

我想禁用碰撞并拥有一个具有_position:absolute_行为的元素,而不使用_position:absolute_。甚至可能吗?我怀疑它,但我不怀疑 StackOverflow 的力量。

但是为什么呢?

我这样做是因为如果我的元素是 position: relative,我可以使用 top:、left:、right: 和 bottom: 相对于它的正常位置。我认为当我想调整 .bg-block 的位置时,这会更好。
此外,我对任何其他可能的方式以及 StackOverflow 的强大功能感兴趣。
如果你需要一些背景代码来玩,这里是我的笔:
.menu
  display: flex
  flex-direction: row
  align-items: center
  justify-content: center
  
  *
    height: 100px
    width: 100px
    margin: 10px
    cursor: pointer
    display: flex
    flex-direction: column
    align-items: center
    justify-content: center
    transition: transform 80ms ease-in
  
  p
    cursor: text
    margin-top: 0
    letter-spacing: 0px
    
    
  img
    margin-bottom: 5px
    
  .home, .search, .inbox
    &:active
      transform: scale(0.95)
    
    
  .bg-block
    position: absolute
    background-color: lightblue
    z-index: -1
    position: relative

.menu
  .bg-block
  .home
    img(src="https://cdn0.iconfinder.com/data/icons/typicons-2/24/home-256.png")
    p Home
    
  .search
    img(src="https://cdn3.iconfinder.com/data/icons/wpzoom-developer-icon-set/500/67-256.png")
    p Search
  .inbox
    img(src="https://cdn2.iconfinder.com/data/icons/maki/100/post-256.png")
    p Inbox

请注意:我的 HTML 使用的是 SASS(使用 SASS 格式,而不是 SCSS)和 Pug。对于您可能遇到的任何不便,我深表歉意,但如果您有普通 HTML 和 CSS 的答案,我也很乐意听到它们(而且 PUG 和 SASS 中的内容相同,只是更好看)。

【问题讨论】:

  • 这听起来像是一个 XY 问题,您不想使用 position:absolute 因为您无法轻松定位元素?你说如果我的元素是位置:相对,我认为当我想调整 .bg-block 的位置时这会更好。所以基本上问题不是位置:绝对而是如何定位元素?
  • @TemaniAfif 是的,但我想通过替换位置来解决它:绝对。如果您有针对此特定项目的答案,您可以评论另一种类型的答案(非常感谢您),但我还想添加另一个位置:绝对到我的开发人员工具箱????。我希望你明白。谢谢!

标签: html css sass


【解决方案1】:

如果您更改 HTML 代码,则可以使用 position:absolute,因为 positon:absolute 是获得所需内容的合乎逻辑的方式。要正确设置位置,您需要考虑一个适合您的元素的 shrink-to-fit 容器,以便您可以轻松地为 position:absolute 元素定义空间。

这是一个基本示例。悬停查看结果:

.menu {
  display: flex;
  align-items: center;
  justify-content: center;
}
.wrapper {
  display: flex;
  position:relative;
  z-index:0;
}

.wrapper > *{
  height: 100px;
  width: 100px;
  padding: 10px;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  transition: transform 80ms ease-in;
}

.menu p {
  cursor: text;
  margin-top: 0;
  letter-spacing: 0px;
}

.menu img {
  margin-bottom: 5px;
  width:100px;
}

.menu .home:active,
.menu .search:active,
.menu .inbox:active {
  transform: scale(0.95);
}

.menu .bg-block {
  position: absolute;
  top:0;
  left:0;
  background-color: lightblue;
  z-index: -1;
  transition: transform 300ms ease-in;
}

.menu .home:hover ~ .bg-block,
.menu .home:active ~ .bg-block{
  transform:translateX(0);
}
.menu .search:hover ~ .bg-block,
.menu .search:active ~ .bg-block{
  transform:translateX(100%);
}
.menu .inbox:hover ~ .bg-block,
.menu .inbox:active ~ .bg-block{
  transform:translateX(200%);
}
<div class="menu">
<div class="wrapper">
  <div class="home"><img src="https://cdn0.iconfinder.com/data/icons/typicons-2/24/home-256.png" />
    <p>Home</p>
  </div>
  <div class="search"><img src="https://cdn3.iconfinder.com/data/icons/wpzoom-developer-icon-set/500/67-256.png" />
    <p>Search</p>
  </div>
  <div class="inbox"><img src="https://cdn2.iconfinder.com/data/icons/maki/100/post-256.png" />
    <p>Inbox</p>
  </div>
  <div class="bg-block"></div>
 </div>
</div>

如果你真的不希望position:absolute 考虑一个大小为 0 的元素(不会影响另一个元素)和一个超低的子元素(你可以使用伪元素),但这比前一个更干净:

.menu {
  display: flex;
  justify-content: center;
}


.menu > *{
  height: 100px;
  width: 100px;
  padding: 10px;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  transition: transform 80ms ease-in;
}

.menu p {
  cursor: text;
  margin-top: 0;
  letter-spacing: 0px;
}

.menu img {
  margin-bottom: 5px;
  width:100px;
}

.menu .home:active,
.menu .search:active,
.menu .inbox:active {
  transform: scale(0.95);
}

.menu .bg-block {
  width:0;
  height:0;
  padding:0;
  display:block;
  position:relative;
  z-index:-1;
  transition: transform 300ms ease-in;
  direction: rtl;
}
.menu .bg-block:before {
  content:"";
  display:block;
  height:100px;
  width:100px;
  padding:10px;
  background-color: lightblue;
}

.menu .home:hover ~ .bg-block,
.menu .home:active ~ .bg-block{
  transform:translateX(-240px);
}
.menu .search:hover ~ .bg-block,
.menu .search:active ~ .bg-block{
  transform:translateX(-120px);
}
.menu .inbox:hover ~ .bg-block,
.menu .inbox:active ~ .bg-block{
  transform:translateX(0);
}
<div class="menu">
  <div class="home"><img src="https://cdn0.iconfinder.com/data/icons/typicons-2/24/home-256.png" />
    <p>Home</p>
  </div>
  <div class="search"><img src="https://cdn3.iconfinder.com/data/icons/wpzoom-developer-icon-set/500/67-256.png" />
    <p>Search</p>
  </div>
  <div class="inbox"><img src="https://cdn2.iconfinder.com/data/icons/maki/100/post-256.png" />
    <p>Inbox</p>
  </div>
  <div class="bg-block"></div>
</div>

另一个技巧是使用box-shadow 来显示彩色框而不是伪元素:

.menu {
  display: flex;
  justify-content: center;
}


.menu > *{
  height: 100px;
  width: 100px;
  padding: 10px;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  transition: transform 80ms ease-in;
}

.menu p {
  cursor: text;
  margin-top: 0;
  letter-spacing: 0px;
}

.menu img {
  margin-bottom: 5px;
  width:100px;
}

.menu .home:active,
.menu .search:active,
.menu .inbox:active {
  transform: scale(0.95);
}

.menu .bg-block {
  width:0;
  height:0;
  padding:0;
  position:relative;
  z-index:-1;
  transition: transform 300ms ease-in;
  box-shadow:-60px 60px 0 60px lightblue;
}

.menu .home:hover ~ .bg-block,
.menu .home:active ~ .bg-block{
  transform:translateX(-240px);
}
.menu .search:hover ~ .bg-block,
.menu .search:active ~ .bg-block{
  transform:translateX(-120px);
}
.menu .inbox:hover ~ .bg-block,
.menu .inbox:active ~ .bg-block{
  transform:translateX(0);
}
<div class="menu">
  <div class="home"><img src="https://cdn0.iconfinder.com/data/icons/typicons-2/24/home-256.png" />
    <p>Home</p>
  </div>
  <div class="search"><img src="https://cdn3.iconfinder.com/data/icons/wpzoom-developer-icon-set/500/67-256.png" />
    <p>Search</p>
  </div>
  <div class="inbox"><img src="https://cdn2.iconfinder.com/data/icons/maki/100/post-256.png" />
    <p>Inbox</p>
  </div>
  <div class="bg-block"></div>
</div>

【讨论】:

    【解决方案2】:

    您可以在 CSS 中为具有负边距的元素设置样式。这意味着您可以通过将margin-left 设置为元素的宽度(但为负)和margin-top 设置为元素的高度(再次为负)来有效地禁用与该元素的碰撞。将此应用于img 应该可以解决您的问题。
    此外,要完成这项工作,您应该将 bg-block 元素放在各个图像元素中。

    【讨论】:

    • 谢谢,这行得通,但我想先看看其他答案,然后再选择正确的答案。谢谢!
    【解决方案3】:

    使用边距,它们工作得很好。

    【讨论】:

    • 您能详细说明一下吗?
    猜你喜欢
    • 1970-01-01
    • 2014-07-17
    • 2022-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多