移动端web开发——像素的适配

vue项目:大屏自适应解决方案(两种) vue大屏自适应解决方案, 移动端自适应方案,vue3, vue2。适配方案 阅读详情

像素和dpr

定义

像素,又称画素,是图像显示的基本单位,译自英文“pixel”,pix 是英语单词 picture 的常用简写,加上英语单词“元素” element,就得到 pixel,故“像素”表示“图像元素”之意,有时亦被称为 pel(picture element)

像素是网页布局的基础。一个像素就是计算机能够显示一种特定颜色的最小区域。当设备尺寸相同但像素变得更密集时,屏幕能显示的画面的过渡更细致,网站看起来更明快。

ppi 是指屏幕上每英寸可以显示的像素点的数量,即屏幕像素密度

分类

像素分为两种:设备像素和 CSS 像素

  1. 设备像素(device independent pixels): 设备屏幕的物理像素,任何设备的物理像素的数量都是固定的
  2. CSS 像素(CSS pixels): 又称为逻辑像素,是为web开发者创造的,在 CSS 和 javascript 中使用的一个抽象的层

CSS 声明和几乎所有的 javascript 属性都使用 CSS 像素,因此实际上从来用不上设备像素,唯一的例外是screen.width/height

//我们通过CSS和javascript代码设置的像素都是逻辑像素
width:300px;
font-size:16px;
缩放

(设备像素→深蓝色背景,CSS 像素→半透明背景)

在桌面端,css 的1个像素往往都是对应着电脑屏幕的1个物理像素。

//一个 CSS 像素完全覆盖了一个设备像素

image

而在手机端,由于屏幕尺寸的限制,缩放是经常性的操作。

//左图表示当用户进行缩小操作时,一个设备像素覆盖了多个 CSS 像素

//右图表示当用户进行放大操作时,一个 CSS 像素覆盖了多个设备像素

image image

不论我们进行缩小或放大操作,元素设置的 CSS 像素(如width:300px)是始终不变的,而一个 CSS 像素对应多少个设备像素是根据当前的缩放比例来决定的

DPR

设备像素比 DPR (devicePixelRatio) 是默认缩放为100%的情况下,设备像素和 CSS 像素的比值

DPR = 设备像素 / CSS像素(某一方向上)

在早先的移动设备中,并没有 DPR 的概念。随着技术的发展,移动设备的屏幕像素密度越来越高。从 iphone4 开始,苹果公司推出了所谓的 retina 视网膜屏幕。之所以叫做视网膜屏幕,是因为屏幕的 PPI (屏幕像素密度)太高,人的视网膜无法分辨出屏幕上的像素点。iphone4 的分辨率提高了一倍,但屏幕尺寸却没有变化,这意味着同样大小的屏幕上,像素多了一倍,于是 DPR = 2

CSS 像素对应着理想视口,其对应的javascript属性是screen.width/screen.height。设备像素比 DPR 对应的 javascript 属性是window.devicePixelRatio

以 iphone5 为例,iphone5 的 CSS 像素为320px * 568px,DPR 是 2,所以其设备像素为640px * 1136px

640(px) / 320(px)  = 2
1136(px) / 568(px) = 2
640(px)*1136(px) /  320(px)*568(px) = 4
常用移动设备dpr
IOS设备PPIDPR
iPhone43262
iPhone4s3262
iPhone53262
iPhone5s3262
iPhone63262
iPhone6s3262
iPhone6 PLUS4413
iPhone6s PLUS4413
iPad --2
iPad --3
android尺寸dpr
低清设备-1
--1.5
--1.75
--2
mx2800*12802.5
小米note720*12802.75
--3
三星note4-4
.........
.........

总的来说,ios设备的dpr总体来说比较一致。

解决方案

1. 淘宝的移动端布局方案 Flexible
/
    hotcss 可能有神奇的问题
