Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
dialog要素でつくるモーダルダイアログ
Search
yomotsu
September 16, 2022
Programming
0
1k
dialog要素でつくるモーダルダイアログ
yomotsu
September 16, 2022
Tweet
Share
More Decks by yomotsu
See All by yomotsu
three.jsとRapierでレースゲームが3日でできた話
yomotsu
0
580
PBR in three.js
yomotsu
1
910
IE to Edge
yomotsu
1
350
A Camera Control Library for three.js
yomotsu
1
1.3k
Let’s try AR on mobile Web with <model-viewer>
yomotsu
0
550
WebXR: Beyond WebGL
yomotsu
2
1.8k
Non-DOM components with WebGL in Vue.js
yomotsu
5
13k
WebGL Libs for WebApp Frameworks
yomotsu
4
7.8k
How do you show assets loading?
yomotsu
1
1k
Other Decks in Programming
See All in Programming
関数型まつり2025登壇資料「関数プログラミングと再帰」
taisontsukada
2
840
ASP.NETアプリケーションのモダナイズ インフラ編
tomokusaba
1
390
ReadMoreTextView
fornewid
1
450
DroidKnights 2025 - 다양한 스크롤 뷰에서의 영상 재생
gaeun5744
3
300
Webの外へ飛び出せ NativePHPが切り拓くPHPの未来
takuyakatsusa
2
190
「ElixirでIoT!!」のこれまでとこれから
takasehideki
0
370
XSLTで作るBrainfuck処理系
makki_d
0
210
コード書くの好きな人向けAIコーディング活用tips #orestudy
77web
3
330
Claude Codeの使い方
ttnyt8701
1
130
エラーって何種類あるの?
kajitack
5
280
WindowInsetsだってテストしたい
ryunen344
1
190
セキュリティマネジャー廃止とクラウドネイティブ型サンドボックス活用
kazumura
1
190
Featured
See All Featured
Navigating Team Friction
lara
187
15k
Keith and Marios Guide to Fast Websites
keithpitt
411
22k
Site-Speed That Sticks
csswizardry
10
650
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
Building Better People: How to give real-time feedback that sticks.
wjessup
367
19k
Done Done
chrislema
184
16k
Stop Working from a Prison Cell
hatefulcrawdad
270
20k
Adopting Sorbet at Scale
ufuk
77
9.4k
Embracing the Ebb and Flow
colly
86
4.7k
GraphQLの誤解/rethinking-graphql
sonatard
71
11k
Optimising Largest Contentful Paint
csswizardry
37
3.3k
Measuring & Analyzing Core Web Vitals
bluesmoon
7
490
Transcript
EJBMPHཁૉͰͭ͘Δ ϞʔμϧμΠΞϩά $PEFST)JHI 1BSU খࢁాߊߒ
w ը໘ͷ࠷લ໘ʹදࣔ͞ΕΔϘοΫε w ϘοΫεʹίϯςϯπ͕ల։͞ΕΔ w ด͡ΔϘλϯ͕͍͍ͭͯΔ w എ໘ʹΦʔόʔϨΠ͕͋Δ ϞʔμϧμΠΞϩάͱ
None
None
None
None
None
w ͍ͭಉ͡+4ϥΠϒϥϦΛͬͯ͠·͏ ʢΧελϚΠζͮ͠Β͍ʣ w Ϟʔμϧͷ[JOEFY͍ͭ͘ʹ͢Δʁ w λϒΩʔΛԡ͢ͱϞʔμϧ֎ʹҠಈͯ͠͠·͏ w 3FBDUͷDSFBUF1PSUBM
7VFͷ5FMFQPSU͕ඞཁ Ϟʔμϧͷ͓Έ
None
EJBMPHͰղܾͰ͖·͢ʂ
גࣜձࣾϐΫηϧάϦου খࢁాߊߒ @yomotsu
Ϟʔμϧ༻ͷཁૉEJBMPH ॏͳΓͷΈ $44ͰΧελϚΠζ EJBMPHͷऑ ͓ॻ͖
Ϟʔμϧ༻ͷཁૉ EJBMPH
w ɺچ༷ͷEJBMPH͕আ w ɺ)5.--JWJOH4UBOEBSEʹ ݱ༷ͰՃ w ɺ$ISPNJVNͰαϙʔτ w ɺ)5.-ͱͯ͠8$༷ʹՃ
EJBMPH
https://html.spec.whatwg.org/multipage/interactive-elements.html#the-dialog-element
<!-- モーダル --> <dialog id="my-modal"> <p>簡易モーダル</p> </dialog>
<!-- モーダル --> <dialog id="my-modal"> <p>簡易モーダル</p> </dialog> <!-- 開くボタン
--> <button type="button" onclick="document.querySelector('#my-modal').showModal();" > 開く </button>
<!-- モーダル --> <dialog id="my-modal"> <p>簡易モーダル</p> </dialog> <!-- 開くボタン
--> <button type="button" onclick="document.querySelector('#my-modal').showModal();" > 開く </button>
<!-- モーダル --> <dialog id="my-modal"> <p>簡易モーダル</p> </dialog> <!-- 開くボタン
--> <button type="button" onclick="document.querySelector('#my-modal').showModal();" > 開く </button>
<!-- モーダル --> <dialog id="my-modal"> <p>簡易モーダル</p> <button type="button" onclick="document.querySelector( '#my-modal'
).close();" > 閉じる </button> </dialog> <!-- 開くボタン --> <button type="button" onclick="document.querySelector('#my-modal').showModal();" > 開く </button>
None
w ɹ$ISPNF ɹ4BGBSJ ɹ'JSFGPY ͰαϙʔτࡁΈ w ඇαϙʔτϒϥβ͚
ϙϦϑΟϧ͕͋Δ EJBMPH
https://github.com/GoogleChrome/dialog-poly fi ll
ॏͳΓͷΈ
w [JOEFYͰࢦఆ͢Δ w ߴ͍͕લ໘ʹදࣔ w ͷॏͳΓ͕༏ઌ ʢελοΩϯάίϯςΩετʣ [JOEFYͷ͓͞Β͍
None
None
None
None
None
w ࠷લ໘ʹදࣔ͢ΔͨΊͷ͍ͭ͘ʁ w ೖΕࢠʹͳΔͱ ࠷લ໘ʹදࣔͰ͖ͳ͍ [JOEFYͷ͓Έ
w EJBMPHʹద༻͞ΕΔ ॏͳΓϨΠϠʔ w ඞͣ࠷લ໘ʹදࣔ͞ΕΔ w $44 [JOEFYͳͲ Ͱ͑ΒΕͳ͍
τοϓϨΠϠʔ
https://fullscreen.spec.whatwg.org/#top-layer
None
None
EJBMPH ࠷લ໘͕อূ͞Ε͍ͯΔ ελοΩϯάίϯςΩετͷೖΕࢠಥഁ
$44ͰΧελϚΠζ
w EJBMPHʹϒϥβ$44͕ޮ͍͍ͯΔɻ $44্ॻ͖Մೳ w എܠ෦ CBDLESPQηϨΫλͰ੍ޚͰ͖Δ ϙϦϑΟϧར༻࣌CBDLESPQ
$44ͰΧελϚΠζ
None
None
None
None
EJBMPHͷऑ എܠΫϦοΫͰด͍ͨ͡
None
EJBMPHΛΫϦοΫͨ͠ͱ͖ ΫϦοΫ͕ɺຊମΑΓ֎ͳΒ ด͡Δ
None
const $modal = document.querySelector( '#my-modal' ); $modal.removeEventListener( 'click', onDialogClick );
function onDialogClick( event ) { const elRect = $modal.getBoundingClientRect(); const isInDialog = elRect.top <= event.clientY && event.clientY <= elRect.bottom && elRect.left <= event.clientX && event.clientX <= elRect.right; // もし、内側をクリックしていたら、なにもしない if ( isInDialog ) return; // それ以外(外側をクリック)なら閉じる $modal.close(); }
const $modal = document.querySelector( '#my-modal' ); $modal.removeEventListener( 'click', onDialogClick );
function onDialogClick( event ) { const elRect = $modal.getBoundingClientRect(); const isInDialog = elRect.top <= event.clientY && event.clientY <= elRect.bottom && elRect.left <= event.clientX && event.clientX <= elRect.right; // もし、内側をクリックしていたら、なにもしない if ( isInDialog ) return; // それ以外(外側をクリック)なら閉じる $modal.close(); }
EJBMPHͷऑ ΞχϝʔγϣϯͰด͍ͨ͡
w ։͘ࡍʹɺ $44"OJNBUJPOTΛద༻͢Δ w ։͘ޙɺด͡Δલʹ DMBTTΛมߋͯ͠ $445SBOTJUJPOΛద༻͢Δ
Ξχϝʔγϣϯ
@keyframes fadeIn { 0% { opacity: 0; } 100% {
opacity: 1; } }
.myModal[open] { animation: fadeIn 1s 1; } .myModal[open]::backdrop { animation:
fadeIn 1s 1; } EJBMPH͕։͘ͱ PQFOଐੑ͕͘
None
.myModal:modal { animation: fadeIn 1s 1; } .myModal:modal::backdrop { animation:
fadeIn 1s 1; } NPEBMٖࣅΫϥε ϙϦϑΟϧͰ͖ͳ͍
w ։͘ࡍʹɺ $44"OJNBUJPOTΛద༻͢Δ w ։͘ޙɺด͡Δલʹ DMBTTΛมߋͯ͠ $445SBOTJUJPOΛద༻͢Δ
Ξχϝʔγϣϯ
dialog.myModal { opacity: 0; transform: scale( .9 ); transition: opacity
.5s, transform .5s; } dialog.myModal.-opening { opacity: 1; transform: scale( 1 ); }
const showModal = ( id ) => { const $modal
= document.getElementById( id ); $modal.showModal(); requestAnimationFrame( () => $modal.classList.add( '-opening' ) ); } ϑϨʔϜ͔ͬͯΒ ΫϥεΛ༩͢Δ
const closeModal = ( id ) => { const $modal
= document.getElementById( id ); $modal.classList.remove( '-opening' ); $modal.addEventListener( 'transitionend', $modal.close, { once: true } ); } ΞχϝʔγϣϯྃΛͬͯ DMPTF͢Δ
None
EJBMPHͷऑ εΫϩʔϧΛࢭΊ͍ͨ
None
<script src="https://unpkg.com/
[email protected]
/index.js"></script>
const showModal = ( id ) => { const $modal
= document.getElementById( id ); $modal.showModal(); noScroll.on(); // ϖʔδຊମͷεΫϩʔϧΛࢭ͢Δ $modal.addEventListener( 'cancel', onClose ); $modal.addEventListener( 'close', onClose ); } EJBMPHͷDMPTF DBODFM͔DMPTFΠϕϯτͰ ݕͰ͖Δ
const onClose = ( event ) => { noScroll.off(); //
ページ本体のスクロール抑止解除 const $modal = event.target; $modal.removeEventListener( 'cancel', onClose ); $modal.removeEventListener( 'close', onClose ); }
w جຊ͚ͩͳΒ+4΄΅ෆཁ w +4ίʔυѹతʹগͳ͍ ʢϒϥβ͕ɺ΄ͱΜͲͬͯ͘ΕΔʣ w ʮϒϥοΫϘοΫεʯ͕ͳ͍ w τοϓϨΠϠʔΛ͍͍ͨͳΒ
EJBMPHҰ ݁ہ+4͕ඞཁʁ
͓࣋ͪؼΓ༻ ίʔυ
https://github.com/codegrid/2022-09-16-cssnite-dialog
https://www.codegrid.net/series/2022-modal-dialog
·ͱΊ
w γϯϓϧ࣮ͳΒɺ+4ϥΠϒϥϦෆཁ w ΧελϚΠζ͍͢͠ɺ੍ޚ͍͢͠ w ࠷લ໘͕อূ͞ΕΔ τοϓϨΠϠʔ w ϑΥʔΧεɺΩʔϘʔυૢ࡞ɺSPMF੍ޚ
Ϟʔμϧઐ༻ͷཁૉͰ ʮ͍͍͜ͱʯͨ͘͞Μ
Ϟʔμϧ࣮ ͏ɺμϧ͘ͳ͍ʁ
͓ΘΓ !ZPNPUTV