Skip to content
New issue

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

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

Already on GitHub? # 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

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

No branches or pull requests

1 participant