Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

移动端适配之remjs vw vh #64

Open
Lenny-Hu opened this issue Jul 5, 2019 · 5 comments
Open

移动端适配之remjs vw vh #64

Lenny-Hu opened this issue Jul 5, 2019 · 5 comments

Comments

@Lenny-Hu
Copy link
Owner Author

Lenny-Hu commented Jul 9, 2019

为什么移动端设计稿总是640px和750px?

在我开始写移动端页面至今,一直有2个疑问困扰着我,我只知道结果但不知道为什么

  问题1:为什么设计师给的设计稿总是640px或750px(现在一般以Phone6为基准,给的750px)

  问题2:为什么我们拿到640px和750px的设计稿,在编码的时候都要除以2,

     (比如设计稿上有一个图标宽高是4040,我们需要先除以2,实际编码时候宽高要写成2020)


结论:pt和px的关系就是—— 1pt 里面有几个像素点

    (比如 1pt里面有1个px,也可以有2个,3个,分别对应上图的@1x,@2x,@3x

  下图的Reader就是反应它们之间的比例,即 pt 和 px为1:2

  还是拿iPhone6举例,下图 pt 宽高是375667,px 宽高是7501334,px的宽高是pt的2倍。

1033257-20180906100351775-1261095461

  所以这里的Reader关系是@2x,也就是2倍

  所以为什么设计稿640px和750px要除以2,就是因为设计师给的640px和750px是物理像素

  而我们在浏览器模拟调试移动端的时候看到的像素是逻辑像素


https://www.cnblogs.com/tu-0718/p/9596894.html

H5案例分享:Retina显示屏-揭秘移动端的视觉稿通常会设计为传统PC的2倍

h5页面设计稿640下20px,逻辑像素就是10px的字体

@Lenny-Hu
Copy link
Owner Author

Lenny-Hu commented Aug 7, 2019

**使用vw + rem布局 **

mixin代码文件


/* 移动端页面设计稿宽度 */
$design-width: 640;
/* 移动端页面设计稿dpr基准值 */
$design-dpr: 2;
/* 将移动端页面分为10块 */
$blocks: 10;
/* 缩放所支持的设备最小宽度 */
$min-device-width: 320px;
/* 缩放所支持的设备最大宽度 */
$max-device-width: 640px;

// 公共
@mixin bg-image($url, $width, $height) {
  background-image: url("/" + $url + "@2x.png");
  background-size: $width $height;
  background-repeat: no-repeat;
}

/* html根元素的font-size定义,简单地将页面分为$blocks块,方便计算 */
/* 当移动端X方向宽度在320-640px之间时,html 的fontsize使用的单位才是vw */
@mixin root-font-size() {
	font-size: 100vw / $blocks;

	body {
			@include container-min-width();
	}

	/* 最小宽度定义:这时候html的fontsize 为 16px */
	@media screen and (max-width: $min-device-width) {
			font-size: $min-device-width / $blocks;
	}

	/* 最大宽度定义:这时候html的fontsize 为 64px  */
	& {
			body {
					@include container-max-width();
			}

			@media screen and (min-width: $max-device-width) {
					font-size: $max-device-width / $blocks;
			}
	}
}

@function strip-units($number){
  @return $number / ($number * 0 + 1);
}

/* 单位px转化为rem */
@function px2rem($px) {
  @return #{strip-units($px) / $design-width * $design-dpr * $blocks}rem;
}

/* 适用于相对于版心容器转换 */
@function px2remByBox($px, $box-width: $center-width) {
  @return #{strip-units($px) / $box-width * $design-dpr * $blocks}rem;
}

/* 百分比转换 */
@function px2per($px, $box-width: $center-width) {
  @return #{strip-units($px) / $box-width * 100%};
}

/* 设置容器拉伸的最小宽度 */
@mixin container-min-width() {
	margin-right: auto;
	margin-left: auto;
	min-width: $min-device-width;
}

/* 设置容器拉伸的最大宽度 */
@mixin container-max-width() {
	margin-right: auto;
	margin-left: auto;
	max-width: $max-device-width;
}

@for $var from 12 to 60 {
  .f-fs-#{$var} {
    font-size: px2rem($var);
	}
	.f-lh-#{$var} {
		line-height: px2rem($var);
	}
}

