diff --git a/src/components/containers/TagField/styles.scss b/src/components/containers/TagField/styles.scss
index f65e12d0..18edac3e 100644
--- a/src/components/containers/TagField/styles.scss
+++ b/src/components/containers/TagField/styles.scss
@@ -3,4 +3,8 @@
   align-items: flex-start;
   justify-content: flex-start;
   flex-wrap: wrap;
+
+  &> * {
+    margin: 0 $gap $gap 0;
+  }
 }
diff --git a/src/components/node/NodeTags/index.tsx b/src/components/node/NodeTags/index.tsx
index 910d2590..d5c48923 100644
--- a/src/components/node/NodeTags/index.tsx
+++ b/src/components/node/NodeTags/index.tsx
@@ -1,6 +1,6 @@
 import React, { FC, memo } from 'react';
-import { Tags } from '../Tags';
 import { ITag } from '~/redux/types';
+import { Tags } from '~/components/tags/Tags';
 
 interface IProps {
   is_editable?: boolean;
diff --git a/src/components/node/NodeTags/placeholder.tsx b/src/components/node/NodeTags/placeholder.tsx
deleted file mode 100644
index f5b015b4..00000000
--- a/src/components/node/NodeTags/placeholder.tsx
+++ /dev/null
@@ -1,17 +0,0 @@
-import React, { FC, memo } from "react";
-import { Tags } from "../Tags";
-import { ITag } from "~/redux/types";
-
-interface IProps {
-  is_editable?: boolean;
-  tags: ITag[];
-  onChange?: (tags: string[]) => void;
-}
-
-const NodeTagsPlaceholder: FC<IProps> = memo(
-  ({ is_editable, tags, onChange }) => (
-    <Tags tags={tags} is_editable={is_editable} onTagsChange={onChange} />
-  )
-);
-
-export { NodeTagsPlaceholder };
diff --git a/src/components/node/NodeTagsPlaceholder/index.tsx b/src/components/node/NodeTagsPlaceholder/index.tsx
new file mode 100644
index 00000000..4fb8e75d
--- /dev/null
+++ b/src/components/node/NodeTagsPlaceholder/index.tsx
@@ -0,0 +1,15 @@
+import React, { FC, memo } from 'react';
+import { ITag } from '~/redux/types';
+import { Tags } from '~/components/tags/Tags';
+
+interface IProps {
+  is_editable?: boolean;
+  tags: ITag[];
+  onChange?: (tags: string[]) => void;
+}
+
+const NodeTagsPlaceholder: FC<IProps> = memo(({ is_editable, tags, onChange }) => (
+  <Tags tags={tags} is_editable={is_editable} onTagsChange={onChange} />
+));
+
+export { NodeTagsPlaceholder };
diff --git a/src/components/node/Tag/index.tsx b/src/components/node/Tag/index.tsx
deleted file mode 100644
index f9bb1c8a..00000000
--- a/src/components/node/Tag/index.tsx
+++ /dev/null
@@ -1,69 +0,0 @@
-import React, { ChangeEventHandler, FC, FocusEventHandler, KeyboardEventHandler, useCallback, } from 'react';
-import * as styles from './styles.scss';
-import { ITag } from '~/redux/types';
-import classNames = require('classnames');
-
-const getTagFeature = (tag: Partial<ITag>) => {
-  if (tag.title.substr(0, 1) === '/') return 'green';
-
-  return '';
-};
-
-interface IProps {
-  tag: Partial<ITag>;
-  size?: 'normal' | 'big';
-
-  is_hoverable?: boolean;
-  is_editing?: boolean;
-
-  onInput?: ChangeEventHandler<HTMLInputElement>;
-  onKeyUp?: KeyboardEventHandler;
-  onBlur?: FocusEventHandler<HTMLInputElement>;
-  onClick?: (tag: Partial<ITag>) => void;
-}
-
-const Tag: FC<IProps> = ({
-  tag,
-  is_hoverable,
-  is_editing,
-  size = 'normal',
-  onInput,
-  onKeyUp,
-  onBlur,
-  onClick,
-}) => {
-  const onClickHandler = useCallback(() => {
-    if (!onClick) return;
-    onClick(tag);
-  }, [tag, onClick]);
-
-  return (
-    <div
-      className={classNames(styles.tag, getTagFeature(tag), size, {
-        is_hoverable,
-        is_editing,
-        input: !!onInput,
-        clickable: !!onClick,
-      })}
-      onClick={onClickHandler}
-    >
-      <div className={styles.hole} />
-      <div className={styles.title}>{tag.title}</div>
-
-      {onInput && (
-        <input
-          type="text"
-          value={tag.title}
-          size={1}
-          placeholder="Добавить"
-          maxLength={24}
-          onChange={onInput}
-          onKeyUp={onKeyUp}
-          onBlur={onBlur}
-        />
-      )}
-    </div>
-  );
-};
-
-export { Tag };
diff --git a/src/components/node/Tags/index.tsx b/src/components/node/Tags/index.tsx
deleted file mode 100644
index 894dde37..00000000
--- a/src/components/node/Tags/index.tsx
+++ /dev/null
@@ -1,118 +0,0 @@
-import React, {
-  ChangeEvent,
-  FC,
-  HTMLAttributes,
-  KeyboardEvent,
-  useCallback,
-  useEffect,
-  useMemo,
-  useRef,
-  useState,
-} from 'react';
-import { TagField } from '~/components/containers/TagField';
-import { ITag } from '~/redux/types';
-import { Tag } from '~/components/node/Tag';
-import uniq from 'ramda/es/uniq';
-
-type IProps = HTMLAttributes<HTMLDivElement> & {
-  tags: Partial<ITag>[];
-  is_editable?: boolean;
-  onTagsChange?: (tags: string[]) => void;
-  onTagClick?: (tag: Partial<ITag>) => void;
-};
-
-export const Tags: FC<IProps> = ({ tags, is_editable, onTagsChange, onTagClick, ...props }) => {
-  const [input, setInput] = useState('');
-  const [data, setData] = useState([]);
-  const timer = useRef(null);
-
-  const [catTags, ordinaryTags] = useMemo(
-    () =>
-      (tags || []).reduce(
-        (obj, tag) =>
-          tag.title.substr(0, 1) === '/' ? [[...obj[0], tag], obj[1]] : [obj[0], [...obj[1], tag]],
-        [[], []]
-      ),
-    [tags]
-  );
-
-  const onInput = useCallback(
-    ({ target: { value } }: ChangeEvent<HTMLInputElement>) => {
-      clearTimeout(timer.current);
-      setInput(value);
-    },
-    [setInput, timer]
-  );
-
-  const onKeyUp = useCallback(
-    ({ key }: KeyboardEvent) => {
-      if (key === 'Backspace' && input === '' && data.length) {
-        setData(data.slice(0, data.length - 1));
-        setInput(data[data.length - 1].title);
-      }
-
-      if (key === 'Enter' || key === ',' || key === 'Comma') {
-        setData(
-          uniq([
-            ...data,
-            ...input
-              .split(',')
-              .map((title: string) =>
-                title
-                  .trim()
-                  .substr(0, 32)
-                  .toLowerCase()
-              )
-              .filter(el => el.length > 0)
-              .filter(el => !tags.some(tag => tag.title.trim() === el.trim()))
-              .map(title => ({
-                title,
-              })),
-          ])
-        );
-        setInput('');
-      }
-    },
-    [input, setInput, data, setData]
-  );
-
-  const onSubmit = useCallback(() => {
-    const title = input && input.trim();
-    const items = (title ? [...data, { title }] : data)
-      .filter(tag => tag.title.length > 0)
-      .map(tag => ({
-        ...tag,
-        title: tag.title.toLowerCase(),
-      }));
-
-    if (!items.length) return;
-
-    setData(items);
-    setInput('');
-    onTagsChange(uniq([...tags, ...items]).map(tag => tag.title));
-  }, [tags, data, onTagsChange, input, setInput]);
-
-  useEffect(() => {
-    setData(data.filter(({ title }) => !tags.some(tag => tag.title.trim() === title.trim())));
-  }, [tags]);
-
-  return (
-    <TagField {...props}>
-      {catTags.map(tag => (
-        <Tag key={tag.title} tag={tag} onClick={onTagClick} />
-      ))}
-
-      {ordinaryTags.map(tag => (
-        <Tag key={tag.title} tag={tag} onClick={onTagClick} />
-      ))}
-
-      {data.map(tag => (
-        <Tag key={tag.title} tag={tag} is_editing />
-      ))}
-
-      {is_editable && (
-        <Tag tag={{ title: input }} onInput={onInput} onKeyUp={onKeyUp} onBlur={onSubmit} />
-      )}
-    </TagField>
-  );
-};
diff --git a/src/components/tags/Tag/index.tsx b/src/components/tags/Tag/index.tsx
new file mode 100644
index 00000000..2dcbc077
--- /dev/null
+++ b/src/components/tags/Tag/index.tsx
@@ -0,0 +1,43 @@
+import React, { FC, FocusEventHandler, useCallback, } from 'react';
+import * as styles from './styles.scss';
+import { ITag } from '~/redux/types';
+import { TagWrapper } from '~/components/tags/TagWrapper';
+
+const getTagFeature = (tag: Partial<ITag>) => {
+  if (tag.title.substr(0, 1) === '/') return 'green';
+
+  return '';
+};
+
+interface IProps {
+  tag: Partial<ITag>;
+  size?: 'normal' | 'big';
+
+  is_hoverable?: boolean;
+  is_editing?: boolean;
+
+  onBlur?: FocusEventHandler<HTMLInputElement>;
+  onClick?: (tag: Partial<ITag>) => void;
+}
+
+const Tag: FC<IProps> = ({ tag, is_hoverable, is_editing, size = 'normal', onBlur, onClick }) => {
+  const onClickHandler = useCallback(() => {
+    if (!onClick) return;
+    onClick(tag);
+  }, [tag, onClick]);
+
+  return (
+    <div className={styles.wrap}>
+      <TagWrapper
+        feature={getTagFeature(tag)}
+        size={size}
+        is_hoverable={is_hoverable}
+        is_editing={is_editing}
+        onClick={onClick && onClickHandler}
+        title={tag.title}
+      />
+    </div>
+  );
+};
+
+export { Tag };
diff --git a/src/components/tags/Tag/styles.scss b/src/components/tags/Tag/styles.scss
new file mode 100644
index 00000000..a834b87e
--- /dev/null
+++ b/src/components/tags/Tag/styles.scss
@@ -0,0 +1,4 @@
+.wrap {
+  background-color: blue;
+  position: relative;
+}
diff --git a/src/components/tags/TagAutocomplete/index.tsx b/src/components/tags/TagAutocomplete/index.tsx
new file mode 100644
index 00000000..69ce26fa
--- /dev/null
+++ b/src/components/tags/TagAutocomplete/index.tsx
@@ -0,0 +1,9 @@
+import React, { FC } from 'react';
+import styles from './styles.module.scss';
+import classNames from 'classnames';
+
+interface IProps {}
+
+const TagAutocomplete: FC<IProps> = () => <div className={classNames(styles.window)}>auto</div>;
+
+export { TagAutocomplete };
diff --git a/src/components/tags/TagAutocomplete/styles.module.scss b/src/components/tags/TagAutocomplete/styles.module.scss
new file mode 100644
index 00000000..740c4a96
--- /dev/null
+++ b/src/components/tags/TagAutocomplete/styles.module.scss
@@ -0,0 +1,11 @@
+.window {
+  display: none;
+  position: absolute;
+  top: 0;
+  right: 0;
+  width: calc(90vw - 20px);
+  max-width: 300px;
+  background: red;
+  height: 100px;
+  z-index: -1;
+}
diff --git a/src/components/tags/TagInput/index.tsx b/src/components/tags/TagInput/index.tsx
new file mode 100644
index 00000000..cae76eb1
--- /dev/null
+++ b/src/components/tags/TagInput/index.tsx
@@ -0,0 +1,121 @@
+import React, {
+  ChangeEvent,
+  FC,
+  FocusEventHandler,
+  KeyboardEvent,
+  useCallback,
+  useMemo,
+  useRef,
+  useState,
+} from 'react';
+import { TagAutocomplete } from '~/components/tags/TagAutocomplete';
+import { TagWrapper } from '~/components/tags/TagWrapper';
+
+const placeholder = 'Добавить';
+
+const prepareInput = (input: string): string[] => {
+  return input
+    .split(',')
+    .map((title: string) =>
+      title
+        .trim()
+        .substr(0, 32)
+        .toLowerCase()
+    )
+    .filter(el => el.length > 0);
+};
+
+interface IProps {
+  onAppend: (tags: string[]) => void;
+  onClearTag: () => string | undefined;
+  onSubmit: (last: string[]) => void;
+}
+
+const TagInput: FC<IProps> = ({ onAppend, onClearTag, onSubmit }) => {
+  const [focused, setFocused] = useState(false);
+  const [input, setInput] = useState('');
+  const ref = useRef<HTMLInputElement>(null);
+
+  const onInput = useCallback(
+    ({ target: { value } }: ChangeEvent<HTMLInputElement>) => {
+      if (!value.trim()) {
+        setInput(value);
+        return;
+      }
+
+      const items = prepareInput(value);
+
+      if (items.length > 1) {
+        onAppend(items.slice(0, items.length - 1));
+      }
+
+      setInput(items[items.length - 1]);
+    },
+    [setInput]
+  );
+
+  const onKeyUp = useCallback(
+    ({ key }: KeyboardEvent) => {
+      if (key === 'Escape' && ref.current) {
+        setInput('');
+        ref.current.blur();
+        return;
+      }
+
+      if (key === 'Backspace' && input === '') {
+        setInput(onClearTag() || '');
+        return;
+      }
+
+      if (key === 'Enter' || key === ',' || key === 'Comma') {
+        const created = prepareInput(input);
+
+        if (created.length) {
+          onAppend(created);
+        }
+
+        setInput('');
+      }
+
+      if (key === 'Enter' && ref.current) {
+        ref.current.blur();
+      }
+    },
+    [input, setInput, onClearTag, onAppend, onSubmit, ref.current]
+  );
+
+  const onFocus = useCallback(() => setFocused(true), []);
+  const onBlur = useCallback<FocusEventHandler<HTMLInputElement>>(() => {
+    setFocused(false);
+
+    if (input.trim()) {
+      const created = prepareInput(input);
+      onAppend(created);
+      setInput('');
+      onSubmit(created);
+    }
+  }, [input, onAppend, setInput, onSubmit]);
+
+  const feature = useMemo(() => (input.substr(0, 1) === '/' ? 'green' : ''), [input]);
+
+  return (
+    <TagWrapper title={input || placeholder} has_input={true} feature={feature}>
+      {onInput && <TagAutocomplete />}
+
+      <input
+        type="text"
+        value={input}
+        size={1}
+        placeholder={placeholder}
+        maxLength={24}
+        onChange={onInput}
+        onKeyUp={onKeyUp}
+        onBlur={onBlur}
+        onFocus={onFocus}
+        ref={ref}
+      />
+    </TagWrapper>
+  );
+};
+
+export { TagInput };
diff --git a/src/components/tags/TagWrapper/index.tsx b/src/components/tags/TagWrapper/index.tsx
new file mode 100644
index 00000000..2eb0f28e
--- /dev/null
+++ b/src/components/tags/TagWrapper/index.tsx
@@ -0,0 +1,40 @@
+import React, { FC } from 'react';
+import classNames from 'classnames';
+import styles from './styles.module.scss';
+
+interface IProps {
+  feature?: string;
+  size?: string;
+  is_hoverable?: boolean;
+  is_editing?: boolean;
+  has_input?: boolean;
+  onClick?: () => void;
+  title?: string;
+}
+
+const TagWrapper: FC<IProps> = ({
+  children,
+  feature,
+  size,
+  is_hoverable,
+  is_editing,
+  has_input,
+  onClick,
+  title = '',
+}) => (
+  <div
+    className={classNames(styles.tag, feature, size, {
+      is_hoverable,
+      is_editing,
+      input: has_input,
+      clickable: onClick,
+    })}
+    onClick={onClick}
+  >
+    <div className={styles.hole} />
+    <div className={styles.title}>{title}</div>
+    {children}
+  </div>
+);
+
+export { TagWrapper };
diff --git a/src/components/node/Tag/styles.scss b/src/components/tags/TagWrapper/styles.module.scss
similarity index 97%
rename from src/components/node/Tag/styles.scss
rename to src/components/tags/TagWrapper/styles.module.scss
index 1fb4d6df..87e71e1b 100644
--- a/src/components/node/Tag/styles.scss
+++ b/src/components/tags/TagWrapper/styles.module.scss
@@ -14,8 +14,9 @@ $big: 1.2;
   font: $font_14_semibold;
   align-self: flex-start;
   padding: 0 8px 0 0;
-  margin: 0 $gap $gap 0;
+  //margin: 0 $gap $gap 0;
   position: relative;
+  z-index: 4;
 
   &:global(.big) {
     height: $tag_height * $big;
@@ -88,6 +89,7 @@ $big: 1.2;
     top: 0;
     bottom: 0;
     width: 100%;
+    min-width: 100px;
     padding-left: $tag_height;
     padding-right: 5px;
     box-sizing: border-box;
@@ -118,3 +120,4 @@ $big: 1.2;
   overflow: hidden;
   text-overflow: ellipsis;
 }
+
diff --git a/src/components/tags/Tags/index.tsx b/src/components/tags/Tags/index.tsx
new file mode 100644
index 00000000..2cf064fb
--- /dev/null
+++ b/src/components/tags/Tags/index.tsx
@@ -0,0 +1,90 @@
+import React, { FC, HTMLAttributes, useCallback, useEffect, useMemo, useState, } from 'react';
+import { TagField } from '~/components/containers/TagField';
+import { ITag } from '~/redux/types';
+import uniq from 'ramda/es/uniq';
+import { Tag } from '~/components/tags/Tag';
+import { TagInput } from '~/components/tags/TagInput';
+
+type IProps = HTMLAttributes<HTMLDivElement> & {
+  tags: Partial<ITag>[];
+  is_editable?: boolean;
+  onTagsChange?: (tags: string[]) => void;
+  onTagClick?: (tag: Partial<ITag>) => void;
+};
+
+export const Tags: FC<IProps> = ({ tags, is_editable, onTagsChange, onTagClick, ...props }) => {
+  const [data, setData] = useState<string[]>([]);
+
+  const [catTags, ordinaryTags] = useMemo(
+    () =>
+      (tags || []).reduce(
+        (obj, tag) =>
+          tag.title.substr(0, 1) === '/' ? [[...obj[0], tag], obj[1]] : [obj[0], [...obj[1], tag]],
+        [[], []]
+      ),
+    [tags]
+  );
+
+  const onSubmit = useCallback(
+    (last: string[]) => {
+      const exist = tags.map(tag => tag.title);
+      onTagsChange(uniq([...exist, ...data, ...last]));
+    },
+    [data]
+  );
+
+  //
+  // const onSubmit = useCallback(() => {
+  //   const title = input && input.trim();
+  //   const items = (title ? [...data, { title }] : data)
+  //     .filter(tag => tag.title.length > 0)
+  //     .map(tag => ({
+  //       ...tag,
+  //       title: tag.title.toLowerCase(),
+  //     }));
+  //
+  //   if (!items.length) return;
+  //
+  //   setData(items);
+  //   setInput('');
+  //   onTagsChange(uniq([...tags, ...items]).map(tag => tag.title));
+  // }, [tags, data, onTagsChange, input, setInput]);
+
+  useEffect(() => {
+    setData(data.filter(title => !tags.some(tag => tag.title.trim() === title.trim())));
+  }, [tags]);
+
+  const onAppendTag = useCallback(
+    (created: string[]) => {
+      setData(uniq([...data, ...created]).filter(title => !tags.some(it => it.title === title)));
+    },
+    [data, setData, tags]
+  );
+
+  const onClearTag = useCallback((): string | undefined => {
+    if (!data.length) return;
+    const last = data[data.length - 1];
+    setData(data.slice(0, data.length - 1));
+    return last;
+  }, [data, setData]);
+
+  return (
+    <TagField {...props}>
+      {catTags.map(tag => (
+        <Tag key={tag.title} tag={tag} onClick={onTagClick} />
+      ))}
+
+      {ordinaryTags.map(tag => (
+        <Tag key={tag.title} tag={tag} onClick={onTagClick} />
+      ))}
+
+      {data.map(title => (
+        <Tag key={title} tag={{ title }} is_editing />
+      ))}
+
+      {is_editable && (
+        <TagInput onAppend={onAppendTag} onClearTag={onClearTag} onSubmit={onSubmit} />
+      )}
+    </TagField>
+  );
+};
diff --git a/src/containers/sidebars/TagSidebar/index.tsx b/src/containers/sidebars/TagSidebar/index.tsx
index bcef7151..edeca2d0 100644
--- a/src/containers/sidebars/TagSidebar/index.tsx
+++ b/src/containers/sidebars/TagSidebar/index.tsx
@@ -2,7 +2,6 @@ import React, { FC, useCallback, useEffect, useMemo } from 'react';
 import { SidebarWrapper } from '~/containers/sidebars/SidebarWrapper';
 import styles from './styles.module.scss';
 import { useHistory, useRouteMatch } from 'react-router';
-import { Tag } from '~/components/node/Tag';
 import { Icon } from '~/components/input/Icon';
 import { Link } from 'react-router-dom';
 import { TagSidebarList } from '~/components/sidebar/TagSidebarList';
@@ -11,6 +10,7 @@ import { selectTagNodes } from '~/redux/tag/selectors';
 import * as ACTIONS from '~/redux/tag/actions';
 import { LoaderCircle } from '~/components/input/LoaderCircle';
 import { InfiniteScroll } from '~/components/containers/InfiniteScroll';
+import { Tag } from '~/components/tags/Tag';
 
 const mapStateToProps = state => ({
   nodes: selectTagNodes(state),
diff --git a/webpack.config.js b/webpack.config.js
index 6cb6b064..f6bc4dd1 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -176,6 +176,7 @@ module.exports = () => {
       contentBase: 'dist',
       publicPath: '/',
       hot: true,
+      open: false,
     },
   };
 };