21

I hope everyone will have heard about Sticky Notes. I wanna stack stuff like that. So this is the approach I have till now. I am not sure how to make it scalable for any number of stickies, without using 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>

Problem:

  1. I cannot keep on adding .stickynote + .stickynote + .stickynote for all.
  2. Is the approach (HTML Structure) correct?
  3. It is not a good idea to nest them, as they will not be semantically correct. If that was possible, I would have used nested <ul> and <li>, but I want all those stickies be siblings.
  4. Every sticky note has variable heights and may be fixed width. Please don't hardcode the height.

Note: I am ready to provide as much as information. I don't see why this question gets close votes!

Praveen Kumar Purushothaman
  • 154,660
  • 22
  • 177
  • 226

5 Answers5

10

EDIT: I did it :). Using transform rotate from the top left on the notes, then reversing the rotation from top left of the parent div. XD

You can change the degrees as long as the parent is negative the same degrees for different offset degrees...

I have eaten my own words saying you can't do it without programming...


I don't know how to overline the rest of the answer, this is the old answer.


The best I could come up with.

Uses pseudo before and after.

Before creates a "bar" the width of the left offset and set height. So if after has more than 200px of height, it falls back to home left.

After is the part that shows the sticky note.

If anyone can figure out how to move this into the element itself, without being in pseudo using the title attribute, then we win! Otherwise that's the closest you can get without creating extra elements. It's about as semantic as sticky notes get too. Very intriguing question!

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;
}
Luke Flego
  • 185
  • 6
  • Looks good for a first attempt buddy!!! Appreciated! But still, I am sceptical why you use `content: attr(title)`, how is it different from having the content in it. – Praveen Kumar Purushothaman Jun 26 '15 at 19:08
  • Have a play. You will see that the content isn't actually where you think it is. It's before the sticky note. Since the styling is in the :after class, the actual .note content is before. This is the only way I could come up with a stepping of the notes as you asked without some form of programming (js or sass) – Luke Flego Jun 26 '15 at 19:11
  • There's another problem with this approach, as you cannot select the contents of the note! Did you see? – Praveen Kumar Purushothaman Jun 26 '15 at 19:12
  • Yep since :before and :after aren't part of the DOM they aren't selectable. However, you didn't ask for that ;) – Luke Flego Jun 26 '15 at 19:15
  • 2
    I have no idea what you're intentions are with this... ;) But as I said, this is THE BEST I CAN DO, without some kind of programming. I personally think the best option is the sass way by @Oka. What you're after just cannot be done, as nicely as we all want by plain CSS. – Luke Flego Jun 26 '15 at 19:21
  • Nice solution, can they have variable height that way? – loli Jun 29 '15 at 16:39
  • @loli Yep, set up min-height as 200. Content can exceed that and make a long sticky note. The following stickies are just -180px from the bottom of the before sticky. – Luke Flego Jul 03 '15 at 14:19
8

You can make your elements float and give them a negative margin for the desired effect. The <div class="nofloat">Floating box</div> is to make every annotation skip a line. The visibility is set to hidden so that the element still affects the layout.

<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 for example : http://jsfiddle.net/1nu02a37/

