diff --git a/wax-prosemirror-components/package.json b/wax-prosemirror-components/package.json
index 62e8b017c43b4ca8d748379d4f24a5268ca0076a..d26175b1a0202ce69d469ddd7ca16b11d42bee81 100644
--- a/wax-prosemirror-components/package.json
+++ b/wax-prosemirror-components/package.json
@@ -17,6 +17,7 @@
     "react-dom": "^16.8.6",
     "react-dropdown": "^1.6.2",
     "styled-components": "^4.2.0",
-    "uuid": "^3.3.2"
+    "uuid": "^3.3.2",
+    "react-transition-group": "^4.3.0"
   }
 }
diff --git a/wax-prosemirror-components/src/components/comments/CommentBox.js b/wax-prosemirror-components/src/components/comments/CommentBox.js
index 32e0042cb9420d80be1fd128f5adb4b3db1dab72..f5f0119617d7bc21dd772834b74cf90c4eaba937 100644
--- a/wax-prosemirror-components/src/components/comments/CommentBox.js
+++ b/wax-prosemirror-components/src/components/comments/CommentBox.js
@@ -1,10 +1,7 @@
-import React, { useEffect, useRef, useContext } from "react";
+import React, { Fragment, useState, useCallback, useEffect } from "react";
+import { Transition } from "react-transition-group";
 import styled from "styled-components";
 
-// export default ({ node, view }) => {
-//   useEffect(() => {}, []);
-// };
-
 const CommentBoxStyled = styled.div`
   height: 50px;
   width: 50px;
@@ -12,7 +9,42 @@ const CommentBoxStyled = styled.div`
   flex-direction: column;
   margin-top: 10px;
   background: black;
+  position: absolute;
+  transition: ${({ state }) => "top 1s, opacity 1.5s"};
+  top: ${props => (props.top ? `${props.top}px` : 0)};
+
+  opacity: ${({ state }) => {
+    switch (state) {
+      case "exited":
+        return 0.2;
+      case "exiting":
+        return 0.4;
+      case "entering":
+        return 0.6;
+      case "entered":
+        return 1;
+    }
+  }};
 `;
 
-const CommentBox = () => <CommentBoxStyled />;
-export default CommentBox;
+export default ({ mark, view, top, dataComment }) => {
+  const [animate, setAnimate] = useState(false);
+
+  useEffect(() => {
+    setAnimate(true);
+  }, []);
+
+  return (
+    <Fragment>
+      <Transition in={animate} timeout={1000}>
+        {state => (
+          <CommentBoxStyled
+            top={top}
+            state={state}
+            data-comment={dataComment}
+          />
+        )}
+      </Transition>
+    </Fragment>
+  );
+};
diff --git a/wax-prosemirror-components/src/components/comments/CommentBubbleComponent.js b/wax-prosemirror-components/src/components/comments/CommentBubbleComponent.js
index 4e925fdd855ee3c370f7d5c02e4392122e117ec3..763ca2a20e81a6563a6cc60723b751426f799761 100644
--- a/wax-prosemirror-components/src/components/comments/CommentBubbleComponent.js
+++ b/wax-prosemirror-components/src/components/comments/CommentBubbleComponent.js
@@ -2,9 +2,10 @@ import React, { useLayoutEffect, useState, useContext } from "react";
 import styled from "styled-components";
 import { Commands } from "wax-prosemirror-utilities";
 import { WaxContext } from "wax-prosemirror-core/src/ioc-react";
+import { DocumentHelpers } from "wax-prosemirror-utilities";
 
 const CommentBubbleComponent = ({ setPosition, position }) => {
-  const { view: { main }, activeView } = useContext(WaxContext);
+  const { activeView, activeViewId } = useContext(WaxContext);
   const { state, dispatch } = activeView;
   useLayoutEffect(
     () => {
@@ -23,17 +24,29 @@ const CommentBubbleComponent = ({ setPosition, position }) => {
 
   const createComment = event => {
     event.preventDefault();
-    Commands.createComment(state, dispatch);
+    Commands.createComment(state, dispatch, activeViewId);
+  };
+
+  const isSelectionComment = () => {
+    const commentMark = activeView.state.schema.marks["comment"];
+    const mark = DocumentHelpers.findMark(state, commentMark, true);
+    const { selection: { $from, $to }, doc } = state;
+
+    //TODO Overlapping comments . for now don't allow
+    if (mark.length >= 1) return true;
+    return false;
   };
 
   return (
-    <button
-      onClick={event => {
-        createComment(event);
-      }}
-    >
-      create
-    </button>
+    !isSelectionComment() && (
+      <button
+        onClick={event => {
+          createComment(event);
+        }}
+      >
+        create
+      </button>
+    )
   );
 };
 
diff --git a/wax-prosemirror-components/src/components/comments/CommentsBoxList.js b/wax-prosemirror-components/src/components/comments/CommentsBoxList.js
index 01299fe178e4b00f71775474764ea1f0fe5c1caf..8b63ba02501d9bd4c1bf544d664003011d5829b9 100644
--- a/wax-prosemirror-components/src/components/comments/CommentsBoxList.js
+++ b/wax-prosemirror-components/src/components/comments/CommentsBoxList.js
@@ -1,12 +1,105 @@
-import React, { Fragment } from "react";
+import React, { Fragment, useState, useEffect, useCallback } from "react";
+import { each } from "lodash";
 import CommentBox from "./CommentBox";
 
+//TODO find from marks actual comment mark
 export default ({ comments, view }) => {
+  const [position, setPosition] = useState();
+
+  const setTops = useCallback(() => {
+    const result = [];
+    const boxes = [];
+    let commentEl = null;
+    let annotationTop = 0;
+    let boxHeight = 0;
+    let top = 0;
+    const allCommentsTop = {};
+
+    each(comments, (entry, pos) => {
+      const WaxSurface = view.dom.getBoundingClientRect();
+      const id = entry.node.marks[0].attrs.id;
+      let isActive = false;
+      // if (entry.id === active) isActive = true
+      commentEl = document.getElementById(id);
+      //annotation top
+      annotationTop = commentEl.getBoundingClientRect().top - WaxSurface.top;
+      // get height of this comment box
+      const boxEl = document.querySelector(`div[data-comment="comment-${id}"]`);
+      if (boxEl) boxHeight = parseInt(boxEl.offsetHeight);
+
+      // keep the elements to add the tops to at the end
+      boxes.push(boxEl);
+
+      // where the box should move to
+      top = annotationTop;
+
+      // if the above comment box has already taken up the height, move down
+      if (pos > 0) {
+        const previousBox = comments[pos - 1];
+        const previousEndHeight = previousBox.endHeight;
+        if (annotationTop < previousEndHeight) {
+          top = previousEndHeight + 2;
+        }
+      }
+      // store where the box ends to be aware of overlaps in the next box
+      entry.endHeight = top + boxHeight + 2;
+      result[pos] = top;
+
+      // if active, move as many boxes above as needed to bring it to the annotation's height
+      if (isActive) {
+        entry.endHeight = annotationTop + boxHeight + 2;
+        result[pos] = annotationTop;
+
+        let b = true;
+        let i = pos;
+
+        // first one active, none above
+        if (i === 0) b = false;
+
+        while (b) {
+          const boxAbove = comments[i - 1];
+          const boxAboveEnds = boxAbove.endHeight;
+          const currentTop = result[i];
+
+          const doesOverlap = boxAboveEnds > currentTop;
+          if (doesOverlap) {
+            const overlap = boxAboveEnds - currentTop;
+            result[i - 1] -= overlap;
+          }
+
+          if (!doesOverlap) b = false;
+          if (i <= 1) b = false;
+          i -= 1;
+        }
+      }
+
+      allCommentsTop[id] = top;
+    });
+
+    return allCommentsTop;
+  });
+
+  useEffect(
+    () => {
+      setPosition(setTops());
+    },
+    [JSON.stringify(setTops())]
+  );
+
   return (
     <Fragment>
-      {comments.map(comment => (
-        <CommentBox key="" node={comment.node} view={view} />
-      ))}
+      {comments.map(comment => {
+        const id = comment.node.marks[0].attrs.id;
+        return (
+          <CommentBox
+            key={comment.node.marks[0].attrs.id}
+            mark={comment.node.marks[0]}
+            view={view}
+            top={position[id]}
+            dataComment={`comment-${id}`}
+          />
+        );
+      })}
     </Fragment>
   );
 };
diff --git a/wax-prosemirror-schema/src/marks/commentMark.js b/wax-prosemirror-schema/src/marks/commentMark.js
index 5c47ceae3702804977441ead1606ce2523bc1aaf..a8a5d918600690f9e6def88399784c194c19012d 100644
--- a/wax-prosemirror-schema/src/marks/commentMark.js
+++ b/wax-prosemirror-schema/src/marks/commentMark.js
@@ -1,14 +1,18 @@
 const comment = {
   attrs: {
+    id: { default: "" },
+    viewId: { default: "" },
     conversation: []
   },
   inclusive: false,
-  excludes: "",
+  // excludes: "",
   parseDOM: [
     {
       tag: "span.comment[data-conversation]",
       getAttrs(dom) {
         return {
+          id: dom.id,
+          viewId: dom.dataset.viewid,
           conversation: JSON.parse(dom.dataset.conversation)
         };
       }
@@ -19,6 +23,8 @@ const comment = {
       "span",
       {
         class: "comment",
+        id: node.attrs.id,
+        "data-viewId": node.attrs.viewId,
         "data-conversation": JSON.stringify(node.attrs.conversation)
       }
     ];
diff --git a/wax-prosemirror-services/src/NoteService/NoteEditor.js b/wax-prosemirror-services/src/NoteService/NoteEditor.js
index 177582a2ab0b0d910e2fed5d39d9cc90c4265bdc..7cf4f57522743738fe5b978de33cfbcc0dced83c 100644
--- a/wax-prosemirror-services/src/NoteService/NoteEditor.js
+++ b/wax-prosemirror-services/src/NoteService/NoteEditor.js
@@ -1,12 +1,12 @@
-import React from "react";
+import React, { Fragment } from "react";
 import Editor from "./Editor";
 
 export default ({ notes, view }) => {
   return (
-    <div>
+    <Fragment>
       {notes.map(note => (
         <Editor key={note.node.attrs.id} node={note.node} view={view} />
       ))}
-    </div>
+    </Fragment>
   );
 };
diff --git a/wax-prosemirror-utilities/src/commands/Commands.js b/wax-prosemirror-utilities/src/commands/Commands.js
index 2f119ea080aa341340f10c72f8181330558c2780..27b25c3b5a95fc4b0123036da47c2ffc9ba9acb1 100644
--- a/wax-prosemirror-utilities/src/commands/Commands.js
+++ b/wax-prosemirror-utilities/src/commands/Commands.js
@@ -1,3 +1,5 @@
+import { v4 as uuid } from "uuid";
+
 const markActive = type => state => {
   const { from, $from, to, empty } = state.selection;
 
@@ -57,13 +59,15 @@ const createLink = (state, dispatch) => {
   );
 };
 
-const createComment = (state, dispatch) => {
+const createComment = (state, dispatch, activeViewId) => {
   const { selection: { $from, $to } } = state;
   dispatch(
     state.tr.addMark(
       $from.pos,
       $to.pos,
       state.schema.marks.comment.create({
+        id: uuid(),
+        viewId: activeViewId,
         conversation: []
       })
     )
diff --git a/wax-prosemirror-utilities/src/document/DocumentHelpers.js b/wax-prosemirror-utilities/src/document/DocumentHelpers.js
index 62af5f2b1efae3206ec8fc0734c019c519c1fa3b..716b5c35a2b624c645ed78264f18776e2890949e 100644
--- a/wax-prosemirror-utilities/src/document/DocumentHelpers.js
+++ b/wax-prosemirror-utilities/src/document/DocumentHelpers.js
@@ -1,9 +1,10 @@
-const findMark = (state, PMmark) => {
+const findMark = (state, PMmark, toArr = false) => {
   const { selection: { $from, $to }, doc } = state;
 
   const fromMark = $from.marks().find(mark => mark.type === PMmark);
   const toMark = $to.marks().find(mark => mark.type === PMmark);
   let markFound;
+  const marksFound = [];
   doc.nodesBetween($from.pos, $to.pos, (node, from) => {
     if (node.marks) {
       const actualMark = node.marks.find(mark => mark.type === PMmark);
@@ -14,9 +15,11 @@ const findMark = (state, PMmark) => {
           attrs: actualMark.attrs,
           contained: !fromMark || !toMark || fromMark === toMark
         };
+        marksFound.push(markFound);
       }
     }
   });
+  if (toArr) return marksFound;
   return markFound;
 };