웹 프론트엔드 JS 튜토리얼 모바일 페이지 개발 적응 렘 레이아웃 원리

모바일 페이지 개발 적응 렘 레이아웃 원리

Nov 21, 2016 pm 05:41 PM

모바일 페이지 개발을 위한 렘 레이아웃 적응의 원리

적응이란 무엇이며 왜 적응해야 하는가

우리가 받는 디자인 도면은 일반적으로 640, 750, 1080 해상도입니다. 디자인을 기반으로 하여 이제는 해상도, 논리 픽셀, 뷰포트가 다른 다양한 모바일 단말기가 있으므로 모든 장치에서 페이지가 잘 표시되도록 하려면 이러한 장치에 맞게 통합 처리해야 합니다. 이 프로세스를 모바일 단말기 적응이라고 합니다.

알아야 할 몇 가지 개념:

물리적 픽셀(물리적 픽셀)

물리적 픽셀은 디스플레이(휴대폰 화면)에서 가장 작은 물리적 디스플레이 단위로, 우리의 일반적인 해결 방법으로 이해될 수 있습니다.

디바이스 독립적 픽셀(밀도 독립적 픽셀)

디바이스 독립적 픽셀(밀도 독립적 픽셀이라고도 함)은 컴퓨터 좌표계의 한 점으로 생각할 수 있습니다. 프로그램에 의해 제어될 수 있는 지점입니다. 사용된 가상 픽셀(예: CSS 픽셀)은 관련 시스템에 의해 실제 픽셀로 변환됩니다. 이는 우리가 말하는 시각적 뷰포트의 크기로 이해될 수 있습니다. >

그래서 물리적 픽셀과 장치 독립적 픽셀의 차이에는 일정한 대응 관계가 있는데, 이것이 바로 다음에 이야기할 장치 픽셀 비율입니다.

장치 픽셀 비율(장치 픽셀 비율)

장치 픽셀 비율(줄여서 dpr)은 물리적 픽셀과 장치 독립 픽셀 간의 대응 관계를 정의합니다. 해당 값은 다음 공식에 따라 얻을 수 있습니다. 장치 픽셀 비율 = 물리적 픽셀 / 장치 독립 픽셀 // 특정 방향, x 방향 또는 y 방향

장치 픽셀 비율은 장치 제작 시에도 설정되며, 자바스크립트에서는 윈도우를 통해 얻을 수 있습니다. .devicePixelRatio를 현재 장치의 dpr로 설정합니다.

뷰포트

PC 뷰포트는 도구 모음과 스크롤 막대를 제외한 브라우저 창 내의 콘텐츠 영역을 나타냅니다.

모바일 브라우저의 뷰포트 여러 상황에서:

콘텐츠별로 설정되는 뷰포트, 최대값을 지정하는 레이아웃 뷰포트입니다. 너비는 document.documentElement.clientWidth를 통해 얻을 수 있습니다.

우리가 보는 브라우저 창과 웹 페이지 영역의 크기는 CSS 픽셀(장치 논리 픽셀)로 표시되는 시각적 뷰포트라고 합니다.

rem

rem은 문서 및 요소 html을 기준으로 하는 css3의 길이 단위입니다. 예를 들어 html 글꼴 크기=100px를 설정한 다음 1rem=100px를 사용할 수 있습니다. 이 기본 값을 사용하여 크기를 설정합니다.

일반적으로 사용되는 솔루션:

고정 높이, 적응형 너비(백분율, em)

rem 레이아웃 사용

다음은 Taobao 홈페이지에서 rem을 사용하는 NetEase의 솔루션

NetEase의 접근 방식을 요약한 것입니다.

1) 크기 조정 없이 시각적 뷰포트, 즉 이상적인 뷰포트에 맞게 레이아웃을 설정합니다.

<meta name="viewport"content="initial-scale=1,maximum-scale=1, minimum-scale=1”>
로그인 후 복사
2) 디자인 도안의 해상도를 기준으로 폰트 크기를 100px 기준으로 했을 때 디자인 시안의 너비가 640이라면 본문 요소의 너비를 설정할 수 있습니다. 너비: 6.4rem(640/100), 레이아웃 뷰포트를 320으로 설정하면 글꼴 크기는 html=deviceWidth / 6.4입니다.

3) document.documentElement.clientWidth를 통해 deviceWidth를 가져옵니다.

4) 페이지 돔이 준비되면 html 글꼴 크기를 설정합니다.

document.documentElement.style.fontSize =document.documentElement.clientWidth / 6.4 + ‘px’
로그인 후 복사
5) mediaQuery를 통해 글꼴 크기를 설정합니다. 오류가 너무 크기 때문에 글꼴 크기로 rem을 사용할 수 없습니다.