$colorList: '000', 'fff', 'ccc', '009754', 'FF6000', '5D4646', 'FF5050', '2DBE7F', '607FD9', 'F137E6', '272727', 'FF2C4F', '232323', '004728', '006438', 'FF392A', 'ECECEC', '1E7459', 'FF476A';
@each $var in $colorList {
  .s-fc-#{$var} {
    color: unquote('##{$var}');
  }
  .s-bgc-#{$var} {
    background-color: unquote('##{$var}');
  }
}

// 重置
* {
  box-sizing: border-box;
}

img {
  max-width: 100%;
  height: auto;
}

/* function */
.f-cb:after,.f-cbli li:after{display:block;clear:both;visibility:hidden;height:0;overflow:hidden;content:".";}
.f-cb,.f-cbli li{zoom:1;}
.f-ib{display:inline-block;*display:inline;*zoom:1;}
.f-dn{display:none;}
.f-db{display:block;}
.f-fl{float:left;}
.f-fr{float:right;}
.f-pr{position:relative;}
.f-prz{position:relative;zoom:1;}
.f-oh{overflow:hidden;}
.f-ff0{font-family:arial,\5b8b\4f53;}
.f-ff1{font-family:"Microsoft YaHei",\5fae\8f6f\96c5\9ed1,arial,\5b8b\4f53;}
.f-fs1{font-size:12px;}
.f-fs2{font-size:14px;}
.f-fwn{font-weight:normal;}
.f-fwb{font-weight:bold;}
.f-tal{text-align:left;}
.f-tac{text-align:center;}
.f-tar{text-align:right;}
.f-taj{text-align:justify;text-justify:inter-ideograph;}
.f-vam,.f-vama *{vertical-align:middle;}
.f-wsn{word-wrap:normal;white-space:nowrap;}
.f-pre{overflow:hidden;text-align:left;white-space:pre-wrap;word-wrap:break-word;word-break:break-all;}
.f-wwb{white-space:normal;word-wrap:break-word;word-break:break-all;}
.f-ti{overflow:hidden;text-indent:-30000px;}
.f-ti2{text-indent:2em;}
.f-lhn{line-height:normal;}
.f-tdu,.f-tdu:hover{text-decoration:underline;}
.f-tdn,.f-tdn:hover{text-decoration:none;}
.f-toe{overflow:hidden;word-wrap:normal;white-space:nowrap;text-overflow:ellipsis;}
.f-csp{cursor:pointer;}
.f-csd{cursor:default;}
.f-csh{cursor:help;}
.f-csm{cursor:move;}
.f-usn{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none;}

// 组件样式
.m-dialog-box,
.m-loading-box {
	display: flex;
	align-items: center;
	justify-content: center;
	position: fixed;
	top: 0;
	right: 0;
	bottom: 0;
	left: 0;
	z-index: 1050;
	background: rgba(0, 0, 0, 0.5);
}

.m-dialog-body {
	position: relative;

	.close {
		position: absolute;
		right: px2rem(5);
		top: - px2rem(46);
		width: px2rem(42);
		height: px2rem(42);
		@include bg-image('close', px2rem(42), px2rem(42));
		background-position: center;
		background-repeat: no-repeat;
	}
}

.m-loading-inner {
	border-radius: px2rem(8);
	padding: px2rem(14);

	.img-box {
		margin-bottom: px2rem(4); 
	}
}

.m-no-data {
	display: block;
	width: 100%;
	opacity: 0.8;
}