loli
  • 1,078
  • 7
  • 14
  • I know this before, but I don't wanna nest it! Else I can use `
      ` and `
    • ` right? Don't get offended, but sorry to say, this is not an answer that I am looking for! `:(`
    – Praveen Kumar Purushothaman Jun 25 '15 at 16:01
  • I guess you are planning to update your answer, is it? `:)` – Praveen Kumar Purushothaman Jun 25 '15 at 16:31
  • 1
    nah, just in case you don't find any other solution! – loli Jun 25 '15 at 16:39
  • I saw this after the edit and this is really clever. I tried to come up with something similar earlier but mine didn't work. Is it possible to use content:after to insert the hidden divs? That would really clean up the markup. – Syntax Error Jun 25 '15 at 20:41
  • 2
    I played with it - here's a way to do it in less code - also more straightforward to understand why it works: http://jsfiddle.net/o9snaxwp/ – Syntax Error Jun 25 '15 at 20:50
  • It looks semantically wrong, if you can get rid of the `noFloat` it would be awesome. Can you try something? – Praveen Kumar Purushothaman Jun 25 '15 at 21:13
  • 1
    @SyntaxError This can't be done with pseudo-elements, because the [formatting contexts](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Block_formatting_context) would be wrong. – Oka Jun 25 '15 at 21:27
  • @PraveenKumar did you see my jsfiddle in this comment thread that does it with simple
    instead?
    – Syntax Error Jun 25 '15 at 21:48
  • Man `
    ` is simple, but bad. Don't use `tables` and `br`s for layout purposes...
    – Praveen Kumar Purushothaman Jun 25 '15 at 21:56
  • I've +1'd this idea, but perhaps this might be ever-so-slightly better? http://jsfiddle.net/o9snaxwp/2/ – Jamie Barker Jun 26 '15 at 08:57
  • Wow I really like the
    idea @Syntax Error, didn't think about this.
    – loli Jun 26 '15 at 12:11
  • Ah!!! This doesn't work with variable heights!!! I am more interested in stacking the tops, not the bottoms. So... Anything for that? – Praveen Kumar Purushothaman Jun 26 '15 at 19:13
  • What do you mean it doesn't work with variable height? look here I changed some height and it works http://jsfiddle.net/1nu02a37/4/ – loli Jun 27 '15 at 11:51
  • 3
    @PraveenKumar The rule for not using tables or br for layout is a rule of thumb for beginners, not a rule of law for all scenarios. Writing convoluted workarounds to avoid an easy to understand
    in your code is a good example of when to break this rule. I can appreciate looking for a CSS only way, but in this situation a
    is certainly not "bad" considering your other options.
    – Syntax Error Jun 29 '15 at 16:12
4

This is a really interesting question. I think I'm going to look at it semantically rather than practically at the code.

I understand why you don't want to nest them, and at first thought it seems semantically wrong to do so. But I think that's where you're making a mistake.

Think about a physical stack of sticky notes. Are they beside each other, or have they been combined into another distinct "thing"?

Semantically, they are a stack. You could look at it and say this is a clear physical representation of a list, with the ul being the stack and the li being the notes. This makes perfect semantic sense.

You could also say that the physical placement of each note depends on the physical placement of the one before it. You are physically nesting related notes on each other (they just stick out on the right and bottom) but the organization of each consecutive note depends on the one before it. Some might say this is a design thing and not semantic, but why are you stacking the notes if they're not semantically related to begin with? This means that nesting them can also make perfect sense semantically.

To have them side by side in your code but represented as not side by side to the user actually seems semantically meaningless to me. Unless you have a parent container to represent the stack. Which means you're essentially just using other elements to represent ul/li.

Syntax Error
  • 4,269
  • 2
  • 19
  • 31
3

A touch of JavaScript can do the trick.

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>
Jamie Barker
  • 7,735
  • 3
  • 26
  • 62
1

If you're not going to nest them, I don't believe there is a very viable way to do this in a truly scalable fashion. Negative margins will work vertically, but you'll always need an incremental value if you want the notes to extend towards the right.

You can do this with a preprocessor, if you enjoy 4000 lines of source code just for your 1k stack. Trivial, really, but that's still a hard limit.

Sass - DEMO

I would post the output in a snippet, but SO yelled at me.

Body is limited to 30000 characters; you entered 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 is a pretty non-scalable language when it comes to certain repetitive tasks.

I also agree with Syntax Error about the semantics of this.

Realistically, I'm not sure why you would need a scalable CSS solution for markup that obviously has to be generated. There's no way you're manually writing in hundreds of .stickynote elements. Whatever is generating the markup could generate the styles as well.

Oka
  • 14,862
  • 5
  • 34
  • 46