javascript - Scroll Snap for div 看起来像 HTML 中的 iPhone

标签 javascript html css scroll-snap

我用 HTML 制作了这个 iPhone(请不要注意意大利面条代码,它是德文的,如果有必要我可以愉快地翻译它):

var time = document.getElementById("time");
    var notification = document.getElementById("notification");
    var notificationHeader = document.getElementById("notificationHeader");
    var notificationDescription = document.getElementById("notificationDescription");
    var verificationCode = Math.floor(1000 + Math.random() * 9000);
    var input = document.getElementById("instagramNumberText");
    var correctOrWrongCheck = document.getElementById("correctOrWrongCheck");
    var verificationCodePTag = document.getElementById("verificationCode");
    var instagram = document.getElementById("instagramApp");
    var mail = document.getElementById("mailApp");
    var createAccountButton = document.getElementById("createAccount");
    var createAccountForm = document.getElementById("createAccountForm");
    var verificationCodeInstagramPage = document.getElementById("verificationCodeInstagramPage");
    var controlVerificationCodeButton = document.getElementById("controlVerificationCode");
    var continueToInstagramAccountButton = document.getElementById("continueToInstagramAccount");
    var verificationCodeEmailDescription = document.getElementById("verificationCodeEmailDescription");
    var verificationCodeEmail = document.getElementById("verificationCodeEmail");
    var erfolgreichAngemeldet = document.getElementById("erfolgreichAngemeldet");
    var instagramAccount = document.getElementById("instagramAccount");

    var instagramName = document.getElementById("instagramName");
    var instagramNameInput = document.getElementById("instagramNameInput");


    // Time

    function checkTime(i) {
        if (i < 10) {
            i = "0" + i;
        }
        return i;
    }

    function startTime() {
        var today = new Date();
        var h = today.getHours();
        var m = today.getMinutes();
        // add a zero in front of numbers<10
        m = checkTime(m);
        document.getElementById('time').innerHTML = h + ":" + m;
        t = setTimeout(function() {
            startTime()
        }, 500);
    }
    startTime();

    // Insta

    function controlVerificationCode() {
        if (input.value == verificationCode) {
            correctOrWrongCheck.innerHTML = "Der Code war korrekt!";
            continueToInstagramAccountButton.style.display = "block";
            continueToInstagramAccountButton.style.margin = "5px auto";
            controlVerificationCodeButton.style.display = "none";
        } else if (input.value !== verificationCode) {
            correctOrWrongCheck.innerHTML = "Der Code ist leider Falsch!";
            continueToInstagramAccountButton.style.display = "none";
            controlVerificationCodeButton.style.display = "block";
        }
    }

    verificationCodeEmailDescription.innerHTML = "Ihr Bestätigunscode lautet: " + verificationCode;

    // OPEN AND CLOSE APPS

    function openVerificationCodeInstagramPage() {
        createAccountForm.style.display = "none";
        verificationCodeInstagramPage.style.display = "block"
        verificationCodeEmail.style.display = "block";
        instagramName.value = instagramNameInput.value;
        notification.style.transform = "translate(-50%, -50%) scale(0)";
        notificationDescription.innerHTML = "Ihr Bestätigunscode lautet: ...";
        setTimeout(
            function() {
                notification.style.transform = "translate(-50%, -50%) scale(1)";
            }, 1000);
         setTimeout(
            function() {
                notification.style.transform = "translate(-50%, -50%) scale(0)";
            }, 7000);
    }

    function continueToInstagramAccount() {
        verificationCodeInstagramPage.style.display = "none";
        instagramAccount.style.display = "flex";
        erfolgreichAngemeldet.display = "none";
        notificationDescription.innerHTML = "Erfolgreich bei Instagram angemeldet"
        notification.style.transform = "translate(-50%, -50%) scale(0)";
        erfolgreichAngemeldet.style.display = "block";

        setTimeout(
            function() {
                notification.style.transform = "translate(-50%, -50%) scale(1)";
            }, 1000);
            setTimeout(
            function() {
                notification.style.transform = "translate(-50%, -50%) scale(0)";
            }, 7000);


        var counter = 0;
        var followers = document.getElementById('followers');
        setTimeout(function(){
            var st = setInterval(function(){
                followers.innerHTML = ++counter;
            },100)
        },100);
        }


    function closeNotification() {
        notification.style.transform = "translate(-50%, -50%) scale(0)";
    }

    function openInstagram() {
        instagram.style.transform = "scale(1)";
    }
    function openMail() {
        mail.style.transform = "scale(1)";
    }

    function closeApp() {
        instagram.style.transform = "scale(0)";
        mail.style.transform = "scale(0)";
    }

    window.onload = function() {
        document.getElementById("instagramNumberText").value = '';
    }
