CSS中可扩展的层叠方式

21

我希望大家都听说过Sticky Notes。我想要像那样堆叠东西。所以这是我到目前为止的方法。我不确定如何使其可扩展到任意数量的便笺,而不使用JavaScript。

* {
  font-family: 'Segoe UI';
}
.stickynote {
  position: absolute;
  background: #fc0;
  border: 1px solid #f90;
  border-radius: 5px;
  padding: 10px;
  width: 75px;
  top: 10px;
  left: 10px;
}
.stickynote + .stickynote {
  top: 20px;
  left: 20px;
}

.stickynote + .stickynote + .stickynote {
  top: 30px;
  left: 30px;
}
<div class="stickynote"> Sticky!!! </div>
<div class="stickynote"> Sticky!!! </div>
<div class="stickynote"> Sticky!!! </div>

问题:

  1. 我不能一直添加 .stickynote + .stickynote + .stickynote。有没有更好的方法?
  2. 这种方法(HTML结构)正确吗?
  3. 它不是一个好主意去嵌套它们,因为它们不会语义上正确。如果可能的话,我会使用嵌套的<ul><li>,但我希望所有的便签都是同级的。
  4. 每个便签的高度是可变的,而且可能是固定的width。请不要硬编码height

注: 我准备提供尽可能多的信息。我不知道为什么这个问题会被投票关闭!


5
要按照您的意愿进行操作,可能需要添加变量... 因此,可能需要使用类似Sass / Less这样的预处理器CSS语言...我现在想不出一种方法,但您可以尝试使用nth-child伪元素和CSS calc()函数来实现,这可能是最接近不使用预处理器或jQuery的方式--因为需要对变量进行数学计算才能达到您想要的效果。 - CleverNode
1
我认为可以肯定地说,你永远不应该展示1000个笔记,最好只展示10个并隐藏其余的。但是当你关闭一个笔记时,另一个会加入到堆栈中。 - JordyvD
1
负边距?确定吗?@g3mini 哎呀!那怎么可能行得通? - Praveen Kumar Purushothaman
1
你可以像这样尝试使用浮点数:http://jsfiddle.net/1nu02a37/ - loli
1
@PraveenKumar 我不知道你是否可以在scss上递归编写...但我可能会这样做。假设人们不会有无限的粘性 对于 $i 从 1 到 20 { &:nth-child(#{$i}) { top: $i * 20; left: $i * 20; }} - CleverNode
显示剩余17条评论
5个回答

10

编辑:我做到了:)在便笺上使用从左上角的转换旋转,然后从父div的左上角反向旋转。XD

只要父级为不同的偏移度负数,就可以更改度数...

我自食其言说你不能没有编程来完成它...


我不知道如何将其余答案划掉,这是旧答案。


我能想到的最好的办法。

使用伪造之前和之后。

之前创建一个宽度为左偏移量并设置高度的“条”。因此,如果之后的高度超过200px,则回退到主页左侧。

之后是显示便笺的部分。

如果有人能够弄清楚如何将其移到元素本身中,而不是在伪造标题属性中使用,则我们获胜!否则,没有创建额外元素,这是您可以接近的最接近的。这正如便笺所拥有的那样语义化。非常有趣的问题!

HTML

<div class="stack">
  <div class="note" title="Lorem ipsum dolor sit amet, consectetur adipiscing elit."></div>
  <div class="note" title="Sed ac tellus at quam convallis feugiat. Ut vehicula leo non tellus convallis, id faucibus quam varius. Sed feugiat nulla in elit dignissim condimentum."></div>
  <div class="note" title=""></div>
  <div class="note" title="Cras quis volutpat sapien. Mauris volutpat ultrices lacus eu accumsan. Cras tempor sapien maximus quam finibus, ullamcorper imperdiet mauris aliquam."></div>
</div>
CSS
.note:before {
  content: '';
  width: 20px;
  height: 200px;
  float: left;
}
.note:after {
  content: attr(title);
  width: 200px;
  min-height: 200px;
  padding: 10px;
  background: khaki;
  box-shadow: 1px 2px 7px rgba(0,0,0,.3);
  border: khaki 1px outset;
  display: inline-block;
  margin: 10px 0 -190px 0;
}

玩一下。你会发现内容并不在你想象的位置。它在便利贴之前。因为样式在:after类中,实际的.note内容是在其之前。这是我能想到的按照你要求排序便笺的唯一方法,没有编程(js或sass)就无法实现。 - Luke Fixt
这种方法还有另一个问题,就是您无法选择注释的内容!你看到了吗? - Praveen Kumar Purushothaman
是的,因为:before和:after不是DOM的一部分,所以它们是不可选择的。不过,你没有问那个 ;) - Luke Fixt
2
我不知道你对此的意图是什么... ;) 但正如我所说,这是我在没有编程的情况下能做到的最好的了。我个人认为最好的选择是@Oka提出的Sass方式。我们想要的那种效果只是用纯CSS实现起来不太可能。 - Luke Fixt
不错的解决方案,它们可以以这种方式具有可变高度吗? - loli
显示剩余2条评论