/
!function() {
    var innerStyle = "@charset \"utf-8\";html{color:#000;background:#fff;overflow-y:scroll;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}html {outline:0;-webkit-text-size-adjust:none;-webkit-tap-highlight-color:rgba(0,0,0,0)}html,body{font-family:sans-serif}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td,hr,button,article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{margin:0;padding:0}input,select,textarea{font-size:100%}table{border-collapse:collapse;border-spacing:0}fieldset,img{border:0}abbr,acronym{border:0;font-variant:normal}del{text-decoration:line-through}address,caption,cite,code,dfn,em,th,var{font-style:normal;font-weight:500}ol,ul{list-style:none}caption,th{text-align:left}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:500}q:before,q:after{content:''}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}a:hover{text-decoration:underline}ins,a{text-decoration:none}",
        createStyle = document.createElement("style");
    if (document.getElementsByTagName("head")[0].appendChild(createStyle),
            createStyle.styleSheet)
        createStyle.styleSheet.disabled || (createStyle.styleSheet.cssText = innerStyle);
    else
        try {
            createStyle.innerHTML = innerStyle;
        } catch (ex) {
            createStyle.innerText = innerStyle;
        }
}();
! function(window, nameSpace) {
    var timer, doc = window.document,
        docEl = doc.documentElement,
        metaEl = doc.querySelector('meta[name="viewport"]'),
        flexibleEl = doc.querySelector('meta[name="flexible"]'),
        dpr = 0,
        scale = 0,
        Flexible = nameSpace.flexible || (nameSpace.flexible = {});
        // 给Flexible 开创命名空间
    //刷新rem
    function refreshRem() {
        var width = docEl.getBoundingClientRect().width;
        //width / dpr > 540 && (width = 540  dpr);
        if(width / dpr > 540) {
            width = 540  dpr ;
        }
        var rootSize = width / 10;
        docEl.style.fontSize = rootSize + "px",
         Flexible.rem = window.rem = rootSize;
    }
    if (metaEl) {
       console.warn('将根据已有的meta标签来设置缩放比例');
       var match = metaEl.getAttribute('content').match(/initial-scale=([\d.]+)/);
       if (match) {
           scale = parseFloat(match[1]);
           dpr = parseInt(1 / scale);
       }
       //如果在meta标签中,我们手动配置了flexible,则使用里面的内容
    } else if (flexibleEl) {
       var content = flexibleEl.getAttribute('content');
       if (content) {
           var initialDpr = content.match(/initial-dpr=([\d.]+)/);
           var maximumDpr = content.match(/maximum-dpr=([\d.]+)/);
           if (initialDpr) {
               dpr = parseFloat(initialDpr[1]);
               scale = parseFloat((1 / dpr).toFixed(2));
           }
           if (maximumDpr) {
               dpr = parseFloat(maximumDpr[1]);
               scale = parseFloat((1 / dpr).toFixed(2));
           }
       }
    }
    if (!dpr && !scale) {
        var isAndroid = window.navigator.appVersion.match(/android/gi);
        var isIPhone = window.navigator.appVersion.match(/iphone/gi);
        //devicePixelRatio这个属性是可以获取到设备的dpr的
        var devicePixelRatio = window.devicePixelRatio;
        if (isIPhone) {
            if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {
                dpr = 3;
            } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){
                dpr = 2;
            } else {
                dpr = 1;
            }
        } else {
            dpr = 1;
        }
        scale = 1 / dpr;
    }
    if (docEl.setAttribute("data-dpr", dpr), !metaEl)
        if (metaEl = doc.createElement("meta"),
                metaEl.setAttribute("name", "viewport"),            //j = scale            //j = scale              //j = scale
                metaEl.setAttribute("content", "initial-scale=" + scale + ", maximum-scale=" + scale + ", minimum-scale=" + scale + ", user-scalable=no"),
                docEl.firstElementChild)
            docEl.firstElementChild.appendChild(metaEl);
        else {
            var createDiv = doc.createElement("div");
            createDiv.appendChild(metaEl),
                doc.write(createDiv.innerHTML)
            }
    window.addEventListener("resize", function() {
                clearTimeout(timer),
                    timer = setTimeout(refreshRem, 300);
        }, !1),
            window.addEventListener("pageshow", function(a) {
            a.persisted && (clearTimeout(timer),
                timer = setTimeout(refreshRem, 300))
        }, !1),
        "complete" === doc.readyState ? doc.body.style.fontSize = 17  dpr + "px" : doc.addEventListener("DOMContentLoaded", function() {
            doc.body.style.fontSize = 17  dpr + "px"
        }, !1),
        refreshRem(),
        Flexible.dpr = window.dpr = dpr,
        Flexible.refreshRem = refreshRem,
        Flexible.rem2px = function(a) {
            var pxValue = parseFloat(a)  this.rem;
            return "string" == typeof a && a.match(/rem$/) && (pxValue += "px"), pxValue ;
        },
        Flexible.px2rem = function(a) {
            var remValue = parseFloat(a) / this.rem;
            return "string" == typeof a && a.match(/px$/) && (remValue += "rem"), remValue ;
        }
}(window, window.lib || (window.lib = {}));