* {
            margin: 0;
            padding: 0;
            font-family: 'Roboto',sans-serif;
            user-select: none;
        }

        input:focus, textarea:focus {
            outline: 0;
        }

        #phone {
            height: 600px;
            width: 350px;
            border-radius: 50px;
            position: absolute;
            top: 600px;
            left: 50%;
            -ms-transform: translate(-50%, -50%);
            transform: translate(-50%, -50%);
            border-top: 90px solid;
            border-right: 15px solid;
            border-left: 15px solid;
            border-bottom: 90px solid;
            background-image: url("https://ioshacker.com/wp-content/uploads/2019/06/iOS-13-wallpaper.jpg");
            background-position: center;
            background-repeat: no-repeat;
            background-size: cover;
        }

        .app {
            box-shadow: 0 0 9px -4px #000;
        }

        #topbar {
            padding: 0.3em;
            color: #fff;
            display: flex;
            justify-content: space-between;
            align-items: center;
            height: 20px;
            transform: translate(-4%,0) scale(0.9);
            width: 370px;
        }

        #connection {
            display: flex;
            align-items: center;
            width: 110px;
            justify-content: space-around;
        }

        #battery {
            display: flex;
            align-items: center;
            width: 110px;
            justify-content: end;
        }

        #battery .bi-battery-full {
            font-size: 23px;
            margin-left: 5px;
        }

        #topbar .bi-wifi-2 {
            font-size: 25px;
            margin-top: -3px;
        }

        #time {
            text-align: center;
        }

        #notification {
            margin: 0;
            position: absolute;
            top: 365px;
            left: 50%;
            -ms-transform: translate(-50%, -50%) scale(0);
            transform: translate(-50%, -50%) scale(0);
            height: 85px;
            width: 315px;
            background: #EDEBED;
            border-radius: 10px;
            z-index: 10000;
            transition: all 0.5s;
            box-shadow: 0 0 10px -1px #525252;
            padding: 0.5em 0 0.5em 1em;
            display: flex;
            flex-direction: column;
            justify-content: center;
        }

        #notification h1 {
            font-size: 23px;
        }

        #appsOne {
            display: flex;
            justify-content: space-around;
            flex-wrap: wrap;
        }

        #instagramIcon, #verificationCode, #mailIcon {
            margin: 20px;
        }

        .app {
            font-size: 40px;
            width: 50px;
            height: 50px;
            display: flex;
            justify-content: center;
            align-items: center;
            border-radius: 10px;
            transition: all 0.2s;
        }

        .app:hover {
            cursor: pointer;
            filter: brightness(90%);
        }

        .bi-instagram, .bi-envelope-fill {
            width: 40px;
            height: 40px;
            color: #fff;
            font-family: sans-serif;
        }

        /* Instagram */

        #instagramIcon {
            background: linear-gradient(45deg, #f09433 0%,#e6683c 25%,#dc2743 50%,#cc2366 75%,#bc1888 100%);
        }

        #instagramApp {
            position: absolute;
            top: 0;
            left: 0;
            background: #EAEAEA;
            height: 100%;
            width: 100%;
            display: flex;
            align-items: center;
            justify-content: center;
            flex-direction: column;
            transition: all 0.3s;
            transform: scale(0);
            z-index: 99999;
            text-align: center;
        }
        .instagramHeader {
            font-family: 'Handlee', cursive;
            font-size: 35px;
        }
        .instagramSecondHeader {
            font-size: 15px;
            width: 260px;
            margin: 1em 0;
        }
        #instagramNameInput, #instagramEmail, #instagramNumberText {
            font-size: 15px;
            padding: 0.5em;
            border: 1px solid #D1D1D1;
            margin: 0.5em 0 0.5em 0;
            width: 220px;
        }
        .instagramButton {
            width: 236px;
            font-size: 15px;
            padding: 0.5em;
            background: #3296F0;
            color: #fff;
            border: none;
            margin: 0.5em 0;
            transition: all 0.2s;
        }
        .instagramButton:hover {
            filter: brightness(80%);
            cursor: pointer;
        }
        #verificationCodeInstagramPage {
            display: none;
        }
        #continueToInstagramAccount {
            display: none;
        }

        #instagramAccount {
            display: none;
            justify-content: flex-start;
            height: 100%;
            width: 100%;
            background: #f7f7f7;
            flex-direction: column;
            align-items: center;
        }
        #instagramName {
            font-size: 20px;
            text-align: left;
            width: 85%;
            padding: 20px 20px 15px 10px;
            border-bottom: 1px solid gray;
            height: 20px;
            border-right: none;
            border-top: none;
            border-left: none;
            background: none;
        }
        #profilePicture {
            font-size: 35px;
            width: 80px;
            height: 80px;
            display: flex;
            justify-content: center;
            align-items: center;
            background: #eae9e9;
            border-radius: 100000px;
            margin: 20px;
            border: 1px solid #6f6e6e;
            color: #6f6e6e;
        }
        #instagramPictureAndNumbers {
            display: inherit;
            width: 360px;
        }
        #numbers {
            width: 225px;
            height: 45px;
            margin: 35px 0 0 0;
        }
        #userDescription {
            width: 320px;
            font-size: 13px;
            border: none;
            background: none;
            resize: none;
        }
        .bi-table {
            font-size: 25px;
            border-bottom: 1px solid;
            width: 90%;
            margin-top: 0.5em;
        }
        #emptyImages {
            color: #c7c7c7;
            margin: 100px;
            font-size: 14px;
        }

        /* Mail */
        #mailIcon {
            background: linear-gradient(0deg, #05ffff 0%, #3cabe6 30%, #2763dc 70%);
        }
        #mailApp {
            position: absolute;
            top: 0;
            left: 0;
            background: #f6f6f6;
            height: 100%;
            width: 100%;
            display: flex;
            align-items: center;
            justify-content: flex-start;
            flex-direction: column;
            transition: all 0.3s;
            transform: scale(0);
            z-index: 99999;
            text-align: center;
        }
        #mailHeader {
            font-size: 25px;
            padding: 20px;
            background: #fff;
            width: 88%;
            z-index: 999;
        }
        #verificationCodeEmail {
            display: none;
        }
        .email {
            background: #fff;
            width: 97%;
            padding: 5px;
            border-top: 1px solid #e6e6e6;
        }
        .emailHeader {
            text-align: left;
            margin: 10px;
            font-size: 25px;
        }
        #verificationCodeEmailDescription, #erfolgreichAngemeldetDescription {
            text-align: left;
            margin: 10px;
        }

        #erfolgreichAngemeldet {
            display: none;
        }

        /* Home Button */
        #homeButton {
            position: absolute;
            height: 60px;
            width: 60px;
            background: transparent;
            z-index: 9999;
            bottom: -107px;
            border-radius: 100000px;
            left: 50%;
            -ms-transform: translate(-50%, -50%) rotate(-10deg);
            transform: translate(-50%, -50%) rotate(-10deg);
            border: 1px outset;
            cursor: pointer;
        }
<meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.4.1/font/bootstrap-icons.css">
    <link rel="preconnect" href="https://fonts.gstatic.com">
    <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@100;300;400&display=swap" rel="stylesheet">

<div id="notification" onclick="closeNotification();">
    <h1 id="notificationHeader"><b>Neue Email erhalten!</b></h1>
    <p id="notificationDescription"></p>
</div>

<div id="phone">

    <div id="topbar">

        <div id="connection">
            <i class="bi bi-bar-chart-fill"></i>
            LIDL LTE
            <i class="bi bi-wifi-2"></i>
        </div>

        <p id="time"></p>

        <div id="battery">
            98%
            <i class="bi bi-battery-full"></i>
        </div>
    </div>

<div id="slider">
        <div id="appsOne">
            <!-- Instagram -->
            <div id="instagramIcon" class="app" onclick="openInstagram();"><i class="bi bi-instagram"></i></div>
                <div id="instagramApp">
                    <form id="createAccountForm" action="#" onsubmit="openVerificationCodeInstagramPage(); return false;">
                        <h1 class="instagramHeader">Instagram</h1>
                        <p>Erstelle einen Account</p>
                        <input type="text" id="instagramNameInput" placeholder="Name" maxlength="12" autocomplete="off" required>
                        <input type="email" id="instagramEmail" placeholder="E-Mail" autocomplete="off" required>
                        <button type="submit" id="createAccount" class="instagramButton">Erstellen</button>
                    </form>

                    <div id="verificationCodeInstagramPage">
                        <h1 class="instagramHeader">Bestätigen</h1>
                        <p class="instagramSecondHeader">Wir haben ihn einen Bestätigungscode per Email gesendet!</p>
                        <input type="text" id="instagramNumberText" maxlength="4" onkeypress="return /[0-9]/i.test(event.key)" placeholder="Bestätigungscode"><br>
                        <button onclick="controlVerificationCode();" id="controlVerificationCode" class="instagramButton">Bestätigen</button>
                        <button class="instagramButton" id="continueToInstagramAccount" onclick="continueToInstagramAccount()">Weiter</button>
                        <p id="correctOrWrongCheck"></p>
                    </div>

                    <div id="instagramAccount">
                        <input type="text" id="instagramName">
                        <div id="instagramPictureAndNumbers">
                            <div id="profilePicture"><i class="bi bi-person-fill"></i></div>
                            <table id="numbers">
                                <tr>
                                    <th id="posts">0</th>
                                    <th id="followers">1</th>
                                    <th id="following">0</th>
                                </tr>
                                <tr>
                                    <td>Posts</td>
                                    <td>Followers</td>
                                    <td>Following</td>
                                </tr>
                            </table>
                        </div>
                        <textarea id="userDescription" placeholder="Beschreibung..." rows="10"></textarea>

                        <i class="bi bi-table"></i>
                        <p id="emptyImages">No images found</p>
                    </div>
            </div>

            <div id="appsTwo">
                Second App Page
            </div>