8
您可以让元素浮动,并为所需效果提供负边距。 <div class="nofloat">浮动框</div> 用于使每个注释都跳过一行。可将其可见性设置为隐藏,以便该元素仍然影响布局。
<div class="floating-box1">Floating box1</div>
<div class="nofloat">Floating box</div>
<div class="floating-box">Floating box2</div>
<div class="nofloat">Floating box</div>
<div class="floating-box">Floating box3</div>
<div class="nofloat">Floating box</div>
<div class="floating-box">Floating box4</div>

CSS:

.floating-box1 {
    float: left;
    width: 150px;
    height: 75px;
    margin: 10px;
    background: #fc0;
    border: 1px solid #f90;
    border-radius: 5px;
    padding: 10px;
}
.floating-box {
    background: #fc0;
    border: 1px solid #f90;
    border-radius: 5px;
    padding: 10px;
    float: left;
    width: 150px;
    height: 75px;
    margin: 10px;
    margin-left:-160px; 
}
.nofloat{
    visibility:hidden;
}

例如 jsfiddle:http://jsfiddle.net/1nu02a37/

这是一个关于jsfiddle的例子,点击链接可以查看示例页面。

1
不过,以防万一你找不到其他解决方案! - loli
2
我试验了一下 - 这里有一种更简短的代码实现方式 - 同时更容易理解为什么它有效: http://jsfiddle.net/o9snaxwp/ - Syntax Error
1
@SyntaxError:使用伪元素无法实现此操作,因为格式化上下文会出错。 - Oka
哇,我真的很喜欢 @Syntax Error 的 <br> 想法,之前没有想到过。 - loli
3
@PraveenKumar,不使用表格或br元素来布局的规则是针对初学者的经验法则,而不是适用于所有情况的法律规定。为了避免在代码中使用易于理解的<br>而编写复杂的变通方法,这是打破这个规则的好例子。我可以理解寻找纯CSS方法的想法,但在这种情况下,考虑到其他选项,<br>肯定不是“不好”的选择。 - Syntax Error
显示剩余9条评论

4

这是一个非常有趣的问题。我想从语义上而不是从代码实践上来看待它。

我理解为什么您不希望将它们嵌套,一开始似乎在语义上这样做是错误的。但我认为您在这里犯了一个错误。

想象一下一叠便利贴。它们是彼此相邻的,还是已经组合成了另一个独特的“东西”?

从语义上讲,它们是一堆。您可以看到这是一个清晰的列表物理表示,其中ul是堆栈,li是便条。这完全符合语义。