640 디자인 초안을 예로 들면 최종 설정 html 글꼴 크기 코드는 다음과 같습니다. 레이아웃 시 디자인 초안에 표시된 크기를 100으로 나눈 값입니다. rem.

var deviceWidth = document.documentElement.clientWidth;
if(deviceWidth > 640) deviceWidth = 640;
document.documentElement.style.fontSize = deviceWidth / 6.4 + &#39;px&#39;;
로그인 후 복사
여기서 if(deviceWidth > 640) deviceWidth = 640;은 deviceWidth가 640보다 크면 물리적 해상도가 이미 1280보다 크기 때문입니다(dpr에 따라 다름). PC 웹사이트를 방문하세요.

淘宝的做法:

原理

1) 通过dpr设置缩放比,实现布局视口大小,

var scale = 1 / devicePixelRatio;  
 document.querySelector(&#39;meta[name="viewport"]&#39;).setAttribute(&#39;content&#39;,&#39;initial-scale=&#39;+ scale + &#39;, maximum-scale=&#39; + scale + &#39;, minimum-scale=&#39; + scale + &#39;, user-scalable=no&#39;);
로그인 후 복사

2) 动态计算html的font-size

document.documentElement.style.fontSize = document.documentElement.clientWidth / 10 + ‘px’;
로그인 후 복사

这里的意思是,clientWidth / 10 得到是布局视口下的rem基准值(以iphone6为例 1rem=75px),那么设计稿正好也是 750,所以对应的关系 clientWidth / 10==设计稿的尺寸/x, 那么x=设计稿的尺寸/rem基准值。如果是iphone6 plus rem基准值等于clientWidth / 10 等于124.2,那么x=750/124.2。

关于具体的实现 淘宝提供了一个开源的方案lib-flexible:https://github.com/amfe/lib-flexible

具体逻辑 :

1)判断head中是否设置了viewport,如果有设置,按照已有viewport 设置缩放比;

if (metaEl) {
        console.warn(&#39;将根据已有的meta标签来设置缩放比例&#39;);
        var match = metaEl.getAttribute(&#39;content&#39;).match(/initial\-scale=([\d\.]+)/);
        if (match) {
            scale = parseFloat(match[1]);
            dpr = parseInt(1 / scale);
        }
    }
로그인 후 복사

2)如果没有设置meta viewport,判断是否设置dpr,如果有,通过dpr计算缩放scale。

        var content = flexibleEl.getAttribute(&#39;content&#39;);
        if (content) {
            var initialDpr = content.match(/initial\-dpr=([\d\.]+)/);
            var maximumDpr = content.match(/maximum\-dpr=([\d\.]+)/);//maximum 设置最大值,与initial的值比较,取最小值;
            if (initialDpr) {
                dpr = parseFloat(initialDpr[1]);
                scale = parseFloat((1 / dpr).toFixed(2));    
            }
            if (maximumDpr) {
                dpr = parseFloat(maximumDpr[1]);
                scale = parseFloat((1 / dpr).toFixed(2));    
            }
        }
로그인 후 복사

3)如果 dpr &scale都没有设置,那么就通过设备的dpr设置起缩放 scale,

if (!dpr && !scale) {//meta[name="viewport"]&&meta[name="flexible"]都不存在。
    var isAndroid = win.navigator.appVersion.match(/android/gi);
    var isIPhone = win.navigator.appVersion.match(/iphone/gi);
    var devicePixelRatio = win.devicePixelRatio;
    if (isIPhone) {
        // iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案
        if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {                
            dpr = 3;
        } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){
            dpr = 2;
        } else {
            dpr = 1;
        }
    } else {
        // 其他设备下,仍旧使用1倍的方案
        dpr = 1;
    }
    scale = 1 / dpr;
}
로그인 후 복사

