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
990
dialog要素でつくるモーダルダイアログ
yomotsu
September 16, 2022
Tweet
Share
More Decks by yomotsu
See All by yomotsu
three.jsとRapierでレースゲームが3日でできた話
yomotsu
0
520
PBR in three.js
yomotsu
1
880
IE to Edge
yomotsu
1
340
A Camera Control Library for three.js
yomotsu
1
1.2k
Let’s try AR on mobile Web with <model-viewer>
yomotsu
0
540
WebXR: Beyond WebGL
yomotsu
2
1.8k
Non-DOM components with WebGL in Vue.js
yomotsu
5
12k
WebGL Libs for WebApp Frameworks
yomotsu
4
7.8k
How do you show assets loading?
yomotsu
1
990
Other Decks in Programming
See All in Programming
The Implementations of Advanced LR Parser Algorithm
junk0612
1
330
状態と共に暮らす:ステートフルへの挑戦
ypresto
1
700
Contribute to Comunities | React Tokyo Meetup #4 LT
sasagar
0
500
Java 24まとめ / Java 24 summary
kishida
3
500
Exit 8 for SwiftUI
ojun9
0
140
PHP で学ぶ OAuth 入門
azuki
1
210
SwiftUI API Design Lessons
niw
1
300
Being an ethical software engineer
xgouchet
PRO
0
210
MCP調べてみました! / Exploring MCP
uhzz
2
2.3k
大LLM時代にこの先生きのこるには-ITエンジニア編
fumiyakume
7
3.1k
一緒に働きたくなるプログラマの思想 #QiitaConference
mu_zaru
59
14k
サービスレベルを管理してアジャイルを加速しよう!! / slm-accelerate-agility
tomoyakitaura
1
190
Featured
See All Featured
Practical Orchestrator
shlominoach
186
11k
StorybookのUI Testing Handbookを読んだ
zakiyama
29
5.6k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
119
51k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
53k
Java REST API Framework Comparison - PWX 2021
mraible
30
8.5k
What's in a price? How to price your products and services
michaelherold
245
12k
Building Better People: How to give real-time feedback that sticks.
wjessup
367
19k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
667
120k
Code Review Best Practice
trishagee
67
18k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
23
2.6k
The Invisible Side of Design
smashingmag
299
50k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
30
2k
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