您还可以说,每个便条的物理位置取决于前面那个的物理位置。您在物理上将相关的便条嵌套在彼此之上(它们只是在右侧和底部突出),但每个连续便条的组织取决于前面的便条。有些人可能会说这是设计问题而不是语义问题,但如果它们一开始就没有语义关系,为什么要将它们堆叠起来呢?这意味着将它们嵌套也可以在语义上完全有意义。

在您的代码中将它们并排放置,但在用户看来并不是相邻的,实际上对我来说似乎在语义上毫无意义。除非您有一个父容器来表示堆栈。这意味着您基本上只是使用其他元素来表示ul / li。


是的,但即使如此,“ul>li>ul>li>ul>li>ul>li>ul>li” - 没有意义,对吧? - Praveen Kumar Purushothaman
@语法错误:看看你的代码,仅仅为了三个粘性!http://jsfiddle.net/u9yzs2su/3/ LoL. 男人!!! - Praveen Kumar Purushothaman
没错,这就是为什么会出现这个问题。解决方案是什么?有更好的想法吗? - Praveen Kumar Purushothaman
我认为我关于为什么嵌套span可以在语义上是正确的笔记是我能够接近这个问题的最接近答案。我刚刚尝试了一些溢出的东西,但没有成功。 - Syntax Error
嵌套被排除在外了伙计!你的答案肯定是不行的......但是由于你的解决方式,我必须点赞!!! - Praveen Kumar Purushothaman
显示剩余2条评论

3
一点 JavaScript 就能解决问题。

var arrStickyNotes = document.querySelectorAll('.stickynote');
var pos = 0;
for (i = 0; i < arrStickyNotes.length; i++) {
    arrStickyNotes[i].style.top = pos + 'px';
    arrStickyNotes[i].style.left = pos + 'px';
    pos += 10;
}
.stickynote {
    background: #fc0;
    border: 1px solid #f90;
    border-radius: 5px;
    padding: 10px;
    width: 75px;
    position:absolute;
}
.container {
    position:relative;
}
<div class="container">
    <div class="stickynote">Sticky!!!</div>
    <div class="stickynote">Sticky!!!</div>
    <div class="stickynote">Sticky!!!</div>
</div>


哈哈...我已经知道这个技巧了。我不想使用JavaScript或jQuery!;) - Praveen Kumar Purushothaman

1
如果您不打算将它们嵌套,我认为在真正可扩展的方式下没有非常可行的方法来做到这一点。负边距可以在垂直方向上起作用,但如果您想要注释向右延伸,就始终需要增量值。
如果您喜欢使用预处理器,您可以通过这种方式实现,但只是为了处理1k堆栈而编写4000行源代码。这很简单,但仍然存在硬限制。
使用Sass可以实现这一点 - DEMO。
我想在片段中发布输出,但SO阻止了我。
引用:
正文限制为30000个字符;您输入了79511个字符。
@mixin notes($m, $n: 10) {
  @for $i from 1 through $n {
    &:nth-child(#{$i}) {
      @each $k, $v in $m {
        #{$k}: $v * $i;
      }
    }
  }
}

* {
  font-family: 'Segoe UI';
}
.stickynote {
  position: absolute;
  background: #fc0;
  border: 1px solid #f90;
  border-radius: 5px;
  padding: 10px;
  width: 75px;
  top: 10px;
  left: 10px;

  @include notes((top: 10px, left: 10px), 1000);
}

CSS在某些重复性任务方面不太具有可伸缩性。
我也同意Syntax Error关于此问题的语义学观点。
实际上,我不确定为什么您需要一个可扩展的CSS解决方案来标记显然必须是生成的标记。您绝不可能手动编写数百个.stickynote元素。无论生成标记的内容是什么,都可以生成相应的样式。

好的,我相信你使用了那个mixin生成了一些疯狂的CSS,是吗?兄弟,但是CSS仍然会被浏览器解析... 它会因为内存不足而死亡!!! - Praveen Kumar Purushothaman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接