4)得到scale之后 ,如果meta 的viewport不存在,那么就创建一meta[name=“viewport”],将scale配置进去。

    metaEl = doc.createElement(&#39;meta&#39;);
    metaEl.setAttribute(&#39;name&#39;, &#39;viewport&#39;);
    metaEl.setAttribute(&#39;content&#39;, &#39;initial-scale=&#39; + scale + &#39;, maximum-scale=&#39; + scale + &#39;, minimum-scale=&#39; + scale + &#39;, user-scalable=no&#39;);

    if (docEl.firstElementChild) {

        docEl.firstElementChild.appendChild(metaEl);
         
    }
로그인 후 복사

5)动态改写html的font-size

    var width = docEl.getBoundingClientRect().width;//获取html的宽度
    if (width / dpr > 540) {//判断屏幕逻辑像素大于540时,取540
        width = 540 * dpr;
    }
    var rem = width / 10;
    docEl.style.fontSize = rem + &#39;px&#39;;
    flexible.rem = win.rem = rem;
로그인 후 복사

总结:

使用rem布局,实质都是通过动态改写html的font-size基准值,来实现不同设备下的良好统一适配;

网易与淘宝不同 的地方是 ,网易将布局视口设置成了 视觉视口,淘宝将布局视口设置成了物理像素大小,通过 scale缩放嵌入了 视觉视口中;

容器元素的字体大小都不使用rem,需要额外的media查询;


본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
1 몇 달 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
1 몇 달 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
1 몇 달 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 채팅 명령 및 사용 방법
1 몇 달 전 By 尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

내 자신의 JavaScript 라이브러리를 어떻게 작성하고 게시합니까? 내 자신의 JavaScript 라이브러리를 어떻게 작성하고 게시합니까? Mar 18, 2025 pm 03:12 PM

기사는 JavaScript 라이브러리 작성, 게시 및 유지 관리, 계획, 개발, 테스트, 문서 및 홍보 전략에 중점을 둡니다.

브라우저에서 성능을 위해 JavaScript 코드를 최적화하려면 어떻게해야합니까? 브라우저에서 성능을 위해 JavaScript 코드를 최적화하려면 어떻게해야합니까? Mar 18, 2025 pm 03:14 PM

이 기사는 브라우저에서 JavaScript 성능을 최적화하기위한 전략에 대해 설명하고 실행 시간을 줄이고 페이지로드 속도에 미치는 영향을 최소화하는 데 중점을 둡니다.

프론트 엔드 열 용지 영수증에 대한 차량 코드 인쇄를 만나면 어떻게해야합니까? 프론트 엔드 열 용지 영수증에 대한 차량 코드 인쇄를 만나면 어떻게해야합니까? Apr 04, 2025 pm 02:42 PM

프론트 엔드 개발시 프론트 엔드 열지대 티켓 인쇄를위한 자주 묻는 질문과 솔루션, 티켓 인쇄는 일반적인 요구 사항입니다. 그러나 많은 개발자들이 구현하고 있습니다 ...

브라우저 개발자 도구를 사용하여 JavaScript 코드를 효과적으로 디버그하려면 어떻게해야합니까? 브라우저 개발자 도구를 사용하여 JavaScript 코드를 효과적으로 디버그하려면 어떻게해야합니까? Mar 18, 2025 pm 03:16 PM

이 기사는 브라우저 개발자 도구를 사용하여 효과적인 JavaScript 디버깅, 중단 점 설정, 콘솔 사용 및 성능 분석에 중점을 둡니다.

누가 더 많은 파이썬이나 자바 스크립트를 지불합니까? 누가 더 많은 파이썬이나 자바 스크립트를 지불합니까? Apr 04, 2025 am 12:09 AM

기술 및 산업 요구에 따라 Python 및 JavaScript 개발자에 대한 절대 급여는 없습니다. 1. 파이썬은 데이터 과학 및 기계 학습에서 더 많은 비용을 지불 할 수 있습니다. 2. JavaScript는 프론트 엔드 및 풀 스택 개발에 큰 수요가 있으며 급여도 상당합니다. 3. 영향 요인에는 경험, 지리적 위치, 회사 규모 및 특정 기술이 포함됩니다.

소스 맵을 사용하여 조정 된 JavaScript 코드를 디버그하는 방법은 무엇입니까? 소스 맵을 사용하여 조정 된 JavaScript 코드를 디버그하는 방법은 무엇입니까? Mar 18, 2025 pm 03:17 PM

이 기사는 소스 맵을 사용하여 원래 코드에 다시 매핑하여 미니어링 된 JavaScript를 디버그하는 방법을 설명합니다. 소스 맵 활성화, 브레이크 포인트 설정 및 Chrome Devtools 및 Webpack과 같은 도구 사용에 대해 설명합니다.

JavaScript를 사용하여 동일한 ID와 동일한 ID로 배열 요소를 하나의 객체로 병합하는 방법은 무엇입니까? JavaScript를 사용하여 동일한 ID와 동일한 ID로 배열 요소를 하나의 객체로 병합하는 방법은 무엇입니까? Apr 04, 2025 pm 05:09 PM

동일한 ID로 배열 요소를 JavaScript의 하나의 객체로 병합하는 방법은 무엇입니까? 데이터를 처리 할 때 종종 동일한 ID를 가질 필요가 있습니다 ...

Console.log 출력 결과의 차이 : 두 통화가 다른 이유는 무엇입니까? Console.log 출력 결과의 차이 : 두 통화가 다른 이유는 무엇입니까? Apr 04, 2025 pm 05:12 PM

Console.log 출력의 차이의 근본 원인에 대한 심층적 인 논의. 이 기사에서는 Console.log 함수의 출력 결과의 차이점을 코드에서 분석하고 그에 따른 이유를 설명합니다. � ...

See all articles