</div>

        <!-- Mail App -->
        <div id="mailIcon" class="app" onclick="openMail();"><i class="bi bi-envelope-fill"></i></div>
            <div id="mailApp">
                <h1 id="mailHeader">E-Mails</h1>

                <div class="email" id="erfolgreichAngemeldet">
                    <h1 class="emailHeader">Instagram</h1>
                    <p class="emailDescription" id="erfolgreichAngemeldetDescription">Erfolgreich angemeldet</p>
                </div>

                <div class="email" id="verificationCodeEmail">
                    <h1 class="emailHeader">Instagram</h1>
                    <p class="emailDescription" id="verificationCodeEmailDescription">Ihr Bestätigunscode lautet</p>
                </div>

            </div>
    </div>


    <div id="homeButton" onclick="closeApp();"></div>

要更好地查看 iPhone,您应该单击片段中的整页。
我的问题是我有 2 个 div:#appsOne#appsTwo在 div #slider 中.在 iPhone 的主页上,您可以在中间看到两个应用程序 (#appsOne) 和一个文本 (#appsTwo)。应用程序 ( #appsOne ) 应保持在原处,但文本 ( #appsTwo ) 应在第二页上进行水平滚动捕捉。我怎么能那样做?
这是一张图片,没有 slider 和 #appsTwo 的样子分区:

最佳答案

CSS 滚动捕捉
我们可以通过将每个屏幕包装在 div 中来分隔两个“屏幕”。与类 panel .
要使 slider 可滚动,我们必须应用 white-space: nowrap 将其强制为单行。要使滚动捕捉水平工作,请设置 scroll-snap-type x并使其成为 mandatory (scroll-snap-type: x mandatory;)。这意味着:

The visual viewport of this scroll container will rest on a snap point if it isn't currently scrolled. That means it snaps on that point when the scroll action finished, if possible. If content is added, moved, deleted or resized the scroll offset will be adjusted to maintain the resting on that snap point.MDN


我们还设置了 overscroll-behavior-x contain这确保相邻滚动区域不会发生滚动链接,例如底层元素不会滚动。
然后我们申请 scroll-snap-align: center .panel .为了防止面板中的内容溢出,我们还应用了white-space: initial .
结果:
https://jsfiddle.net/Spectric/j7br8h5a/
JS Scroll-snapping(鼠标拖动)
我们可以通过添加对用户拖动滚动的支持更进一步。
为此,我们实际上根本不需要滚动捕捉。我们可以用纯 JS 做到这一点。
mousedown 添加事件监听器设置 isDowntrue .记录鼠标的最后位置。
mousemove 添加事件监听器检查用户当前是否正在拖动 (isDown == true)。如果用户是,计算从当前鼠标位置到最后一个鼠标位置的距离,增加 slider 的scrollLeft通过差值,并将最后一个位置设置为当前位置。
mouseup 添加事件监听器设置 isDownfalse并检查 slider 的当前 scrollLeft大于一半。如果是,我们可以使用scrollIntoView()在一个面板上将其平滑地滚动到视口(viewport)中。

