노트
HTML
< div class = " note " >
< p >
오늘도 또 우리 수탉이 막 쫓기었다. 내가 점심을 먹고 나무를 하러 갈
양으로 나올 때이었다. 산으로 올라서려니까 등뒤에서 푸르득푸드득, 하고
닭의 횃소리가 야단이다. 깜짝 놀라서 고개를 돌려보니 아니나다르랴, 두
놈이 또 얼리었다.
</ p >
< p >
점순네 수탉(은 대강이가 크고 똑 오소리같이 실팍하게 생긴 놈)이 덩저리
작은 우리 수탉을 함부로 해내는 것이다. 그것도 그냥 해내는 것이 아니라
푸드득 하고 면두를 쪼고 물러섰다가 좀 사이를 두고 또 푸드득 하고
모가지를 쪼았다. 이렇게 멋을 부려 가며 여지없이닦아 놓는다. 그러면 이
못생긴 것은 쪼일 적마다 주둥이로 땅을 받으며 그 비명이 킥, 킥할 뿐이다.
물론 미처 아물지도 않은 면두를 또 쪼이어 붉은 선혈은 뚝뚝 떨어진다.
</ p >
< img src = " https://i.imgur.com/pEmnc36.jpg " alt = " roster " />
< p >
이걸 가만히 내려다보자니 내 대강이가 터져서 피가 흐르는 것같이 두 눈에서
불이 번쩍난다. 대뜸 지게 막대기를 메고 달려들어 점순네 닭을 후려칠까
하다가 생각을 고쳐먹고헛매질로 떼어만 놓았다.
</ p >
< p >
이번에도 점순이가 쌈을 붙여 놨을 것이다. 바짝바짝 내 기를 올리느라고
그랬음에 틀림없을 것이다.
</ p >
< p >
고놈의 계집애가 요새로 들어서서 왜 나를 못 먹겠다고 고렇게
아르렁거리는지 모른다.
</ p >
< p > 나흘 전 감자 조각만 하더라도 나는 저에게 조금도 잘못한 것은 없다. </ p >
</ div >
.note
를 생성하고 아래에 텍스트와 이미지를 추가했습니다.
외에도 다양한 요소를 추가하실 수 있지만, 높이나 너비를 잘 고려하셔야 합니다.
CSS
: root {
--bg-color : # fff ;
--bg-transparent : rgba ( 255 , 255 , 255 , 0 );
--border-color : # 2035a7 ;
}
. note {
font-size : 16 px ;
line-height : 32 px ;
border : 2 px solid var ( --border-color );
background : -webkit-linear-gradient (
top ,
var ( --border-color ) 0 % ,
var ( --border-color ) 1 px ,
var ( --bg-transparent ) 1 px ,
var ( --bg-transparent ) 100 %
);
background : linear-gradient (
to bottom ,
var ( --border-color ) 0 % ,
var ( --border-color ) 1 px ,
var ( --bg-transparent ) 1 px ,
var ( --bg-transparent ) 100 %
);
background-size : 100 % 32 px ;
}
. note > p {
margin : 0 ;
padding : 0 4 px ;
}
. note > img {
display : block ;
width : auto ;
max-width : 100 % ;
margin : 0 auto ;
object-fit : cover ;
}
노트 제작은 굉장히 간단한 편입니다.
1px짜리 줄 하나 긋는 그래디언트를 만든 뒤, 32px마다 반복되게 해뒀습니다.
아래에 들어갈 요소들의 높이만 전부 신경 써준다면 노트에 쓰는 느낌으로 글을 쓸 수 있습니다.
JS
function resizeImageForNote () {
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 { naturalWidth , naturalHeight } = img ;
const ratio = naturalHeight / naturalWidth ;
const newHeight = element . offsetWidth * ratio ;
img . height = Math . floor ( newHeight - ( newHeight % 32 )) ;
} ) ;
}
resizeImageForNote () ;
이미지처럼 일정 비를 유지하며 작아져야 하는 요소를 위한 예제입니다.
CSS에서 줄 간격을 변경하시면 newHeight % 32
의 32도 그 값으로 변경해주셔야 합니다.
결과
원고지
HTML
< div class = " manuscript-container " >
< div class = " manuscript " >
< p >
오늘도 또 우리 수탉이 막 쫓기었다. 내가 점심을 먹고 나무를 하러 갈
양으로 나올 때이었다. 산으로 올라서려니까 등뒤에서 푸르득푸드득,
하고 닭의 횃소리가 야단이다. 깜짝 놀라서 고개를 돌려보니
아니나다르랴, 두 놈이 또 얼리었다.
</ p >
< p >
점순네 수탉(은 대강이가 크고 똑 오소리같이 실팍하게 생긴 놈)이
덩저리 작은 우리 수탉을 함부로 해내는 것이다. 그것도 그냥 해내는
것이 아니라 푸드득 하고 면두를 쪼고 물러섰다가 좀 사이를 두고 또
푸드득 하고 모가지를 쪼았다. 이렇게 멋을 부려 가며 여지없이닦아
놓는다. 그러면 이 못생긴 것은 쪼일 적마다 주둥이로 땅을 받으며 그
비명이 킥, 킥할 뿐이다. 물론 미처 아물지도 않은 면두를 또 쪼이어
붉은 선혈은 뚝뚝 떨어진다.
</ p >
< img src = " https://i.imgur.com/pEmnc36.jpg " alt = " roster " />
< p >
이걸 가만히 내려다보자니 내 대강이가 터져서 피가 흐르는 것같이 두
눈에서 불이 번쩍난다. 대뜸 지게 막대기를 메고 달려들어 점순네 닭을
후려칠까 하다가 생각을 고쳐먹고헛매질로 떼어만 놓았다.
</ p >
< p >
이번에도 점순이가 쌈을 붙여 놨을 것이다. 바짝바짝 내 기를 올리느라고
그랬음에 틀림없을 것이다.
</ p >
< p >
고놈의 계집애가 요새로 들어서서 왜 나를 못 먹겠다고 고렇게
아르렁거리는지 모른다.
</ p >
< p > 나흘 전 감자 조각만 하더라도 나는 저에게 조금도 잘못한 것은 없다. </ p >
</ div >
</ div >
.note
와 마찬가지지만 줄 공책과 달리 원고는 한 칸의 크기가 정해져 있어 .manuscript
의 크기도 유동적으로 변경되어야 하기에, .manuscript
를 감싸주는 .manuscript-container
가 하나 추가되었습니다.
CSS
: root {
--bg-color : # fff ;
--bg-transparent : rgba ( 255 , 255 , 255 , 0 );
--border-color : # d12e2e ;
}
. manuscript-container {
margin : 0 auto ;
}
. manuscript {
font-size : 16 px ;
line-height : 32 px ;
padding : 8 px 0 ;
border : 2 px solid var ( --border-color );
background : -webkit-linear-gradient (
top ,
var ( --bg-transparent ) 0 % ,
var ( --bg-transparent ) 1 px ,
var ( --bg-color ) 1 px ,
var ( --bg-color ) 8 px ,
var ( --bg-transparent ) 8 px ,
var ( --bg-transparent ) 100 %
),
-webkit-linear-gradient (
top ,
var ( --bg-transparent ) 0 % ,
var ( --bg-transparent ) 1 px ,
var ( --bg-color ) 1 px ,
var ( --bg-color ) 8 px ,
var ( --bg-transparent ) 8 px ,
var ( --bg-transparent ) 100 %
),
-webkit-linear-gradient (
left ,
var ( --border-color ) 0 % ,
var ( --border-color ) 1 px ,
var ( --bg-transparent ) 1 px ,
var ( --bg-transparent ) 100 %
),
-webkit-linear-gradient (
top ,
var ( --border-color ) 0 % ,
var ( --border-color ) 1 px ,
var ( --bg-transparent ) 1 px ,
var ( --bg-transparent ) 100 %
),
-webkit-linear-gradient (
top ,
var ( --border-color ) 0 % ,
var ( --border-color ) 1 px ,
var ( --bg-transparent ) 1 px ,
var ( --bg-transparent ) 100 %
),
var ( --bg-color );
background : linear-gradient (
to bottom ,
var ( --bg-transparent ) 0 % ,
var ( --bg-transparent ) 1 px ,
var ( --bg-color ) 1 px ,
var ( --bg-color ) 8 px ,
var ( --bg-transparent ) 8 px ,
var ( --bg-transparent ) 100 %
),
linear-gradient (
to bottom ,
var ( --bg-transparent ) 0 % ,
var ( --bg-transparent ) 1 px ,
var ( --bg-color ) 1 px ,
var ( --bg-color ) 8 px ,
var ( --bg-transparent ) 8 px ,
var ( --bg-transparent ) 100 %
),
linear-gradient (
to right ,
var ( --border-color ) 0 % ,
var ( --border-color ) 1 px ,
var ( --bg-transparent ) 1 px ,
var ( --bg-transparent ) 100 %
),
linear-gradient (
to bottom ,
var ( --border-color ) 0 % ,
var ( --border-color ) 1 px ,
var ( --bg-transparent ) 1 px ,
var ( --bg-transparent ) 100 %
),
linear-gradient (
to bottom ,
var ( --border-color ) 0 % ,
var ( --border-color ) 1 px ,
var ( --bg-transparent ) 1 px ,
var ( --bg-transparent ) 100 %
),
var ( --bg-color );
background-size : 24 px 32 px ;
margin : 0 auto ;
background-position : 0 -1 px , 0 0 , -1 px 0 , 0 8 px , 0 px -1 px ;
}
. manuscript > p {
display : flex ;
flex-wrap : wrap ;
margin : -8 px -1 px 8 px 0 ;
font-size : 16 px ;
line-height : 24 px ;
}
. manuscript > p > span {
display : inline-block ;
text-align : center ;
width : 24 px ;
height : 24 px ;
flex-shrink : 0 ;
margin-top : 8 px ;
}
. manuscript > : empty : not ( img ) {
height : 32 px ;
margin-bottom : 8 px ;
}
. manuscript > : last-child {
margin-bottom : 0 ;
}
. manuscript > img {
display : block ;
width : auto ;
max-width : 100 % ;
margin : 0 auto ;
object-fit : cover ;
}
. manuscript > * : not ( : last-child ) {
margin-bottom : 40 px ;
}
그래디언트도 조금 골이 아파지기 시작합니다.
원고 한 칸의 크기를 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)들을 모조리 수정해주시면 됩니다.
결과
여담
아무래도 노트와 달리 한 칸에 맞춰서 글자를 써야 하다 보니 글자를 모조리 span
에 담아야 깔끔하게 작업할 수 있었습니다.
이 때문에 검색 엔진이 본문의 내용을 파악하기 힘들어질 수 있고, SEO에 악영향을 미칠 수 있습니다.
해당 스크립트가 SEO에 미치는 영향 등은 조사해보지 않았으니 이 점 유의해주세요.
ⓒ 2021. Marshall K All rights reserved