核心方法如下:

if (metaEl) {
    console.warn('将根据已有的meta标签来设置缩放比例');
    var match = metaEl.getAttribute('content').match(/initial-scale=([\d.]+)/);
    if (match) {
        scale = parseFloat(match[1]);
        dpr = parseInt(1 / scale);
    }
    //如果在meta标签中,我们手动配置了flexible,则使用里面的内容
} else if (flexibleEl) {
    var content = flexibleEl.getAttribute('content');
    if (content) {
        var initialDpr = content.match(/initial-dpr=([\d.]+)/);
        var maximumDpr = content.match(/maximum-dpr=([\d.]+)/);
        if (initialDpr) {
            dpr = parseFloat(initialDpr[1]);
           scale = parseFloat((1 / dpr).toFixed(2));
       }
       if (maximumDpr) {
           dpr = parseFloat(maximumDpr[1]);
           scale = parseFloat((1 / dpr).toFixed(2));
       }
   }
}

if (!dpr && !scale) {
    var isAndroid = window.navigator.appVersion.match(/android/gi);
    var isIPhone = window.navigator.appVersion.match(/iphone/gi);
    //devicePixelRatio这个属性是可以获取到设备的dpr的
    var devicePixelRatio = window.devicePixelRatio;
    if (isIPhone) {
        if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {
            dpr = 3;
        } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){
            dpr = 2;
        } else {
            dpr = 1;
        }
    } else {
        dpr = 1;
        // 其他设备仍旧使用1倍的方案
    }
    scale = 1 / dpr;
}

这里只对ios作了处理,android 仍采用了1倍的布局方案。

2. 另一种方案 hotcss.js
(function(window, document) {
    'use strict';
    //给hotcss开辟个命名空间,别问我为什么,我要给你准备你会用到的方法,免得用到的时候还要自己写。
    var hotcss = {};
    (function() {
        //根据devicePixelRatio自定计算scale
        //可以有效解决移动端1px这个世纪难题。
        var viewportEl = document.querySelector('meta[name="viewport"]'),
            hotcssEl = document.querySelector('meta[name="hotcss"]'),
            dpr = window.devicePixelRatio || 1,
            maxWidth = 540,
            designWidth = 0;
        dpr = dpr >= 3 ? 3 : (dpr >= 2 ? 2 : 1);
        //允许通过自定义name为hotcss的meta头,通过initial-dpr来强制定义页面缩放
        if (hotcssEl) {
            var hotcssCon = hotcssEl.getAttribute('content');
            if (hotcssCon) {
                var initialDprMatch = hotcssCon.match(/initial-dpr=([\d.]+)/);
                if (initialDprMatch) {
                    dpr = parseFloat(initialDprMatch[1]);
                }
                var maxWidthMatch = hotcssCon.match(/max-width=([\d.]+)/);
                if (maxWidthMatch) {
                    maxWidth = parseFloat(maxWidthMatch[1]);
                }
                var designWidthMatch = hotcssCon.match(/design-width=([\d.]+)/);
                if (designWidthMatch) {
                    designWidth = parseFloat(designWidthMatch[1]);
                }
            }
        }
        document.documentElement.setAttribute('data-dpr', dpr);
        hotcss.dpr = dpr;
        document.documentElement.setAttribute('max-width', maxWidth);
        hotcss.maxWidth = maxWidth;
        if (designWidth) {
            document.documentElement.setAttribute('design-width', designWidth);
            hotcss.designWidth = designWidth;
        }
        var scale = 1 / dpr,
            content = 'width=device-width, initial-scale=' + scale + ', minimum-scale=' + scale + ', maximum-scale=' + scale + ', user-scalable=no';
        if (viewportEl) {
            viewportEl.setAttribute('content', content);
        } else {
            viewportEl = document.createElement('meta');
            viewportEl.setAttribute('name', 'viewport');
            viewportEl.setAttribute('content', content);
            document.head.appendChild(viewportEl);
        }
    })();
    hotcss.px2rem = function(px, designWidth) {
        //预判你将会在JS中用到尺寸,特提供一个方法助你在JS中将px转为rem。就是这么贴心。
        if (!designWidth) {
            //如果你在JS中大量用到此方法,建议直接定义 hotcss.designWidth 来定义设计图尺寸;
            //否则可以在第二个参数告诉我你的设计图是多大。
            designWidth = parseInt(hotcss.designWidth, 10);
        }
        return parseInt(px, 10)  320 / designWidth / 20;
    }
    hotcss.rem2px = function(rem, designWidth) {
        //新增一个rem2px的方法。用法和px2rem一致。
        if (!designWidth) {
            designWidth = parseInt(hotcss.designWidth, 10);
        }
        //rem可能为小数,这里不再做处理了
        return rem  20  designWidth / 320;
    }
    hotcss.mresize = function() {
        //对,这个就是核心方法了,给HTML设置font-size。
        var innerWidth = document.documentElement.getBoundingClientRect().width || window.innerWidth;
        if (hotcss.maxWidth && (innerWidth / hotcss.dpr > hotcss.maxWidth)) {
            innerWidth = hotcss.maxWidth  hotcss.dpr;
        }
        if (!innerWidth) {
            return false;
        }
        document.documentElement.style.fontSize = (innerWidth * 20 / 320) + 'px';
        hotcss.callback && hotcss.callback();
    };
    hotcss.mresize();
    //直接调用一次
    window.addEventListener('resize', function() {
        clearTimeout(hotcss.tid);
        hotcss.tid = setTimeout(hotcss.mresize, 33);
    }, false);
    //绑定resize的时候调用
    window.addEventListener('load', hotcss.mresize, false);
    //防止不明原因的bug。load之后再调用一次。
    setTimeout(function() {
        hotcss.mresize();
        //防止某些机型怪异现象,异步再调用一次
    }, 333)
    window.hotcss = hotcss;
    //命名空间暴露给你,控制权交给你,想怎么调怎么调。
})(window, document);

里面有这样简单粗暴的设置:

dpr = dpr >= 3 ? 3 : ( dpr >=2 ? 2 : 1 );
3. 前端开发博客的方案

<span style="font-family: Arial, Helvetica, sans-serif;">动态写dpr和根元素的fontsize:  </span> 

!function(x) {  
    function w() {  
        var a = r.getBoundingClientRect().width;  
        a / v > 540 && (a = 540 * v), x.rem = a / 16, r.style.fontSize = x.rem + "px"  
    }  
    var v, u, t, s = x.document, r = s.documentElement, q = s.querySelector('meta[name="viewport"]');  
    if (q) {  
        console.warn("将根据已有的meta标签来设置缩放比例");  
        var o = q.getAttribute("content").match(/initial\-scale=(["‘]?)([\d\.]+)\1?/);  
        o && (u = parseFloat(o[2]), v = parseInt(1 / u))  
    }  
    if (!v && !u) {  
        var n = (x.navigator.appVersion.match(/android/gi), x.navigator.appVersion.match(/iphone/gi)), v = x.devicePixelRatio;  
        v = n ? v >= 3 ? 3 : v >= 2 ? 2 : 1 : 1, u = 1 / v  
    }  
    if (r.setAttribute("data-dpr", v), !q) {  
        if (q = s.createElement("meta"), q.setAttribute("name", "viewport"), q.setAttribute("content", "initial-scale=" + u + ", maximum-scale=" + u + ", minimum-scale=" + u + ", user-scalable=no"), r.firstElementChild) {  
            r.firstElementChild.appendChild(q)  
        } else {  
            var m = s.createElement("div");  
            m.appendChild(q), s.write(m.innerHTML)  
        }  
    }  
    x.dpr = v, x.addEventListener("resize", function() {  
        clearTimeout(t), t = setTimeout(w, 300)  
    }, !1), x.addEventListener("pageshow", function(b) {  
        b.persisted && (clearTimeout(t), t = setTimeout(w, 300))  
    }, !1), "complete" === s.readyState ? s.body.style.fontSize = 12 * v + "px" : s.addEventListener("DOMContentLoaded", function() {  
        s.body.style.fontSize = 12 * v + "px"  
    }, !1), w()  
}(window); 
4. 耿旭亮的方案

直接存为一个 viewport.js 文件,在所有js中最先引入该文件

!function(win, lib) {
    var timer,
        doc     = win.document,
        docElem = doc.documentElement,

        vpMeta   = doc.querySelector('meta[name="viewport"]'),
        flexMeta = doc.querySelector('meta[name="flexible"]'),
 
        dpr   = 0,
        scale = 0,
 
        flexible = lib.flexible || (lib.flexible = {});
 
    // 设置了 viewport meta
    if (vpMeta) {
 
        console.warn("将根据已有的meta标签来设置缩放比例");
        var initial = vpMeta.getAttribute("content").match(/initial\-scale=([\d\.]+)/);
 
        if (initial) {
            scale = parseFloat(initial[1]); // 已设置的 initialScale
            dpr = parseInt(1 / scale);      // 设备像素比 devicePixelRatio
        }
 
    }
    // 设置了 flexible Meta
    else if (flexMeta) {
        var flexMetaContent = flexMeta.getAttribute("content");
        if (flexMetaContent) {
 
            var initial = flexMetaContent.match(/initial\-dpr=([\d\.]+)/),
                maximum = flexMetaContent.match(/maximum\-dpr=([\d\.]+)/);
 
            if (initial) {
                dpr = parseFloat(initial[1]);
                scale = parseFloat((1 / dpr).toFixed(2));
            }
 
            if (maximum) {
                dpr = parseFloat(maximum[1]);
                scale = parseFloat((1 / dpr).toFixed(2));
            }
        }
    }
 
    // viewport 或 flexible
    // meta 均未设置
    if (!dpr && !scale) {
        // QST
        // 这里的 第一句有什么用 ?
        // 和 Android 有毛关系 ?
        var u = (win.navigator.appVersion.match(/android/gi), win.navigator.appVersion.match(/iphone/gi)),
            _dpr = win.devicePixelRatio;
 
        // 所以这里似乎是将所有 Android 设备都设置为 1 了
        dpr = u ? ( (_dpr >= 3 && (!dpr || dpr >= 3))
                        ? 3
                        : (_dpr >= 2 && (!dpr || dpr >= 2))
                            ? 2
                            : 1
                  )
                : 1;
 
        scale = 1 / dpr;
    }
 
    docElem.setAttribute("data-dpr", dpr);
 
    // 插入 viewport meta
    if (!vpMeta) {
        vpMeta = doc.createElement("meta");
         
        vpMeta.setAttribute("name", "viewport");
        vpMeta.setAttribute("content",
            "initial-scale=" + scale + ", maximum-scale=" + scale + ", minimum-scale=" + scale + ", user-scalable=no");
 
        if (docElem.firstElementChild) {
            docElem.firstElementChild.appendChild(vpMeta)
        } else {
            var div = doc.createElement("div");
            div.appendChild(vpMeta);
            doc.write(div.innerHTML);
        }
    }
 
    function setFontSize() {
        var winWidth = docElem.getBoundingClientRect().width;
 
        if (winWidth / dpr > 540) {
            (winWidth = 540 * dpr);
        }
 
        // 根节点 fontSize 根据宽度决定
        var baseSize = winWidth / 10;
 
        docElem.style.fontSize = baseSize + "px";
        flexible.rem = win.rem = baseSize;
    }
 
    // 调整窗口时重置
    win.addEventListener("resize", function() {
        clearTimeout(timer);
        timer = setTimeout(setFontSize, 300);
    }, false);
 
     
    // orientationchange 时也需要重算下吧
    win.addEventListener("orientationchange", function() {
        clearTimeout(timer);
        timer = setTimeout(setFontSize, 300);
    }, false);
 
 
    // pageshow
    // keyword: 倒退 缓存相关
    win.addEventListener("pageshow", function(e) {
        if (e.persisted) {
            clearTimeout(timer);
            timer = setTimeout(setFontSize, 300);
        }
    }, false);
 
    // 设置基准字体
    if ("complete" === doc.readyState) {
        doc.body.style.fontSize = 12 * dpr + "px";
    } else {
        doc.addEventListener("DOMContentLoaded", function() {
            doc.body.style.fontSize = 12 * dpr + "px";
        }, false);
    }
  
    setFontSize();
 
    flexible.dpr = win.dpr = dpr;
 
    flexible.refreshRem = setFontSize;
 
    flexible.rem2px = function(d) {
        var c = parseFloat(d) * this.rem;
        if ("string" == typeof d && d.match(/rem$/)) {
            c += "px";
        }
        return c;
    };
 
    flexible.px2rem = function(d) {
        var c = parseFloat(d) / this.rem;
         
        if ("string" == typeof d && d.match(/px$/)) {
            c += "rem";
        }
        return c;
    }
}(window, window.lib || (window.lib = {}));
移动端页面像素值的适配问题的几种处理方式 移动端页面像素值适配问题的几种处理方式 移动端机型巨多,各种屏幕分辨率,眼花缭乱!作为前端开发,样式的适配性也显得非常重要!那么。今天,就说说我在之前h5开发过程中,对于像素值的适配问题的几种解决方法 ... 阅读详情

相关推荐

[前端]Web前端-移动端开发知识点及常用适配方案

文章目录一、前端开发常用单位1.像素(Pixel)2.百分比3.em4.rem5.vw(Viewport Width)和vh(Viewport Height)二、视口三、设备像素和CSS像素1.什么是设备像素和CSS像素?2.如何解决设备像素和CSS像素不一样的问题?3.获取设备像素比DPR(Device Pixel Ratio)四、常用移动端适配方案1.通过media媒体查询2.通过media媒体查询+rem3.通过JS+rem4移动端开发适配方案之终极方案相关文献 一、前端开发常用单位 1.像素(Pix

deathz15的博客 2314

移动端页面开发适配 rem布局原理

我们拿到的设计图一般是以640,750,1080分辨率为基准设计的,而现在的手机终端各式各样,分辨率不同,逻辑像素不同 ,适口不同,所以为了让我们的页面在每个设备上都可以良好的展示,那么就需要为这些设备做统一的处理,这个过程就称为移动端适配。需要知道的一些概念:物理像素(physical pixel)一个物理像素是显示器(手机屏幕)上最小的物理显示单元,可以理解为我们平时说的分辨率;设备独立像素(density-independent pixel)

风中追风 4991

web前端开发html5+css3(入门学习笔记)(day20)flex弹性盒的简介、弹性容器的样式、弹性元素的样式、像素、移动端像素、移动端页面、视口、vw适配、响应式布局、媒体查询

flex弹性盒的简介、弹性容器的样式、弹性元素的样式、像素、移动端像素、移动端页面、视口、vw适配、响应式布局、媒体查询

weixin_44647089的博客 392

使用Flexible实现手淘H5页面的终端适配

使用Flexible实现手淘H5页面的终端适配 曾几何时为了兼容IE低版本浏览器而头痛,以为到Mobile时代可以跟这些麻烦说拜拜。可没想到到了移动时代,为了处理各终端的适配而乱了手脚。对于混迹各社区的偶,时常发现大家拿手机淘宝的H5页面做讨论——手淘的H5页面是如何实现多终端的适配? 那么趁此Amfe阿里无线前端团队双11技术连载之际,用一个实战案例来告诉大家...

weixin_30337157的博客 1351

2020年史上最全移动端Web整理从开发基础到实战(一)

一、基础知识 1、屏幕 移动设备与PC设备最大的差异在于屏幕,这主要体现在屏幕尺寸和屏幕分辨率两个方面。 通常我们所指的屏幕尺寸,实际上指的是屏幕对角线的长度(一般用英寸来度量)。 而分辨率则一般用像素来度量 px,表示屏幕水平和垂直方向的像素数,例如 1920*1080 指的是屏幕垂直方向和水平方向分别有1920和1080个像素点而构成。 2、长度单位 在Web开发中可以使用px(像素)、em...

weixin_45992710的博客 511

5分钟搞定!用Keil MDK将STM32F103C8T6工程无缝迁移到ZET6开发板

本文详细介绍了如何在Keil MDK环境下快速将STM32F103C8T6工程迁移到ZET6开发板,涵盖硬件差异对比、工程配置调整、外设适配及编译排错等关键步骤,帮助开发者5分钟内完成工程移植,大幅提升开发效率。

weixin_30879169的博客 409

移动端页面适配方案

获取布局视口的宽度:document.documentElement.clientWidth 获取设备css像素(屏幕尺寸):window.screen.width <meta name=”viewport” content=”width=device-width, initial-scale=1, maximum-scale=1″> width:控制 layout viewport 的大小,可以指定的一个值,如 600,或者特殊的值,如 device-width 为设备的宽度(单位为缩放为

weixin_42114053的博客 1489

逆变器技术解析:DDSRF双解耦在正负序分离中的关键作用

本文深入解析了DDSRF双解耦技术在逆变器正负序分离中的关键作用。通过建立正反旋转坐标系并利用交叉反馈解耦网络,DDSRF能快速、精准地分离电网电压中的正负序分量,从而显著提升锁相环在电网不平衡条件下的精度与系统稳定性,是现代高性能并网逆变器的核心算法之一。

m3n5b7v8c9x的博客 411

前端开发移动端适配(保姆级)

web前端开发进行移动端适配

linyuzhizou的博客 1042

基于Python的携程景点评价爬虫与情感评分分析

摘要: 本项目通过Python技术栈实现携程景点评论的情感分析系统,包含数据爬取、文本预处理、情感评分和可视化分析全流程。使用requests抓取评论接口,jieba进行中文分词,SnowNLP计算情感得分(0-1),并通过词云、情感分布图呈现结果。典型分析显示72%评论为正面,负面反馈多涉及"排队久""票价贵"等问题。系统可辅助景点口碑管理,扩展方向包括多景点对比、BERT模型优化等。项目强调需遵守爬虫伦理,控制请求频率,适用于非商业用途的旅游数据分析。(150字)

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 978

Jetson Orin NX上CAN总线调试全攻略:从硬件焊接到开机自启动(附常见问题解决方案)

本文详细介绍了在NVIDIA Jetson Orin NX开发板上进行CAN总线调试的全过程,包括硬件焊接、驱动配置、通信测试和开机自启动设置。针对常见问题如信号接反、波特率设置等提供了实用解决方案,帮助开发者快速实现稳定的CAN总线通信。

c2d3e4f的博客 1076

移动web开发相关知识 物理像素、逻辑像素、设备像素比、移动端常见布局、布局视口、视觉视口、理想视口

在Web开发中可以使用px(像素)、em、pt(点)、in(英寸)、cm(厘米)做为长度单位,我们最常用px(像素)做为长度单位 一、物理像素 物理像素指的是屏幕渲染图像的最小单位,属于屏幕的物理属性,不可人为进行改变,其值大小决定了屏幕渲染图像的品质。 手机屏幕横向有828个点 手机屏幕纵向上有1792个点 同等大小屏幕下,点越多、图像显示越精细 上面所说屏幕上一个个点就是物理像素(physi...

欢迎来到我的博客 1224

手把手教你用STM32的SPI驱动MCP2517FD实现CAN FD通信(附完整代码)

本文详细介绍了如何使用STM32通过SPI驱动MCP2517FD实现CAN FD通信,涵盖硬件连接、SPI驱动编写、寄存器配置及数据收发实战。提供完整代码示例和常见问题排查指南,帮助开发者快速构建高可靠性的CAN FD通信系统,适用于汽车电子和工业控制等领域。

weixin_30607029的博客 676

H5移动端适配(1)

比如一张图片的分辨率是800*400,这表示图片的垂直和水平上具有的像素点分别是800和400。理论上来讲,在A手机上相同大小的图片和文字,在B手机上会被缩放一倍,因为它的分辨率提高了一倍。这里的点是一个抽象的单位,它可以是屏幕像素点、图片像素点也可以是打印机的墨点。然而,事实并不是这样的,我们现在使用的智能手机,不管分辨率多高,他们所展示的界面比例都是基本类似的。但是,随着科技的发展,低分辨率的手机已经不能满足我们的需求了。(视网膜屏幕)的概念,它正是解决了上面的问题,这也使它成为一款跨时代的手机。

jdpopdmy的博客 1223

PCIe 6.0 – 关于 PCI Express Gen6 您需要知道的一切

幸运的是,PCIe 6.0 FEC 足够轻,对延迟的影响最小。在电气层上,PCIe 6.0 使用 PAM4 信号(“四级脉冲幅度调制”),每个时钟周期将 2 位组合为 4 个幅度级别(00、01、10、11),与 PCIe 5.0 和前几代相比,它使用 NRZ 调制,每个时钟周期 1 位和两个幅度级别 (0, 1)。虽然 PAM4 信号更容易出错,但由于调制技术的性质,与 PCIe 5.0 相比,通道损耗不受影响,因此 PCB 上 PCIe 6.0 信号的范围将与 PCIe 5.0 相同。

qq_43416206的博客 3433

【Claude】权限被拒绝 (Permission Denied) 全场景排查 — 已解决

权限配置是 Claude Code 安全使用的核心机制。通过合理的 allow/deny 规则、正确的通配符使用、子代理独立配置、定期安全审计,可以在保证安全性的同时不影响开发效率。deny 优先:deny 规则优先级高于 allow,先保护敏感资源通配符精确单层匹配,**递归匹配,Bash(cmd*)允许带参数最小权限:只允许必要的操作,避免Bash(*)等危险规则CI 用 skip:Headless 模式用避免挂起子代理独立:每个子代理单独配置权限,不自动继承保护密钥:deny.env。

一键难忘的博客 3946

移动web开发入门

学习目标 移动web开发基础概念:像素 、视口-viewport 移动web开发基础知识:box-sizing、图标字体、flex布局、媒体查询、移动端常用单位 响应式布局 移动端屏幕适配 移动端事件 移动端调试 终端检测 移动端常见问题 移动端性能优化 基本概念: 一、像素 分辨率:分辨率越高,越清晰;如1792*828像素分辨率,竖着分为1792个点的物理像素,横着分为828个点的物理像素 物理像素(实际开发中不用):与设备有关,不可改变;也称设备像素 css像素:也称逻辑像素和设备独立像素 .bo

weixin_47204963的博客 321

Transformer从菜鸟到新手(一)

从本文开始回顾一下Transformer的原理与实现细节,包括分词算法BPE的实现。最终利用从零实现的Transformer模型进行英中翻译。

日积月累,天道酬勤 2125

移动WEB的硬知识

一、概述 APP开发目前有三种趋势,一种是原生APP,一种是网页APP,还有一种是H5APP。 移动web开发: 跑在我们手机端的web页面,(H5页面) 跨平台 基于webview 告别IE,拥抱webkit,兼容性问题不用担心 更高的适配性,和性能要求 由于是基于webview,所以可以跨平台,不论是android还是ios,都能很好的呈现。webview可以理解为是我们的移动web页面...

weixin_34269583的博客 214

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

.net移动端开发_移动端开发(web app) 之移动端布局

作者:RickyLong出处:https://segmentfault.com/a/1190000019241607App 分类如上图, Native app 是使用原生开发的 app, 优点是性能更好,还能调用系统的 api ,但是发布 app 流程繁琐,而且不跨平台。而 Web app , 优点是跨平台,修改方便,缺点是不能调用原生的 api, 而且用户体验不如原生 app, 好。而 Hybr...

weixin_42108948的博客 888

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

对移动端使用rem实现适配

我们要了解几个概念:CSS像素、设备像素、逻辑像素、设备像素比、PPI、Viewport; 视口设置 <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no" /> 通过js代码设置移动端适配 可通过j...

misterHao的博客 383

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

3-移动端Web

移动端Web 移动端 兼容移动端主流浏览器,处理Webkit内核浏览器即可. 我们现状开发的移动端主要针对手机端开发 现在移动端碎片化严重,分辨率和屏幕尺寸大小不一 学会用谷歌浏览器模拟手机界面及调试 视口 viewport 布局视口 layout viewpor 早期用于解决pc端网页在手机上显示的问题 但是移动端将pc端的视口分辨率设置为980px,相对手机屏幕看上去很小. 视觉视口 ...

qq_45754486的博客 226

移动端的一些基础知识

一、设备像素比 缩写简称dpr,也就是我们经常在谷歌控制台移动端调试顶端会看到的一个值。设备像素比 = 设备像素 / css像素(垂直方向或水平方向)。 可以通过JS来获取: window.devicePixelRatio // 在iPhoneX上,3 ...

sak1sm的笔记 439

移动web的适配

我在另一篇文章中谈到过一些移动端分辨率自适应问题,主要是基于个人实际开发中遇到的问题提出的解决方法。 近期有幸听到他人对移动web开发的分享,特来补充上一篇文章,向大神讨教。 Part 1 理解关于长度单位的一些概念 1、设备像素或逻辑像素 指设备能控制显示的最小物理单位,意指屏幕上一个个的点 (还是不理解??太正常了,接着往下看) 2、CSS像素或设备独立像素 指CSS样式代码中使用的逻辑像素...

Joy_Yue的博客 8654

(一)移动端 Web 开发基础

文章目录一、移动 Web 开发基础概念1. 像素(1) 分辨率(2) 物理像素(3) CSS 像素(4) 设备像素比(5) 标清屏和高清屏(6) 缩放(7) PPI / DPI2. 视口 viewport二、移动 Web 开发基础知识1. box-sizing2. 图标字体3. flex 布局(1) 什么是 flex 布局(2) flex 布局的基本概念(3) flex 容器的属性(4) flex 项目的属性4. 媒体查询(1) 什么是媒体查询(media query)(2) 为什么需要媒体查询(3) 媒体

weixin_46227563的博客 2721

移动网站适配

对于物理像素,设备独立像素,设备像素比,css像素,布局视口,可视视口,理想视口的概念了解参考 我对移动端适配的了解 移动WEB开发之-流式布局 关于移动端适配,你必需要知道的 各种视口和js中API的对应关系为: 屏幕分辨率:screen.width 布局视口:document.documentElement.clientWidth 视觉视口:window.innerWidth 理想视口:screen.width 设备像素比:window.devicePixelRatio 屏幕方向:window.or

Wind_waving的博客 548
上一篇: Webstorm下配置autoprefixer插件(css兼容代码)
下一篇: 微信跨域&分享
AmberQu
博客等级 码龄9年 1粉丝 9原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值