
클립보드 복사 붙여넣기의 숨겨진 동작 원리
클립보드에 데이터를 복사할 때 실제로 어떤 일이 일어나는지, 그리고 환경에 따라 붙여넣기 동작이 달라지는 이유를 살펴봅니다.
시작하며
"왜 Excel에서 복사한 표가 카톡에는 이미지로 붙여넣어질까?"
"Notion에서 복사한 내용이 메모장에서는 왜 이상하게 보일까?"
우리는 매일 수십 번씩 Ctrl+C, Ctrl+V를 누르지만, 정작 클립보드가 어떻게 동작하는지는 잘 모릅니다. 웹 서비스를 운영하면서 받는 버그 리포트 중 상당수가 바로 이 복사-붙여넣기와 관련된 문제들입니다.
이번 글에서는 클립보드의 내부 동작 원리를 파헤쳐보며, 왜 같은 데이터도 환경마다 다르게 보이는지 알아보겠습니다.
복사할 때 클립보드에는 무엇이 저장될까?
클립보드에 저장된 실제 데이터를 확인할 수 있는 clipboard-viewer.mech2cs.com 애플리케이션을 활용해, 몇 가지 사례를 통해 클립보드 안에 어떤 데이터가 들어가는지 살펴보겠습니다.
Google Sheets에서 복사하기
먼저 Google Sheets에서 테스트 데이터를 작성한 뒤 복사해 보겠습니다.
clipboard-viewer에서 확인한 결과, 클립보드에는 다음과 같은 데이터가 저장되었습니다.
test file
1 2 3
4 5 6
7 8 9
<meta charset='utf-8'><google-sheets-html-origin><style type="text/css"><!--td {border: 1px solid #cccccc;}br {mso-data-placement:same-cell;}--></style><table xmlns="http://www.w3.org/1999/xhtml" cellspacing="0" cellpadding="0" dir="ltr" border="1" style="table-layout:fixed;font-size:10pt;font-family:Arial;width:0px;border-collapse:collapse;border:none" data-sheets-root="1" data-sheets-baot="1"><colgroup><col width="100"/><col width="100"/><col width="100"/></colgroup><tbody><tr style="height:21px;"><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;">test file</td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;"></td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;"></td></tr><tr style="height:21px;"><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;text-align:right;">1</td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;text-align:right;">2</td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;text-align:right;">3</td></tr><tr style="height:21px;"><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;text-align:right;">4</td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;text-align:right;">5</td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;text-align:right;">6</td></tr><tr style="height:21px;"><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;text-align:right;">7</td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;text-align:right;">8</td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;text-align:right;">9</td></tr></tbody></table>
{"dih":3245853022,"data":"{\"cid\":\"[[[\\\"0\\\",0,4,1,4]]]\",\"grh\":\"<google-sheets-html-origin><style type=\\\"text/css\\\"><!--td {border: 1px solid #cccccc;}br {mso-data-placement:same-cell;}--></style><table xmlns=\\\"http://www.w3.org/1999/xhtml\\\" cellspacing=\\\"0\\\" cellpadding=\\\"0\\\" dir=\\\"ltr\\\" border=\\\"1\\\" style=\\\"table-layout:fixed;font-size:10pt;font-family:Arial;width:0px;border-collapse:collapse;border:none\\\" data-sheets-root=\\\"1\\\" data-sheets-baot=\\\"1\\\"><colgroup><col width=\\\"100\\\"/><col width=\\\"100\\\"/><col width=\\\"100\\\"/></colgroup><tbody><tr style=\\\"height:21px;\\\"><td style=\\\"overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;\\\">test file</td><td style=\\\"overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;\\\"></td><td style=\\\"overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;\\\"></td></tr><tr style=\\\"height:21px;\\\"><td style=\\\"overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;text-align:right;\\\">1</td><td style=\\\"overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;text-align:right;\\\">2</td><td style=\\\"overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;text-align:right;\\\">3</td></tr><tr style=\\\"height:21px;\\\"><td style=\\\"overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;text-align:right;\\\">4</td><td style=\\\"overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;text-align:right;\\\">5</td><td style=\\\"overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;text-align:right;\\\">6</td></tr><tr style=\\\"height:21px;\\\"><td style=\\\"overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;text-align:right;\\\">7</td><td style=\\\"overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;text-align:right;\\\">8</td><td style=\\\"overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;text-align:right;\\\">9</td></tr></tbody></table>\",\"csm\":\"[null,null,[[[[\\\"8g2fIHK762aRwPnFCZsB8w==\\\",\\\"WpaOJp8Uw53CuF/653QBqQ==\\\"],[\\\"1B2M2Y8AsgTpgAmY7PhCfg==\\\",\\\"WpaOJp8Uw53CuF/653QBqQ==\\\"],[\\\"1B2M2Y8AsgTpgAmY7PhCfg==\\\",\\\"WpaOJp8Uw53CuF/653QBqQ==\\\"]]],[[[\\\"xMpCOKC5I4INzFCab3WEmw==\\\",\\\"MUF1zl7JQ1TDh0NlRJZV6Q==\\\"],[\\\"yB5yjZ1ML2NvBn+JzBSGLA==\\\",\\\"MUF1zl7JQ1TDh0NlRJZV6Q==\\\"],[\\\"7MvIfktc4v4oMI/Z8qe68w==\\\",\\\"MUF1zl7JQ1TDh0NlRJZV6Q==\\\"]]],[[[\\\"qH/2eaLz5x2RgaZ7dUISLA==\\\",\\\"MUF1zl7JQ1TDh0NlRJZV6Q==\\\"],[\\\"5No7f7vOI0XXdysGdKMY1Q==\\\",\\\"MUF1zl7JQ1TDh0NlRJZV6Q==\\\"],[\\\"FnkJHFqID69vteYIfrGy3A==\\\",\\\"MUF1zl7JQ1TDh0NlRJZV6Q==\\\"]]],[[[\\\"jxTkX87qFnpaNt7dS+olQw==\\\",\\\"MUF1zl7JQ1TDh0NlRJZV6Q==\\\"],[\\\"yfD4lfuYq5FZ9R/QKX4jbQ==\\\",\\\"MUF1zl7JQ1TDh0NlRJZV6Q==\\\"],[\\\"RcSMzi4tf73qGvxRx8atJg==\\\",\\\"MUF1zl7JQ1TDh0NlRJZV6Q==\\\"]]]]]\"}","edi":"J5o5V_qVpiKQ7bGPBU9UtLbBVsepNCDjRtnfNglTq_3Tuh1AOWleDbFvw3NXYFhENl0-IzjAd03JcLzGfJByfM7Z_DxJX3FtpMQBvahEzUe0","edrk":"Bs13ykXIHdBRaOWXSqhlGTbpG6r0pX0L5UDTB-7poLIY4UQrsA..","dct":"ritz","ds":false,"cses":false,"sm":"other"}
fcee7517-7fff-b8e9-9712-715f8a6fc6f7
{"1":1,"2":[195,-2,194,-9,195],"3":{"1":[2,1,1,1,1,1,1,1,1,1],"3":[1,2,3,4,5,6,7,8,9],"4":["test file"]},"4":[{"2":4224,"10":2,"15":"Arial"},{"2":4288,"9":2,"10":2,"15":"Arial"}],"5":[-3,0,-9,1],"12":[-12,1],"13":[-12,1],"15":{"1":4,"2":3},"20":12}
Notion에서 복사하기
Notion에서도 동일하게 테스트 데이터를 작성한 후 복사해 보겠습니다.
clipboard-viewer에서 확인한 결과, 클립보드에는 다음과 같은 데이터가 담겨 있었습니다.
1. test1
2. test2
3. test3
| 1 | 2 | 3 |
| --- | --- | --- |
| 4 | 5 | 6 |
| 7 | 8 | 9 |
<meta charset='utf-8'><ol>
<li>test1</li>
<li>test2</li>
<li>test3</li>
</ol>
<table>
<thead>
<tr>
<th>1</th>
<th>2</th>
<th>3</th>
</tr>
</thead>
<tbody>
<tr>
<td>4</td>
<td>5</td>
<td>6</td>
</tr>
<tr>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
</tbody>
</table>
<!-- notionvc: 6c59c13b-270a-4039-b742-c7405b47146b -->
{"blocks":[{"blockId":"1808cecc-4a07-8056-9533-fd6a6dd16795","blockSubtree":{"__version__":3,"block":{"1808cecc-4a07-8056-9533-fd6a6dd16795":{"value":{"id":"1808cecc-4a07-8056-9533-fd6a6dd16795","space_id":"fedc6588-957b-44d6-82a9-4cb2f4e91dbf","version":107,"type":"numbered_list","properties":{"title":[["test1"]]},"created_time":1737292584836,"last_edited_time":1756366729070,"parent_id":"1808cecc-4a07-8047-b5ea-c67ff7f3a9a4","parent_table":"block","alive":true,"created_by_table":"notion_user","created_by_id":"4d8010d8-8b21-4686-b2c6-de011d53afd4","last_edited_by_table":"notion_user","last_edited_by_id":"4d8010d8-8b21-4686-b2c6-de011d53afd4"}}}}},{"blockId":"1808cecc-4a07-80ea-a631-e708c4c8881d","blockSubtree":{"__version__":3,"block":{"1808cecc-4a07-80ea-a631-e708c4c8881d":{"value":{"id":"1808cecc-4a07-80ea-a631-e708c4c8881d","space_id":"fedc6588-957b-44d6-82a9-4cb2f4e91dbf","version":96,"type":"numbered_list","properties":{"title":[["test2"]]},"created_time":1737292601583,"last_edited_time":1756366730359,"parent_id":"1808cecc-4a07-8047-b5ea-c67ff7f3a9a4","parent_table":"block","alive":true,"created_by_table":"notion_user","created_by_id":"4d8010d8-8b21-4686-b2c6-de011d53afd4","last_edited_by_table":"notion_user","last_edited_by_id":"4d8010d8-8b21-4686-b2c6-de011d53afd4"}}}}},{"blockId":"1808cecc-4a07-807d-9b20-cf89a1d5ed05","blockSubtree":{"__version__":3,"block":{"1808cecc-4a07-807d-9b20-cf89a1d5ed05":{"value":{"id":"1808cecc-4a07-807d-9b20-cf89a1d5ed05","space_id":"fedc6588-957b-44d6-82a9-4cb2f4e91dbf","version":15,"type":"numbered_list","created_time":1737292604965,"last_edited_time":1756366731565,"parent_id":"1808cecc-4a07-8047-b5ea-c67ff7f3a9a4","parent_table":"block","alive":true,"created_by_table":"notion_user","created_by_id":"4d8010d8-8b21-4686-b2c6-de011d53afd4","last_edited_by_table":"notion_user","last_edited_by_id":"4d8010d8-8b21-4686-b2c6-de011d53afd4","properties":{"title":[["test3"]]}}}}}},{"blockId":"18b8cecc-4a07-80f1-8e17-d5f342715313","blockSubtree":{"__version__":3,"block":{"18b8cecc-4a07-80f1-8e17-d5f342715313":{"value":{"id":"18b8cecc-4a07-80f1-8e17-d5f342715313","space_id":"fedc6588-957b-44d6-82a9-4cb2f4e91dbf","version":5,"type":"text","created_time":1738253104198,"last_edited_time":1738253104205,"parent_id":"1808cecc-4a07-8047-b5ea-c67ff7f3a9a4","parent_table":"block","alive":true,"created_by_table":"notion_user","created_by_id":"4d8010d8-8b21-4686-b2c6-de011d53afd4","last_edited_by_table":"notion_user","last_edited_by_id":"4d8010d8-8b21-4686-b2c6-de011d53afd4"}}}}},{"blockId":"25d8cecc-4a07-8098-a5c0-fc61ec8fdb6f","blockSubtree":{"__version__":3,"block":{"25d8cecc-4a07-8098-a5c0-fc61ec8fdb6f":{"value":{"id":"25d8cecc-4a07-8098-a5c0-fc61ec8fdb6f","type":"table","content":["25d8cecc-4a07-8037-96c0-ecfb1bad1de4","25d8cecc-4a07-80f0-b31a-dff274df7832","25d8cecc-4a07-80f3-a4e2-ffc4fb53c21d"],"format":{"table_block_column_order":["bVXk","KQZF","y_At"],"table_block_column_format":{"bVXk":{"width":236.33333333333334},"KQZF":{"width":236.33333333333334},"y_At":{"width":236.33333333333334}}},"space_id":"fedc6588-957b-44d6-82a9-4cb2f4e91dbf","created_time":1756366740506,"last_edited_time":1756366740513,"last_edited_by_id":"4d8010d8-8b21-4686-b2c6-de011d53afd4","last_edited_by_table":"notion_user","created_by_id":"4d8010d8-8b21-4686-b2c6-de011d53afd4","created_by_table":"notion_user","version":4,"parent_id":"1808cecc-4a07-8047-b5ea-c67ff7f3a9a4","parent_table":"block","alive":true}},"25d8cecc-4a07-8037-96c0-ecfb1bad1de4":{"value":{"id":"25d8cecc-4a07-8037-96c0-ecfb1bad1de4","type":"table_row","parent_id":"25d8cecc-4a07-8098-a5c0-fc61ec8fdb6f","parent_table":"block","alive":true,"space_id":"fedc6588-957b-44d6-82a9-4cb2f4e91dbf","created_time":1756366740506,"last_edited_time":1756366743711,"last_edited_by_id":"4d8010d8-8b21-4686-b2c6-de011d53afd4","last_edited_by_table":"notion_user","created_by_id":"4d8010d8-8b21-4686-b2c6-de011d53afd4","created_by_table":"notion_user","version":8,"properties":{"bVXk":[["1"]],"KQZF":[["2"]],"y_At":[["3"]]}}},"25d8cecc-4a07-80f0-b31a-dff274df7832":{"value":{"id":"25d8cecc-4a07-80f0-b31a-dff274df7832","type":"table_row","parent_id":"25d8cecc-4a07-8098-a5c0-fc61ec8fdb6f","parent_table":"block","alive":true,"space_id":"fedc6588-957b-44d6-82a9-4cb2f4e91dbf","created_time":1756366740506,"last_edited_time":1756366744910,"last_edited_by_id":"4d8010d8-8b21-4686-b2c6-de011d53afd4","last_edited_by_table":"notion_user","created_by_id":"4d8010d8-8b21-4686-b2c6-de011d53afd4","created_by_table":"notion_user","version":8,"properties":{"bVXk":[["4"]],"KQZF":[["5"]],"y_At":[["6"]]}}},"25d8cecc-4a07-80f3-a4e2-ffc4fb53c21d":{"value":{"id":"25d8cecc-4a07-80f3-a4e2-ffc4fb53c21d","type":"table_row","parent_id":"25d8cecc-4a07-8098-a5c0-fc61ec8fdb6f","parent_table":"block","alive":true,"space_id":"fedc6588-957b-44d6-82a9-4cb2f4e91dbf","created_time":1756366740506,"last_edited_time":1756366745943,"last_edited_by_id":"4d8010d8-8b21-4686-b2c6-de011d53afd4","last_edited_by_table":"notion_user","created_by_id":"4d8010d8-8b21-4686-b2c6-de011d53afd4","created_by_table":"notion_user","version":8,"properties":{"bVXk":[["7"]],"KQZF":[["8"]],"y_At":[["9"]]}}}}}},{"blockId":"24a8cecc-4a07-8069-bafe-c784985a74a2","blockSubtree":{"__version__":3,"block":{"24a8cecc-4a07-8069-bafe-c784985a74a2":{"value":{"id":"24a8cecc-4a07-8069-bafe-c784985a74a2","space_id":"fedc6588-957b-44d6-82a9-4cb2f4e91dbf","version":3,"type":"text","created_time":1754731509042,"last_edited_time":1754731509044,"parent_id":"1808cecc-4a07-8047-b5ea-c67ff7f3a9a4","parent_table":"block","alive":true,"created_by_table":"notion_user","created_by_id":"4d8010d8-8b21-4686-b2c6-de011d53afd4","last_edited_by_table":"notion_user","last_edited_by_id":"4d8010d8-8b21-4686-b2c6-de011d53afd4"}}}}}],"action":"copy","wasContiguousSelection":true}
{"id":"1808cecc-4a07-8047-b5ea-c67ff7f3a9a4","table":"block","spaceId":"fedc6588-957b-44d6-82a9-4cb2f4e91dbf"}
왜 여러 형식으로 저장할까?
사례를 분석해 보면, 웹 서비스들은 복사 시 한 가지 형식이 아니라 여러 가지 데이터 형식을 동시에 클립보드에 저장한다는 것을 알 수 있습니다.
이유는 크게 두 가지입니다.
1. 구조화된 데이터의 완벽한 복원
복잡한 구조(표, 스타일, 블록, 서식 등)를 단일 형식으로 표현하기는 어렵습니다.
예를 들어 Excel의 셀 서식이나 Notion의 블록 구조는 단순 텍스트로는 담아낼 수 없죠.
따라서 각 서비스는 자체 메타데이터 형식을 함께 저장해 둡니다.
이 덕분에 같은 서비스 내부에서 붙여넣을 때는 원본 구조를 거의 완벽하게 복원할 수 있습니다.
2. 다양한 환경에 대한 호환성
모든 애플리케이션이 모든 데이터 형식을 지원하는 것은 아닙니다.
그래서 여러 형식을 동시에 저장해 두고, 붙여넣는 쪽 애플리케이션이 지원 가능한 형식을 선택하게 합니다.
예를 들어 Excel이 데이터를 복사할 때 이미지 형식을 함께 넣는 이유는:
- PowerPoint나 Word에서는 표를 이미지로 삽입하는 것이 레이아웃상 유리할 수 있고
- 이미지 편집 도구에서는 텍스트보다 이미지가 필요하며
- 일부 메신저나 SNS는 표 형식을 지원하지 않기 때문입니다
붙여넣기 동작이 달라지는 이유
같은 내용을 복사해도 어디에 붙여넣느냐에 따라 결과가 달라지는 이유는, 각 애플리케이션이 클립보드 데이터 형식을 선택하는 방식이 다르기 때문입니다.
일부 애플리케이션은 명시적으로 우선순위를 정의하여, 예를 들어 HTML 에디터라면 text/html
을 우선적으로 가져오고, 일반 텍스트 에디터라면 text/plain
을 우선하는 식으로 동작합니다.
document.addEventListener('paste', (event) => {
const clipboardData = event.clipboardData;
// 애플리케이션별 우선순위 설정
if (clipboardData.types.includes('text/html')) {
// HTML 에디터는 HTML 형식 우선
const html = clipboardData.getData('text/html');
processHTML(html);
} else if (clipboardData.types.includes('text/plain')) {
// 일반 텍스트 에디터는 plain text 사용
const text = clipboardData.getData('text/plain');
processText(text);
}
});
반면, 어떤 애플리케이션은 이런 우선순위를 따로 두지 않고 클립보드에 저장된 데이터의 순서대로 단순 추출하기도 합니다.
이런 경우에는 사용자의 기대와 다른 결과가 나올 수 있습니다. 예를 들어 텍스트를 붙여넣고 싶었는데 이미지가 먼저 선택되거나, 풍부한 메타데이터 대신 단순 텍스트만 붙여넣어지는 상황이 발생할 수 있습니다.
마무리
클립보드는 단순해 보이지만 실제로는 복잡한 다중 포맷 시스템입니다. 이번 글에서는 복사-붙여넣기의 기본적인 동작 원리를 살펴보며, 왜 같은 데이터도 애플리케이션마다 다르게 표시되는지 알아봤습니다. 우리가 무심코 사용하는 Ctrl+C, Ctrl+V 뒤에는 여러 데이터 형식이 동시에 저장되고, 각 애플리케이션이 자신에게 맞는 형식을 선택하는 복잡한 과정이 숨어있었습니다. Google Sheets와 Notion의 예시를 통해 각 서비스가 자체 메타데이터를 포함해 다양한 형식으로 데이터를 준비한다는 것도 확인할 수 있었습니다.
복사·붙여넣기 기능에서도 어떤 데이터 포맷을 우선적으로 활용할지 고민하는 것은 더 나은 사용자 경험을 만드는 데 중요한 요소가 됩니다.
clipboard-viewer.mech2cs.com에서 직접 클립보드 데이터를 탐색해보면서, 여러분이 사용하는 애플리케이션들이 어떻게 클립보드를 활용하는지 확인해보시길 바랍니다.