在一些pc到移动端的自适应中,可能整体缩小在移动端字体会很小,有2种方法可以处理:

  1. 使用媒体查询,然后用px2remByBox覆盖一遍尺寸定义,缺点是得多写一遍,例如:
.a {
  width: px2rem(100);
  font-size: px2rem(20);

 $box: 700;

  @media screen and (max-width: 768px) {
    width: px2remByBox(100, $box);
    font-size: px2remByBox(20, $box);
  }
}
  1. 有的地方使用em为单位,在小屏幕下使用媒体查询控制字体就行。例如:
$fs: 20; // 最小的字体,移动端最小显示为12px。
@function px2em ($px, $_fs: $fs) {
  @return #{$px / $_fs}em;
}
// 按比例设置最小字体,小屏幕最小设置为12px字体
@function getminfs ($target, $base: $fs) {
  @return #{round(12 / $base * $target)}px;
}
@mixin mobile-screen($width: 768px)
{
  @media screen and (max-width: $width)
  {
    @content;
  }
}
// 设置最小字体
@mixin minFontSize ($size: 12px) {
  @include mobile-screen () {
    font-size: $size;
  }
}

font-size: px2rem($fs);
@include minFontSize;

.a {
  padding: px2em(50, 26) 0 0;
  font-size: px2rem(26); // 这是为了适应pc-768px之间的屏幕

  @include minFontSize(getminfs(26)); // 按比例缩小的字体,20px的字在小屏幕显示为12px,那么26px的字相对于这个比例
}

@Lenny-Hu
Copy link
Owner Author

关于移动端rem与px换算的计算方式

https://blog.csdn.net/daimomo000/article/details/81610178

@Lenny-Hu
Copy link
Owner Author

Lenny-Hu commented Mar 16, 2020

腾讯新闻所用的JS计算html节点的fontsize

https://xw.qq.com

(function(base, min, max, scaling){
  var cacheWidth = 0;
  var timer;
  var docEl = document.documentElement;
  var resizeEvt = 'onorientationchange' in window ? 'orientationchange' : 'resize';
  var recalc = function () {
    var clientWidth = docEl.clientWidth;
    if (!clientWidth) return;
    clientWidth = Math.min(clientWidth, max);
    clientWidth = Math.max(clientWidth, min);
    if(cacheWidth !== clientWidth) {
      clearInterval(timer);
      cacheWidth = clientWidth;
      docEl.style.fontSize = scaling * (clientWidth / base) + 'px';
    }
  }
  if (!document.addEventListener) return;
  window.addEventListener(resizeEvt, function() {
    timer = setInterval(recalc, 10);
  });
  recalc();
})(375, 300, 768, 100);

其设计图为 750,尺寸计算公式为 1rem = 100px, 3.75rem = 375px,sass计算函数如下

// 移除单位
@function strip-units($number){
  @return $number / ($number * 0 + 1);
}

/* 单位px转化为rem */
@function px2rem($px) {
  @return #{strip-units($px) / 2 / 100}rem; // 如果设计图已经按375标注了,无需除以2
}

@Lenny-Hu
Copy link
Owner Author

Lenny-Hu commented May 7, 2020

利用viewport,适配各种屏幕

使用px写各种尺寸,利用js动态设置mete的viewport来达到适配的效果

(function () {
	var phoneScale = parseInt(window.screen.width) / 375;
	document.querySelector('meta[name="viewport"]').setAttribute('content', 'width=375, minimum-scale=' + phoneScale + ', maximum-scale=' + phoneScale + ', user-scalable=no');
})();

利用该方法可以使网页自动缩放,达到简单粗暴的适配效果,可能存在以下问题:

  • 竖屏切换横屏的时候页面会被明显放大
  • Android webview来说,就是个坑,需要在Android App中配置支持
  • 这种方法是不支持响应式的,因为媒体查询的width指的是布局视口
  • 如果把这个网站封装一个壳做成web APP就不能自适应

参考资源 https://www.zhihu.com/question/32198592

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant