diff --git a/editors/editoria/src/layout/EditorElements.js b/editors/editoria/src/layout/EditorElements.js
index e2e896a3663293f4913c2f9e692fd45ce1d3a1a2..d31d0839f3254b47f51b51fb181579e23e7b2429 100644
--- a/editors/editoria/src/layout/EditorElements.js
+++ b/editors/editoria/src/layout/EditorElements.js
@@ -30,7 +30,8 @@ export default css`
     h4 span::selection,
     code span::selection,
     custom-tag-block::selection,
-    custom-tag-inline::selection {
+    custom-tag-inline::selection,
+     figcaption span::selection, {
       background-color: transparent;
     }
 
@@ -100,9 +101,36 @@ export default css`
     margin-right: 0;
   }
 
-  img {
-    cursor: default;
-    width: 100%;
+  figure {
+    display: table;
+    flex-direction: column;
+    margin-left: auto;
+    margin-right: auto;
+
+    img {
+      cursor: default;
+      height: auto;
+      max-width: 100%;
+      width: auto;
+    }
+
+    figcaption {
+      background: #e2ebff;
+      caption-side: bottom;
+      display: table-caption;
+      max-width: 100%;
+      min-height: 20px;
+      padding: 4px;
+      width: auto;
+
+      &:focus {
+        outline: none;
+      }
+      &: before {
+        content: 'Caption : ';
+        font-weight: bold;
+      }
+    }
   }
 
   sup,
diff --git a/wax-prosemirror-components/src/components/comments/CommentBubbleComponent.js b/wax-prosemirror-components/src/components/comments/CommentBubbleComponent.js
index 9e9f9818b5293a9c99db74ff407d8481a6eff31b..4dce8b2db5390262770c03b70ea99106a8611299 100644
--- a/wax-prosemirror-components/src/components/comments/CommentBubbleComponent.js
+++ b/wax-prosemirror-components/src/components/comments/CommentBubbleComponent.js
@@ -41,7 +41,8 @@ const CommentBubbleComponent = ({
       (node, from) => {
         if (
           node.type.name === 'math_display' ||
-          node.type.name === 'math_inline'
+          node.type.name === 'math_inline' ||
+          node.type.name === 'image'
         ) {
           allowed = false;
         }
diff --git a/wax-prosemirror-plugins/src/images/captionPlugin.js b/wax-prosemirror-plugins/src/images/captionPlugin.js
index 6ae3b7a1d41764b68fde03877d624c0a5a3589d8..ea7acd9fffe6cd7aa57e5a9fa2c53de99fa6ddb0 100644
--- a/wax-prosemirror-plugins/src/images/captionPlugin.js
+++ b/wax-prosemirror-plugins/src/images/captionPlugin.js
@@ -1,18 +1,106 @@
-import { Decoration, DecorationSet } from 'prosemirror-view';
-import { Plugin, TextSelection } from 'prosemirror-state';
+import { DecorationSet } from 'prosemirror-view';
+import { Plugin, PluginKey, NodeSelection } from 'prosemirror-state';
 
 const captionPlugin = key =>
   new Plugin({
+    key: new PluginKey(key),
     state: {
       init() {
         return DecorationSet.empty;
       },
-      apply(tr, set) {},
+      apply(tr, set) {
+        let setMap = set;
+        setMap = setMap.map(tr.mapping, tr.doc);
+        setMap = setMap.remove(set.find(null, null, spec => spec.id != null));
+        return setMap;
+      },
     },
     props: {
       decorations(state) {
         return this.getState(state);
       },
+      handleDOMEvents: {
+        mousedown(view, e) {
+          const captionPlugins = view.state.plugins.find(plugin =>
+            plugin.key.startsWith('caption$'),
+          );
+
+          if (
+            e.target.nodeName === 'IMG' &&
+            e.target.parentNode.lastElementChild.nodeName !== 'FIGCAPTION'
+          ) {
+            let pos = view.posAtDOM(e.target);
+            const id = {};
+            const { tr } = view.state;
+            pos += 1;
+            //  insert figure caption node
+            view.dispatch(
+              tr
+                .replaceWith(
+                  pos,
+                  pos,
+                  view.state.schema.nodes.figcaption.create({
+                    class: 'decoration',
+                    dataContent: 'Caption : ',
+                  }),
+                )
+                .setMeta(captionPlugins, {
+                  add: { id, pos },
+                }),
+            );
+          } else if (e.target.nodeName !== 'FIGCAPTION') {
+            const decorationelement = document.getElementsByTagName(
+              'figcaption',
+            );
+            const decorationLength = decorationelement.length;
+
+            if (decorationLength) {
+              for (let i = 0; i < decorationLength; i += 1) {
+                if (!decorationelement[i].textContent.length) {
+                  decorationelement[i].remove();
+                } else if (
+                  decorationelement[i].parentElement.firstChild.tagName ===
+                  'FIGCAPTION'
+                ) {
+                  decorationelement[i].parentElement.remove();
+                }
+              }
+            }
+          }
+
+          if (e.target.nodeName === 'IMG') {
+            let pos = view.posAtDOM(e.target);
+            const { $from } = view.state.selection;
+            const same = $from.sharedDepth(pos);
+            if (same === 0) return false;
+            pos = $from.before(same);
+            view.dispatch(
+              view.state.tr.setSelection(
+                NodeSelection.create(view.state.doc, pos),
+              ),
+            );
+          }
+
+          return true;
+        },
+        keyup(view, e) {
+          // delete caption if figure is deleted
+          if (e.key === 'Delete') {
+            const figcap = document.getElementsByTagName('figcaption');
+            const figcapLength = figcap.length;
+
+            if (figcapLength) {
+              for (let i = 0; i < figcapLength; i += 1) {
+                if (
+                  figcap[i].parentElement.firstChild.tagName === 'FIGCAPTION'
+                ) {
+                  figcap[i].parentElement.remove();
+                }
+              }
+            }
+          }
+        },
+      },
     },
   });
 
diff --git a/wax-prosemirror-plugins/src/images/placeHolderPlugin.js b/wax-prosemirror-plugins/src/images/placeHolderPlugin.js
index 7cbe9bdfd3695f1db32fa5f06385f11a8eab1aef..2d294a6977137a57782bd93a90ff2220efe21495 100644
--- a/wax-prosemirror-plugins/src/images/placeHolderPlugin.js
+++ b/wax-prosemirror-plugins/src/images/placeHolderPlugin.js
@@ -20,9 +20,9 @@ export default key =>
           });
           set = set.add(tr.doc, [deco]);
         } else if (action && action.remove) {
-          set = set.remove(
-            set.find(null, null, spec => spec.id === action.remove.id),
-          );
+          // set = set.remove(
+          //   set.find(null, null, spec => spec.id === action.remove.id),
+          // );
         }
         return set;
       },
diff --git a/wax-prosemirror-schema/index.js b/wax-prosemirror-schema/index.js
index 30b965c426c43930e2172e545a4fcd02b8357334..fd0c54754ca8ddb00116031f1adf81aa472b81b9 100644
--- a/wax-prosemirror-schema/index.js
+++ b/wax-prosemirror-schema/index.js
@@ -37,7 +37,7 @@ export { default as bulletListNode } from './src/nodes/bulletListNode';
 export { default as listItemNode } from './src/nodes/listItemNode';
 export { default as subTitleNode } from './src/nodes/subTitleNode';
 export { default as figureNode } from './src/nodes/figureNode';
-export { default as figureCaptionNode } from './src/nodes/figureNode';
+export { default as figureCaptionNode } from './src/nodes/figureCaptionNode';
 export { default as imageNode } from './src/nodes/imageNode';
 export { default as headingNode } from './src/nodes/headingNode';
 export { default as blockQuoteNode } from './src/nodes/blockQuoteNode';
diff --git a/wax-prosemirror-schema/src/nodes/figureCaptionNode.js b/wax-prosemirror-schema/src/nodes/figureCaptionNode.js
index a4303d6b9aa04556b7c5631ec6f00e6d42f6ed9a..2b267b1d5ee18978aa9756f31ad2faaa5b73a1f0 100644
--- a/wax-prosemirror-schema/src/nodes/figureCaptionNode.js
+++ b/wax-prosemirror-schema/src/nodes/figureCaptionNode.js
@@ -1,11 +1,26 @@
 const figureCaption = {
   content: 'inline*',
   group: 'figure',
-  marks: 'strong link',
-  parseDOM: [{ tag: 'figcaption' }],
-  toDOM(node) {
-    return ['figcaption', 0];
+  draggable: false,
+  attrs: {
+    class: { default: '' },
+    tabindex: { default: 0 },
+    dataContent: { default: '' },
   },
+  toDOM: node => {
+    return ['figcaption', node.attrs, 0];
+  },
+  parseDOM: [
+    {
+      tag: 'figcaption',
+      getAttrs(dom) {
+        return {
+          class: dom.getAttribute('class'),
+          dataContent: dom.getAttribute('dataContent'),
+        };
+      },
+    },
+  ],
 };
 
 export default figureCaption;
diff --git a/wax-prosemirror-schema/src/nodes/imageNode.js b/wax-prosemirror-schema/src/nodes/imageNode.js
index 40e38f316a572f8d2bf5318449ccb56045564103..34e825c63b235142d72dbbc7415174caca9dda80 100644
--- a/wax-prosemirror-schema/src/nodes/imageNode.js
+++ b/wax-prosemirror-schema/src/nodes/imageNode.js
@@ -1,6 +1,6 @@
 import { SchemaHelpers } from 'wax-prosemirror-utilities';
+
 const image = {
-  // inline: true,
   attrs: {
     src: {},
     alt: { default: null },
@@ -8,7 +8,7 @@ const image = {
     track: { default: [] },
   },
   group: 'figure',
-  draggable: true,
+  draggable: false,
   parseDOM: [
     {
       tag: 'img[src]',
@@ -26,12 +26,15 @@ const image = {
   ],
   toDOM(hook, next) {
     const attrs = {};
-    let temp = '';
+
     if (hook.node.attrs.track && hook.node.attrs.track.length) {
       attrs['data-track'] = JSON.stringify(hook.node.attrs.track);
       attrs['data-id'] = hook.node.attrs.id;
     }
+
     const { src, alt, title, id, track } = hook.node.attrs;
+
+    // eslint-disable-next-line no-param-reassign
     hook.value = [
       'img',
       { src, alt, title, 'data-id': id, 'data-track': track },
diff --git a/wax-prosemirror-services/src/DisplayBlockLevel/HeadingService/Heading2.js b/wax-prosemirror-services/src/DisplayBlockLevel/HeadingService/Heading2.js
index f29ab84670b3e5413ec6a3ba648ab8da80b76bcb..d48724224265e0f2b58fdc2e6d0f6fb0a326d83f 100644
--- a/wax-prosemirror-services/src/DisplayBlockLevel/HeadingService/Heading2.js
+++ b/wax-prosemirror-services/src/DisplayBlockLevel/HeadingService/Heading2.js
@@ -27,7 +27,12 @@ class Heading2 extends Tools {
       if (activeViewId !== 'main') return false;
       const { from, to } = state.selection;
       state.doc.nodesBetween(from, to, (node, pos) => {
-        if (node.type.name === 'list_item' || node.type.name === 'image') {
+        if (
+          node.type.name === 'list_item' ||
+          node.type.name === 'image' ||
+          node.type.name === 'figure' ||
+          node.type.name === 'figcaption'
+        ) {
           isActive = false;
         }
       });
diff --git a/wax-prosemirror-services/src/DisplayBlockLevel/HeadingService/Heading3.js b/wax-prosemirror-services/src/DisplayBlockLevel/HeadingService/Heading3.js
index e2dd3d94ecd790c725fd28c363938c0fe2dcd00a..e79ea62f3f7e83468e372ff42be80904c1250a51 100644
--- a/wax-prosemirror-services/src/DisplayBlockLevel/HeadingService/Heading3.js
+++ b/wax-prosemirror-services/src/DisplayBlockLevel/HeadingService/Heading3.js
@@ -27,7 +27,12 @@ class Heading3 extends Tools {
       if (activeViewId !== 'main') return false;
       const { from, to } = state.selection;
       state.doc.nodesBetween(from, to, (node, pos) => {
-        if (node.type.name === 'list_item' || node.type.name === 'image') {
+        if (
+          node.type.name === 'list_item' ||
+          node.type.name === 'image' ||
+          node.type.name === 'figure' ||
+          node.type.name === 'figcaption'
+        ) {
           isActive = false;
         }
       });
diff --git a/wax-prosemirror-services/src/DisplayBlockLevel/HeadingService/Heading4.js b/wax-prosemirror-services/src/DisplayBlockLevel/HeadingService/Heading4.js
index 3991590cf620ef5a844e0d16726dd36262ce5912..31df0dcb9296c62d307cb57542511d0e18de5103 100644
--- a/wax-prosemirror-services/src/DisplayBlockLevel/HeadingService/Heading4.js
+++ b/wax-prosemirror-services/src/DisplayBlockLevel/HeadingService/Heading4.js
@@ -27,7 +27,12 @@ class Heading4 extends Tools {
       if (activeViewId !== 'main') return false;
       const { from, to } = state.selection;
       state.doc.nodesBetween(from, to, (node, pos) => {
-        if (node.type.name === 'list_item' || node.type.name === 'image') {
+        if (
+          node.type.name === 'list_item' ||
+          node.type.name === 'image' ||
+          node.type.name === 'figure' ||
+          node.type.name === 'figcaption'
+        ) {
           isActive = false;
         }
       });
diff --git a/wax-prosemirror-services/src/ImageService/ImageService.js b/wax-prosemirror-services/src/ImageService/ImageService.js
index c25501933b0a6552f2a703f722fe04c8343c4c8f..13b1612440ad896c18d1d7350cc2c484f1caf393 100644
--- a/wax-prosemirror-services/src/ImageService/ImageService.js
+++ b/wax-prosemirror-services/src/ImageService/ImageService.js
@@ -33,7 +33,10 @@ class ImageService extends Service {
     );
     createNode({
       figcaption: figureCaptionNode,
-    });
+    }
+    // ,
+    // { toWaxSchema: true },
+    );
   }
 }
 
diff --git a/wax-prosemirror-services/src/ImageService/fileUpload.js b/wax-prosemirror-services/src/ImageService/fileUpload.js
index 36a6040420141f93373cffb4021006c538b3d009..d0e5d61139f3793a8060c4e3c904f2b7b56d567e 100644
--- a/wax-prosemirror-services/src/ImageService/fileUpload.js
+++ b/wax-prosemirror-services/src/ImageService/fileUpload.js
@@ -34,6 +34,9 @@ export default (view, fileUpload, placeholderPlugin) => file => {
           .replaceWith(
             pos,
             pos,
+            // view.state.schema.nodes.image.create({
+            //   src: url,
+            // }),
             view.state.schema.nodes.image.create({
               src: url,
             }),