HTML과 CSS JS만을 이용해 노트 원고지를 만들어 보겠습니다.
1.노트 만들기
HTML 코드
<div class="note">
<p>
이별은 공평하지 않다.
한 사람이 가볍게 생각한 마음을 다른 사람은 선물처럼 끌어 안고 있다.
어떻게든 추억이라는 말로 포장하려고 해도,
세상에서 단 하나밖에 없던 이야기는
또 하나의 흔해 빠진 사랑얘기가 될 뿐이다.
</p>
<p>
목매달고 애원했던 것들도 세월이 지나면
뭐 그리 대단한 것도 아니다
끊어지고 이어지고 끊어지는 것이 인연인가보다
</p>
<img src="https://mblogthumb-phinf.pstatic.net/20130619_298/rlawjdgus190_1371596605469CG8GY_JPEG/daum_net_20130219_100328.jpg?type=w2" alt="roster" />
<p>
그 누구도 살아서는 이 세상을 빠져 나갈 수 없다.
따라서 바로 지금 이 순간이
우리가 살고, 보살피고, 나누고, 축하하고
그리고 사랑해야 할 시간이다.
</p>
<p>
기회는 신선한 음식같은거야.
냉장고에 넣어두면 맛이 떨어져.
젊은이에게 제일 나쁜건 아예 판단을 내리지 않는거야.
</p>
<p>
우리가 보낸 하루하루를 모두 더하였을 때
그것이 형체 없는 안개로 사라지느냐,
아니면 예술 작품에 버금가는 모습으로 형상화되느냐는
바로 우리가 어떤 일을 선택하고 그 일을
어떤 방식으로 하는가에 달려 있다.
</p>
</div>
note 클래스를 생성후 아래에 텍스트와 이미지를 추가했습니다.
이외 다양한 요소를 넣을 수 있으나 원고의 CSS 높이와 너비에 따라 잘 고려하셔야 합니다.
CSS 코드
* {
margin: 0;
padding: 0;
}
:root {
--bg-color:#fff;
--bg-transparent: rgba(255,255,255,0);
--border-color: #2035a7;
}
.note {
font-size: 16px;
line-height: 32px;
border: 2px solid var(--border-color);
background: -webkit-linear-gradient(
top,
var(--border-color) 0%,
var(--border-color) 1px,
var(--bg-transparent) 1px,
var(--bg-transparent) 100%
);
background: linear-gradient(
to bottom,
var(--border-color) 0%,
var(--border-color) 1px,
var(--bg-transparent) 1px,
var(--bg-transparent) 100%
);
background-size: 100% 32px;
}
.note > p {
margin: 0;
padding: 0 4px;
}
.note > img {
display: block;
width: auto;
max-width: 100%;
margin: 25px auto;
object-fit: cover;
}
CSS는 간단하게 구현해볼 수 있습니다.
1px 짜리 그라디언트를 만들고 32px마다 반복되게 만들어 주었습니다.
아래 들어갈 요소로 높이만 전부 신경 써주면 노트에 글을 쓰는 느낌으로 글을 쓸 수 있습니다.
JS 코드
function resizeNotebook() {
const note = document.querySelectorAll('.note');
const resize = () => note.forEach(resizeImage);
resize();
window.addEventListener('load', resize, { passive: true });
window.addEventListener('resize', resize, { passive: true });
}
function resizeImage(element) {
element.querySelectorAll('img').forEach(img => {
const { natualWidth, natualHeight } = img;
const ratio = natualHeight / natualWidth;
const newHeight = element.offsetWidth * ratio;
img.height = Math.floor(newHeight - (newHeight % 32));
});
}
이미지와 같이 일정한 비를 유지하면 작야저야 하는 요소를 위한 예제입니다.
CSS에서 줄 간격을 변경하면 newHeight % 32의 32도 그 값으로 변경해주어야 합니다.
:root {
--bg-color: #fff;
--bg-transparent: rgba(255, 255, 255, 0);
--border-color: #2035a7;
}
.note {
font-size: 16px;
line-height: 32px;
border: 2px solid var(--border-color);
background: -webkit-linear-gradient(
top,
var(--border-color) 0%,
var(--border-color) 1px,
var(--bg-transparent) 1px,
var(--bg-transparent) 100%
);
background: linear-gradient(
to bottom,
var(--border-color) 0%,
var(--border-color) 1px,
var(--bg-transparent) 1px,
var(--bg-transparent) 100%
);
background-size: 100% 32px;
}
.note > p {
margin: 0;
padding: 0 4px;
}
.note > img {
display: block;
width: auto;
max-width: 100%;
margin: 0 auto;
object-fit: cover;
}
.note > *:not(:last-child) {
margin-bottom: 32px;
}
/* Align */
body {
display:flex;
margin: 0;
padding: 10px;
justify-content: center;
align-items: center;
}
.note {
max-width: 860px;
}
2.원고지
HTML 코드
<div class="note-container">
<div class="menuscript">
<p>
이별은 공평하지 않다.
한 사람이 가볍게 생각한 마음을 다른 사람은 선물처럼 끌어 안고 있다.
어떻게든 추억이라는 말로 포장하려고 해도,
세상에서 단 하나밖에 없던 이야기는
또 하나의 흔해 빠진 사랑얘기가 될 뿐이다.
</p>
<p>
점순네 수탉(은 대강이가 크고 똑 오소리같이 실팍하게 생긴 놈)이 덩저리
작은 우리 수탉을 함부로 해내는 것이다. 그것도 그냥 해내는 것이 아니라
푸드득 하고 면두를 쪼고 물러섰다가 좀 사이를 두고 또 푸드득 하고
모가지를 쪼았다. 이렇게 멋을 부려 가며 여지없이닦아 놓는다. 그러면 이
못생긴 것은 쪼일 적마다 주둥이로 땅을 받으며 그 비명이 킥, 킥할 뿐이다.
물론 미처 아물지도 않은 면두를 또 쪼이어 붉은 선혈은 뚝뚝 떨어진다.
</p>
<img src="https://mblogthumb-phinf.pstatic.net/20130619_298/rlawjdgus190_1371596605469CG8GY_JPEG/daum_net_20130219_100328.jpg?type=w2" alt="roster" />
<p>
그 누구도 살아서는 이 세상을 빠져 나갈 수 없다.
따라서 바로 지금 이 순간이
우리가 살고, 보살피고, 나누고, 축하하고
그리고 사랑해야 할 시간이다.
</p>
<p>
기회는 신선한 음식같은거야.
냉장고에 넣어두면 맛이 떨어져.
젊은이에게 제일 나쁜건 아예 판단을 내리지 않는거야.
</p>
<p>
우리가 보낸 하루하루를 모두 더하였을 때
그것이 형체 없는 안개로 사라지느냐,
아니면 예술 작품에 버금가는 모습으로 형상화되느냐는
바로 우리가 어떤 일을 선택하고 그 일을
어떤 방식으로 하는가에 달려 있다.
</p>
</div>
.note와 마찬가지로 줄 공책과는 달리 한 칸의 크기가 정해져 있고 .manuscript의 크기도 유동저그로 변경되어야
하기 떄문에 .manuscript를 감싸주는 .manuscript-container가 하나 추가됩니다.
CSS 코드
:root {
--bg-color: #fff;
--bg-transparent: rgba(255, 255, 255, 0);
--border-color: #2035a7;
}
.note-container {
margin : 0 auto;
}
.menuscript {
font-size: 16px;
line-height: 32px;
border: 2px solid var(--border-color);
background: -webkit-linear-gradient(
top,
var(--border-color) 0%,
var(--border-color) 1px,
var(--bg-transparent) 1px,
var(--bg-transparent) 100%
);
-webkit-linear-gradient(
top,
var(--bg-transparent) 0%,
var(--bg-transparent) 1px,
var(--bg-color) 1px,
var(--bg-color) 8px,
var(--bg-transparent) 8px,
var(--bg-transparent) 100%
),
-webkit-linear-gradient(
left,
var(--border-color) 0%,
var(--border-color) 1px,
var(--bg-transparent) 1px,
var(--bg-transparent) 100%
),
-webkit-linear-gradient(
top,
var(--border-color) 0%,
var(--border-color) 1px,
var(--bg-transparent) 1px,
var(--bg-transparent) 100%
),
-webkit-linear-gradient(
top,
var(--border-color) 0%,
var(--border-color) 1px,
var(--bg-transparent) 1px,
var(--bg-transparent) 100%
),
var(--bg-color);
background: linear-gradient(
to bottom,
var(--bg-transparent) 0%,
var(--bg-transparent) 1px,
var(--bg-color) 1px,
var(--bg-color) 8px,
var(--bg-transparent) 8px,
var(--bg-transparent) 100%
),
linear-gradient(
to bottom,
var(--bg-transparent) 0%,
var(--bg-transparent) 1px,
var(--bg-color) 1px,
var(--bg-color) 8px,
var(--bg-transparent) 8px,
var(--bg-transparent) 100%
),
linear-gradient(
to right,
var(--border-color) 0%,
var(--border-color) 1px,
var(--bg-transparent) 1px,
var(--bg-transparent) 100%
),
linear-gradient(
to bottom,
var(--border-color) 0%,
var(--border-color) 1px,
var(--bg-transparent) 1px,
var(--bg-transparent) 100%
),
linear-gradient(
to bottom,
var(--border-color) 0%,
var(--border-color) 1px,
var(--bg-transparent) 1px,
var(--bg-transparent) 100%
),
var(--bg-color);
background-size: 24px 32px;
margin: 0 auto;
background-position: 0 -1px, 0 0, -1px 0, 0 8px, 0px -1px;
}
.menuscript > p {
display:flex;
flex-wrap: wrap;
margin: -8px -1px 8px 0;
font-size: 16px;
line-height: 24px;;
}
.menuscript > p > span {
display:inline-block;
text-align: center;
width: 24px;
height: 24px;
flex-shrink: 0;
margin-top: 8px;
}
.menuscript > :empty:not(img) {
height: 32px;
margin-bottom: 8px;
}
.menuscript > :last-child {
margin-bottom: 0;
}
.menuscript > img {
display: block;
width: auto;
max-width: 100%;
margin: 0 auto;
object-fit: cover;
}
.menuscript > *:not(:last-child) {
margin-bottom: 40px;
}
.note-container {
max-width: 860px;
}
원고 한 칸의 크기를 24px * 24px, 줄 간격을 8px로 잡고 만드니, 수정 시 참고 바랍니다.
JS 코드
function initManuscript() {
const manuscript = document.querySelectorAll('.manuscript');
const handleResize = () => {
manuscript.forEach(elt => {
resizeMnuascriptContainer(elt);
resizeImage(elt);
});
};
window.addEventListener('load', handleResize, { passive: true });
window.addEventListener('resize', handleResize, { passive: true });
manuscript.forEach(element => {
element.querySelectorAll('p').forEach(element => {
const text = element.innerText;
element.innerHTML = '';
[...text].forEach(word => {
const span = document.createElement('span');
const textNode = document.createTextNode(word);
span.appendChild(textNode);
element.append(span);
});
});
});
handleResize();
}
function resizeMnuascriptContainer(element) {
element.style.width = `${(Math.floor(element.parentElement.offsetWidth / 24) - 1) * 24 - 1}px`;
}
function resizeImage(element) {
element.querySelectorAll('img').forEach(img => {
const { naturalWidth, naturalHeight } = img;
const ratio = naturalHeight / naturalWidth;
const newHeight = element.offsetWidth * ratio;
img.height = Math.floor(newHeight - (newHeight % 32) - 8);
});
}
initManuscript();
노트와 마찬가지로 이미지의 크기를 유동적으로 변경해주는 스크립트에 최초 글자 하나하나를 뜯어 span코드에 넣어주는 스크립트와 원고지 크기를 유동적으로 변경해주는 스크립트가 추가 되었습니다.
원고 칸의 크기를 수정하면 resizeManuscriptContainer, resizeImage가 들어있는 8의 배수(8,24,32)들을 모조리
수정해주시면 끝입니다
결과
See the Pen Untitled by JungHo Kim (@koras02-the-lessful) on CodePen.
결론
노트와 달리 한 칸에 맞춰 글자를 써야 하다 보니까 글자를 모두 span 에 담아줘야 깔끔하게 작업할 것 같습니다.
이 떄문에도 검색 엔진이 본문의 내용을 파악하기 힘들어 질 수 있으며 SEO(검색 엔진 최적화)에도 악영향을
미칠 수 있습니다.
참고 자료
'프론트 엔드 > CSS' 카테고리의 다른 글
[CSS] CSS 란 무엇인가? - CSS3의 등장 (0) | 2023.02.17 |
---|---|
[CSS] SASS와 SCSS (0) | 2022.01.30 |
[css]media query란 무엇인가? 방법론이란 ? (0) | 2022.01.10 |