为了防止应用程序打开时滚动,我们可以将状态存储在一个变量中,我们将其设置为 true当一个打开的应用程序函数被调用并且falsecloseApp函数被调用。在 mousemove listener 我们还检查这个变量是否是true .
最佳观看位置 full-page mode

var time = document.getElementById("time");
var notification = document.getElementById("notification");
var notificationHeader = document.getElementById("notificationHeader");
var notificationDescription = document.getElementById("notificationDescription");
var verificationCode = Math.floor(1000 + Math.random() * 9000);
var input = document.getElementById("instagramNumberText");
var correctOrWrongCheck = document.getElementById("correctOrWrongCheck");
var verificationCodePTag = document.getElementById("verificationCode");
var instagram = document.getElementById("instagramApp");
var mail = document.getElementById("mailApp");
var createAccountButton = document.getElementById("createAccount");
var createAccountForm = document.getElementById("createAccountForm");
var verificationCodeInstagramPage = document.getElementById("verificationCodeInstagramPage");
var controlVerificationCodeButton = document.getElementById("controlVerificationCode");
var continueToInstagramAccountButton = document.getElementById("continueToInstagramAccount");
var verificationCodeEmailDescription = document.getElementById("verificationCodeEmailDescription");
var verificationCodeEmail = document.getElementById("verificationCodeEmail");
var erfolgreichAngemeldet = document.getElementById("erfolgreichAngemeldet");
var instagramAccount = document.getElementById("instagramAccount");

var instagramName = document.getElementById("instagramName");
var instagramNameInput = document.getElementById("instagramNameInput");


// Time

function checkTime(i) {
  if (i < 10) {
    i = "0" + i;
  }
  return i;
}

function startTime() {
  var today = new Date();
  var h = today.getHours();
  var m = today.getMinutes();
  // add a zero in front of numbers<10
  m = checkTime(m);
  document.getElementById('time').innerHTML = h + ":" + m;
  t = setTimeout(function() {
    startTime()
  }, 500);
}
startTime();

// Insta

function controlVerificationCode() {
  if (input.value == verificationCode) {
    correctOrWrongCheck.innerHTML = "Der Code war korrekt!";
    continueToInstagramAccountButton.style.display = "block";
    continueToInstagramAccountButton.style.margin = "5px auto";
    controlVerificationCodeButton.style.display = "none";
  } else if (input.value !== verificationCode) {
    correctOrWrongCheck.innerHTML = "Der Code ist leider Falsch!";
    continueToInstagramAccountButton.style.display = "none";
    controlVerificationCodeButton.style.display = "block";
  }
}

verificationCodeEmailDescription.innerHTML = "Ihr Bestätigunscode lautet: " + verificationCode;

// OPEN AND CLOSE APPS

function openVerificationCodeInstagramPage() {
  createAccountForm.style.display = "none";
  verificationCodeInstagramPage.style.display = "block"
  verificationCodeEmail.style.display = "block";
  instagramName.value = instagramNameInput.value;
  notification.style.transform = "translate(-50%, -50%) scale(0)";
  notificationDescription.innerHTML = "Ihr Bestätigunscode lautet: ...";
  setTimeout(
    function() {
      notification.style.transform = "translate(-50%, -50%) scale(1)";
    }, 1000);
  setTimeout(
    function() {
      notification.style.transform = "translate(-50%, -50%) scale(0)";
    }, 7000);
}

function continueToInstagramAccount() {
  verificationCodeInstagramPage.style.display = "none";
  instagramAccount.style.display = "flex";
  erfolgreichAngemeldet.display = "none";
  notificationDescription.innerHTML = "Erfolgreich bei Instagram angemeldet"
  notification.style.transform = "translate(-50%, -50%) scale(0)";
  erfolgreichAngemeldet.style.display = "block";

  setTimeout(
    function() {
      notification.style.transform = "translate(-50%, -50%) scale(1)";
    }, 1000);
  setTimeout(
    function() {
      notification.style.transform = "translate(-50%, -50%) scale(0)";
    }, 7000);


  var counter = 0;
  var followers = document.getElementById('followers');
  setTimeout(function() {
    var st = setInterval(function() {
      followers.innerHTML = ++counter;
    }, 100)
  }, 100);
}


function closeNotification() {
  notification.style.transform = "translate(-50%, -50%) scale(0)";
}

var isAppOpened = false;

function openInstagram() {
  isAppOpened = true;
  instagram.style.transform = "scale(1)";
}

function openMail() {
  isAppOpened = true;
  mail.style.transform = "scale(1)";
}

function closeApp() {
  isAppOpened = false;
  instagram.style.transform = "scale(0)";
  mail.style.transform = "scale(0)";
}

window.onload = function() {
  document.getElementById("instagramNumberText").value = '';
}
const slider = document.getElementById("slider");
const panels = document.querySelectorAll('.panel');
var lastX = 0;
var isDown = false;

document.addEventListener("mousedown", function(e) {
  lastX = e.pageX;
  isDown = true;
})
document.addEventListener("mousemove", function(e) {
  if (isDown && !isAppOpened) {
    const curX = e.pageX;
    const diff = lastX - curX;
    slider.scrollLeft += diff;
    lastX = curX;
  }

})
document.addEventListener("mouseup", function() {
  isDown = false;
  slider.style.scrollBehavior = "smooth";
  if (slider.scrollLeft > 175) {
    panels[1].scrollIntoView();
  } else {
    panels[0].scrollIntoView();
  }
  slider.style.scrollBehavior = "unset";
})
* {
  margin: 0;
  padding: 0;
  font-family: 'Roboto', sans-serif;
  user-select: none;
}

input:focus,
textarea:focus {
  outline: 0;
}

#phone {
  height: 600px;
  width: 350px;
  border-radius: 50px;
  position: absolute;
  top: 600px;
  left: 50%;
  -ms-transform: translate(-50%, -50%);
  transform: translate(-50%, -50%);
  border-top: 90px solid;
  border-right: 15px solid;
  border-left: 15px solid;
  border-bottom: 90px solid;
  background-image: url("https://ioshacker.com/wp-content/uploads/2019/06/iOS-13-wallpaper.jpg");
  background-position: center;
  background-repeat: no-repeat;
  background-size: cover;
}

.app {
  box-shadow: 0 0 9px -4px #000;
}

#topbar {
  padding: 0.3em;
  color: #fff;
  display: flex;
  justify-content: space-between;
  align-items: center;
  height: 20px;
  transform: translate(-4%, 0) scale(0.9);
  width: 370px;
}

#connection {
  display: flex;
  align-items: center;
  width: 110px;
  justify-content: space-around;
}

#battery {
  display: flex;
  align-items: center;
  width: 110px;
  justify-content: end;
}

#battery .bi-battery-full {
  font-size: 23px;
  margin-left: 5px;
}

#topbar .bi-wifi-2 {
  font-size: 25px;
  margin-top: -3px;
}

#time {
  text-align: center;
}

#notification {
  margin: 0;
  position: absolute;
  top: 365px;
  left: 50%;
  -ms-transform: translate(-50%, -50%) scale(0);
  transform: translate(-50%, -50%) scale(0);
  height: 85px;
  width: 315px;
  background: #EDEBED;
  border-radius: 10px;
  z-index: 10000;
  transition: all 0.5s;
  box-shadow: 0 0 10px -1px #525252;
  padding: 0.5em 0 0.5em 1em;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

#notification h1 {
  font-size: 23px;
}

#appsOne {
  display: flex;
  justify-content: space-around;
  flex-wrap: wrap;
}

#instagramIcon,
#verificationCode,
#mailIcon {
  margin: 20px;
}

.app {
  font-size: 40px;
  width: 50px;
  height: 50px;
  display: flex;
  justify-content: center;
  align-items: center;
  border-radius: 10px;
  transition: all 0.2s;
}

.app:hover {
  cursor: pointer;
  filter: brightness(90%);
}

.bi-instagram,
.bi-envelope-fill {
  width: 40px;
  height: 40px;
  color: #fff;
  font-family: sans-serif;
}


/* Instagram */

#instagramIcon {
  background: linear-gradient(45deg, #f09433 0%, #e6683c 25%, #dc2743 50%, #cc2366 75%, #bc1888 100%);
}

#instagramApp {
  position: absolute;
  top: 0;
  left: 0;
  background: #EAEAEA;
  height: 100%;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  transition: all 0.3s;
  transform: scale(0);
  z-index: 99999;
  text-align: center;
}

.instagramHeader {
  font-family: 'Handlee', cursive;
  font-size: 35px;
}

.instagramSecondHeader {
  font-size: 15px;
  width: 260px;
  margin: 1em 0;
}

#instagramNameInput,
#instagramEmail,
#instagramNumberText {
  font-size: 15px;
  padding: 0.5em;
  border: 1px solid #D1D1D1;
  margin: 0.5em 0 0.5em 0;
  width: 220px;
}

.instagramButton {
  width: 236px;
  font-size: 15px;
  padding: 0.5em;
  background: #3296F0;
  color: #fff;
  border: none;
  margin: 0.5em 0;
  transition: all 0.2s;
}

.instagramButton:hover {
  filter: brightness(80%);
  cursor: pointer;
}

#verificationCodeInstagramPage {
  display: none;
}

#continueToInstagramAccount {
  display: none;
}

#instagramAccount {
  display: none;
  justify-content: flex-start;
  height: 100%;
  width: 100%;
  background: #f7f7f7;
  flex-direction: column;
  align-items: center;
}

#instagramName {
  font-size: 20px;
  text-align: left;
  width: 85%;
  padding: 20px 20px 15px 10px;
  border-bottom: 1px solid gray;
  height: 20px;
  border-right: none;
  border-top: none;
  border-left: none;
  background: none;
}

#profilePicture {
  font-size: 35px;
  width: 80px;
  height: 80px;
  display: flex;
  justify-content: center;
  align-items: center;
  background: #eae9e9;
  border-radius: 100000px;
  margin: 20px;
  border: 1px solid #6f6e6e;
  color: #6f6e6e;
}

#instagramPictureAndNumbers {
  display: inherit;
  width: 360px;
}

#numbers {
  width: 225px;
  height: 45px;
  margin: 35px 0 0 0;
}

#userDescription {
  width: 320px;
  font-size: 13px;
  border: none;
  background: none;
  resize: none;
}

.bi-table {
  font-size: 25px;
  border-bottom: 1px solid;
  width: 90%;
  margin-top: 0.5em;
}

#emptyImages {
  color: #c7c7c7;
  margin: 100px;
  font-size: 14px;
}


/* Mail */

#mailIcon {
  background: linear-gradient(0deg, #05ffff 0%, #3cabe6 30%, #2763dc 70%);
}

#mailApp {
  position: absolute;
  top: 0;
  left: 0;
  background: #f6f6f6;
  height: 100%;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  flex-direction: column;
  transition: all 0.3s;
  transform: scale(0);
  z-index: 99999;
  text-align: center;
}

#mailHeader {
  font-size: 25px;
  padding: 20px;
  background: #fff;
  width: 88%;
  z-index: 999;
}

#verificationCodeEmail {
  display: none;
}

.email {
  background: #fff;
  width: 97%;
  padding: 5px;
  border-top: 1px solid #e6e6e6;
}

.emailHeader {
  text-align: left;
  margin: 10px;
  font-size: 25px;
}

#verificationCodeEmailDescription,
#erfolgreichAngemeldetDescription {
  text-align: left;
  margin: 10px;
}

#erfolgreichAngemeldet {
  display: none;
}


/* Home Button */

#homeButton {
  position: absolute;
  height: 60px;
  width: 60px;
  background: transparent;
  z-index: 9999;
  bottom: -107px;
  border-radius: 100000px;
  left: 50%;
  -ms-transform: translate(-50%, -50%) rotate(-10deg);
  transform: translate(-50%, -50%) rotate(-10deg);
  border: 1px outset;
  cursor: pointer;
}

#slider {
  white-space: nowrap;
  position: relative;
  overflow-x: scroll;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  height: calc(100% - 30px);
}

.panel {
  display: inline-block;
  width: 350px;
  white-space: initial;
}

#appsTwo {
  display: flex;
  justify-content: space-around;
  flex-wrap: wrap;
}
<!DOCTYPE html>
<html>

<head>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.4.1/font/bootstrap-icons.css">
  <link rel="preconnect" href="https://fonts.gstatic.com">
  <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@100;300;400&display=swap" rel="stylesheet">
</head>

<body>
  <div id="notification" onclick="closeNotification();">
    <h1 id="notificationHeader"><b>Neue Email erhalten!</b></h1>
    <p id="notificationDescription"></p>
  </div>

  <div id="phone">

    <div id="topbar">

      <div id="connection">
        <i class="bi bi-bar-chart-fill"></i> LIDL LTE
        <i class="bi bi-wifi-2"></i>
      </div>

      <p id="time"></p>

      <div id="battery">
        98%
        <i class="bi bi-battery-full"></i>
      </div>
    </div>

    <div id="slider">
      <div class="panel">
        <div id="appsOne">
          <!-- Instagram -->
          <div id="instagramIcon" class="app" onclick="openInstagram();"><i class="bi bi-instagram"></i></div>
          <div id="instagramApp">
            <form id="createAccountForm" action="#" onsubmit="openVerificationCodeInstagramPage(); return false;">
              <h1 class="instagramHeader">Instagram</h1>
              <p>Erstelle einen Account</p>
              <input type="text" id="instagramNameInput" placeholder="Name" maxlength="12" autocomplete="off" required>
              <input type="email" id="instagramEmail" placeholder="E-Mail" autocomplete="off" required>
              <button type="submit" id="createAccount" class="instagramButton">Erstellen</button>
            </form>

            <div id="verificationCodeInstagramPage">
              <h1 class="instagramHeader">Bestätigen</h1>
              <p class="instagramSecondHeader">Wir haben ihn einen Bestätigungscode per Email gesendet!
              </p>
              <input type="text" id="instagramNumberText" maxlength="4" onkeypress="return /[0-9]/i.test(event.key)" placeholder="Bestätigungscode"><br>
              <button onclick="controlVerificationCode();" id="controlVerificationCode" class="instagramButton">Bestätigen</button>
              <button class="instagramButton" id="continueToInstagramAccount" onclick="continueToInstagramAccount()">Weiter</button>
              <p id="correctOrWrongCheck"></p>
            </div>

            <div id="instagramAccount">
              <input type="text" id="instagramName">
              <div id="instagramPictureAndNumbers">
                <div id="profilePicture"><i class="bi bi-person-fill"></i></div>
                <table id="numbers">
                  <tr>
                    <th id="posts">0</th>
                    <th id="followers">1</th>
                    <th id="following">0</th>
                  </tr>
                  <tr>
                    <td>Posts</td>
                    <td>Followers</td>
                    <td>Following</td>
                  </tr>
                </table>
              </div>
              <textarea id="userDescription" placeholder="Beschreibung..." rows="10"></textarea>

              <i class="bi bi-table"></i>
              <p id="emptyImages">No images found</p>
            </div>
          </div>
          <div id="mailIcon" class="app" onclick="openMail();"><i class="bi bi-envelope-fill"></i></div>
          <div id="mailApp">
            <h1 id="mailHeader">E-Mails</h1>

            <div class="email" id="erfolgreichAngemeldet">
              <h1 class="emailHeader">Instagram</h1>
              <p class="emailDescription" id="erfolgreichAngemeldetDescription">Erfolgreich angemeldet</p>
            </div>

            <div class="email" id="verificationCodeEmail">
              <h1 class="emailHeader">Instagram</h1>
              <p class="emailDescription" id="verificationCodeEmailDescription">Ihr Bestätigunscode lautet
              </p>
            </div>

          </div>
        </div>

      </div>
      <div class="panel">
        <div id="appsTwo">
          <div>
            Second App Page
          </div>
        </div>
      </div>
    </div>
    <div id="homeButton" onclick="closeApp();"></div>
  </div>
</body>

</html>

结果:

您可以通过应用 overflow-x:hidden 隐藏水平滚动条至#slider

关于javascript - Scroll Snap for div 看起来像 HTML 中的 iPhone,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68195040/

相关文章:

javascript - 使用 jQuery 封装动态内容

html - 根据屏幕大小按比例缩小包含图像的 HTML 表格

javascript - 将带有字符串的换行符存储在变量中

html - Firefox 中的站点标题问题

html - 不知道如何使导航栏居中

javascript - 汉堡菜单,如何改变十字的颜色

html - CSS Transitions 交叉淡入淡出多个图像无法正常工作

javascript - 加载时不可靠地检索图像中的属性

javascript - 如果输入为空,如何查找?

javascript - Kendo UI TreeView DragEnd 事件崩溃极其缓慢