整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

又一个布局利器,CSS 伪类 :placeholder-shown

般我们常见placeholder伪类选择器用来修改默认样式及文案,忽然发现placeholder-shown伪类选择器,比较官方的解释是

CSS伪类表示任何显示占位符文本的form元素。

简单来说就是当输入框的placeholder内容显示的时候,输入框干嘛干嘛。

兼容性如下,在移动端没什么问题

placeholder-show是如何工作的?

:placeholder-shown CSS 伪类 在 <input> 或 <textarea> 元素显示 placeholder text 时生效,简单的说就是 placeholder 有值才生效,如下所示:

// html
<input placeholder="placeholder text" />
<textarea placeholder="placeholder text"></textarea>

// css 
input:placeholder-shown, textarea:placeholder-shown{ 
  border:1px solid pink;
}

如果 placeholder 为空 placeholder-show 就没效果了:

// html
<input placeholder="" />
<textarea placeholder=" text"></textarea>

:placeholder-shown vs ::placeholder

我们可以使用:placeholder-shown设置input元素的样式。

input:placeholder-shown {
  border: 1px solid pink;
  background: yellow;
  color: green;
}

注意一些奇怪的问题-我们设置 color: green,但没有作用用。这是因为:placeholder-shown仅会针对input本身。对于实际的占位符文本,必须使用伪元素::placeholder。

input::placeholder {
  color: green;
}

⚠️ 我注意到有一些其他的属性,如果应用::placeholder-shown,也会影响placeholder的样式。

input:placeholder-shown, textarea:placeholder-shown{ 
  font-style: italic;
  text-transform: uppercase;
  letter-spacing: 5px;
}

我也不知道这是啥情况,也许是因为这些属性被placeholder继承了,如果你知道原因,欢迎留言告诉我一下,谢谢。

:placeholder-shown vs :empty

:placeholder-shown是专门用于确定元素是否显示占位符的对象,我们主要使用它来检查input 内容是否为空(假设所有的input都有一个占位符)。这里你可能会想,使用 empty 也是可以的吧?我们来看看。

// html
<input value="not empty">
<input><!-- empty -->

// css
input:empty {
  border: 1px solid pink;
}

input {
  border: 1px solid black;
}

这里看似empty起作用了,因为我们看到的是粉红色边框,但这实际上不起作用

之所以显示粉红色,是因为伪类增加了 css 的权重。类似于类选择器(即.form-input)比类型选择器(即input)具有更高的权重。高权限选择器将始终覆盖低权重设置的样式。

所以我们可以这样说:不要使用:empty检查输入元素是否为空。

如果检查 input 内容是否为空(在没有点位符的情况下)?

我们检查输入是否为空的唯一方法是使用:placeholder-shown。但是如果我们的输入元素没有占位符会发生什么呢? 这里有个取巧的方法:传入一个空字符串" "。

// html
<input placeholder=" "><!--  pass empty string -->

//css
input:placeholder-shown {
  border-color: pink;
}

组合其它选择器

我们可以使用:not伪类对某些事物进行逆运算。在这里,我们可以在输入不是空的情况下进行定位。

//html
<input placeholder="placeholder" value="not empty" />

// css
input:not(:placeholder-shown) {
  border: 1px solid green;
}

实战

用placeholder-shown我们可以实现下面动效

具体代码如下:

Html

<div class="input">
    <input class="input-fill" placeholder="邮箱">
    <label class="input-label">邮箱</label>
</div>

Css

.input{
   position: relative;
 }
.input-fill{
  border: 1px solid #ececec;
  outline: none;
  padding: 13px 16px 13px;
  font-size: 16px;
  line-height: 1.5;
  width: fit-content;
  border-radius: 5px;
}
.input-fill:placeholder-shown::placeholder {
  color: transparent;
}
.input-label {
  position: absolute;
  font-size: 16px;
  line-height: 1.5;
  left: 16px; top: 14px;
  color: #a2a9b6;
  padding: 0 2px;
  transform-origin: 0 0;
  pointer-events: none;
  transition: all .25s;
}
.input-fill:focus{
  border: 1px solid #2486ff;
}
.input-fill:not(:placeholder-shown) ~ .input-label,
.input-fill:focus ~ .input-label {
  transform: scale(0.75) translate(0, -32px);
  background-color: #fff;
  color: #2486ff;
}

作者:Samantha Ming 译者:前端小智 来源:medium 原文:https://www.samanthaming.com/tidbits/88-css-placeholder-shown/

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录页面</title>
    /*总体的样式*/
    <style>
    	/*盒子样式*/
        #box{
            width: 350px; //宽
            height: 450px; //高
            border: 1px solid black; //边框
            border-radius: 10px; //边框弧度
            font-family: 黑体; //字体
            letter-spacing:8px; //段间距
            word-spacing: 10px; //字间距
            line-height: 40px; //行高
            font-size: 18px; //字大小
            padding: 20px; //内边框
        }
        /*给'注册'赋予样式*/
        .register{
            width:280px ; //宽
            height: 50px; //高
            background-color: skyblue; //背景颜色
            border-radius: 10px; //边框弧度

        }
        /*将所有边框都改变*/
        *{
            border-radius: 5px; 边框弧度
        }
        /*使用class选择器,赋予number宽高和边框*/
        .number{
            width: 185px; //宽
            height: 27px; //高
            border-width: 1px; //边框宽度

        }
        /*id选择器*/
        #two{
            width: 55px; //宽
            border-width: 1px; 边框宽度
        }
        /*id选择器*/
        #phone{
            width: 103px; //宽
        }
        /*class 选择器*/
        .boxs{
            zoom: 75%; //清除浮动
            color: darkgray; //颜色
        }
        /*class选择器*/
        .box_a{
            width: 50px; //宽
            height: 50px; //高
            background-image: url("../image/04.jpg "); //背景图片
            background-repeat: no-repeat; // 是否平铺
            background-size: 50px 25px; //背景尺寸
            position: relative; //定位 相对定位
            left: 310px; //定位后左移
            bottom: 32px; //定位后下移

        }
    </style>
</head>
<body>
<div id="box">
    <h1>请注册</h1>
<p style="color: darkgray">已有帐号?<a href="https://im.qq.com/index">登录</a></p>
<form action="" method="post">
    <label for="name">用户名</label>
    <input type="text" placeholder="请输入用户名" id="name" class="number"> <br>
    <label for="phone">手机号</label>
    <select name="" id="two" class="number">
    <optgroup>
        <option style="" class="">+86</option>
    </optgroup>
    </select>
    <input type="text" placeholder="请输入手机号" id="phone" class="number"> <br>
    <label for="mima">密 码</label>
    <input type="password" placeholder="请输入密码" id="mima" class="number"> <br>
    <label for="mima">验证码</label>
    <input type="password" placeholder="请输入验证码" id="is" class="number">
    <div class="box_a"></div>
    <div class="boxs">
        <input type="radio" id="" class="accept">阅读并接受协议<br>
    </div>
    <input type="submit" value="注册" class="register" >

    </form>
</div>


</body>
</html>
在这里插入图片描述

为一个产品经理,学习并掌握基础的技术知识是非常重要的。而本篇文章就重点讨论前端部分,讲一讲HTML和CSS、JavaScript的知识要点。

为什么学习技术?我想上面这段话给予了非常好的解释。

在当今时代,职能划分越来越精细,但你仍然可以看到不同行业、领域、职业都密不可分,他们互相融合和渗透。设计和技术亦是如此,产品经理和程序员亦是如此。

不难发现,成功的产品经理有一个共性,那就是在精通设计与用户体验的基础上,精通技术或者如何运用技术。前者如张小龙,后者如乔布斯。

这并非偶然,而是因为技术和设计原本就是一体的:设计使用当下的技术来解决问题,因此设计中就包含了对技术的考量与使用。

你可能会说,作为一个执行层的产品,并不需要了解这些宏观的问题。你可能还会说,在技术如此成熟的当下,产品可以尽情发挥想象或者直接套用现有设计模式。

可是事实表明,在微观层面设计和技术达成共识可以显著提升合作质量和效率,这也正是各个平台(不管是安卓、iOS,还是小程序、网站)推出设计/开发规范的原因;另一方面,只有深谙设计模式及其背后的技术基础,才能打破模式、迸发创意。

在学习技术的同时,我刚好在看交互设计精髓这本书。书中提到了设计可以分为对内容、形态、行为的设计。我惊喜地发现这些设计领域刚好可以对应一些技术语言或实现方案,例如HTML、CSS、JS,又例如MVC(一种开发模式,下篇文章会提及)。

所以对产品经理而言,学习技术可以帮助你更好地理解产品设计,更好地执行产品工作,更加顺畅地与开发人员合作。

最初我学习技术的动机来自于想写一份好的PRD(我的一篇专栏文章讲述了这个主题,详见文章底部的参考资料),为此,我需要知道前端、后端分别想从需求文档中获取哪些信息以及他们会如何利用这些信息进行开发。

由此出发,我看了三本书,分别介绍了HTML和CSS、JavaScript、Python这些编程语言在前端开发、后端开发中的应用。

在这里,简单总结一下这些书中提及的技术原理,并结合自己的思考和实践指出这些技术原理在产品工作中的应用,希望可以对自己以及他人有所帮助。

由于内容较多,这篇文章将重点讨论前端部分,涉及HTML和CSS、JavaScript的内容;关于后端的内容,将在下一篇文章中分享。

下面将分别介绍一下HTML、CSS、JavaScript在web前端开发中的应用。

一、HTML

1.1 简介

HTML翻译作“超文本标记语言”,和现在广为使用的markdown一样,作为一种标记语言,HTML通过一套既定的语法来标记文本或者富文本内容,从而为这些内容划定结构。

这些HTML格式的文件通常存储在服务器上,浏览器通过互联网向服务器请求这些页面资源,然后解析并呈现出用户直接看到的页面。

1.2 HTML元素

在浏览器中打开任意web页面,并检查其HTML元素,都可以看到其大体的结构:

<head>元素存放网页的基本信息,<body>元素里的内容就是用户将在浏览器看到的东西,此外还有许许多多的元素(如:<h>、<p>、<a>、<img>、<div>、<li>、<div>)嵌套起来,共同构建了网页的结构。

这些元素一般由开始标记、结束标记、内容、属性等部分构成,其中“属性”可以帮助对这些元素进行更加具体的描述。

举例说明:标题元素的写法如下,<h1></h1>为开始和结束标记,中间包围的即为标题元素的内容。

<h1>这里是标题</h1>

表单元素的常见写法如下,其中<form>为开始标记,有action 和method两个属性,</form>为结束标记,省略号的位置放置表单元素包围的所有内容和输入控件。

<form action="http://123.com/test.py" method="POST"> ... </form>

1.3 如何定位HTML页面

在同一网站内部,可以通过在<a>元素中使用相对资源路径链接到一个新的页面。

在网站之外,则可以使用URL(统一资源定位符,用文件地址来标识web上的任何资源),通过绝对路径直接向服务器请求页面资源。

URL的结构通常如下:通信协议(http、https、file等)、服务器名(常见的www)、域名(服务器IP地址的简便记法)、资源的绝对路径、随URL传递的参数。

1.4 产品工作中的应用

我们设计出一个页面,页面上每一个元素(包括控件、信息、图片)都由HTML元素(例如<input>、<p>、<img>)来定义或者说实现。

这些页面控件、信息、图片的属性同样可以由HTML元素属性来实现,例如通过设置placeholder属性值,可以为输入框加入提示文案,通过设置draggable属性,让元素可以拖动。

在页面结构层面了解设计与技术的关联,可以帮助从技术的角度撰写产品方案。

(1)一方面,知道了技术会把页面结构拆解为元素及其属性,我们在写文档时,也应当以这种思路拆解并描述页面,写清楚页面有哪些信息,哪些输入控件,哪些显示控件,这些控件的属性是否需要自定义,还是直接使用浏览器或操作系统的默认样式。

(2)另一方面,从技术角度了解元素及其基本属性,就可以减少产品方案中对细节描述的遗漏。

二、CSS

2.1 简介

CSS翻译作“层叠样式表”,和HTML一样,CSS也是我们用来创建网页的语言,HTML定义页面的内容和结构,而CSS定义了web页面的样式和表现。

具体来说,通过在HTML的<link>或<style>中链接到CSS样式表,CSS就可以通过其众多的样式属性,控制HTML中元素的外观表现。

2.2 CSS样式属性

CSS的样式属性,例如color、border、font-style等,可以控制HTML元素的字体颜色、边框、字体样式等等。此外,CSS将每个HTML元素看作一个盒子(这也就是“盒模型”),以控制其内外边距、边框等。

还可以使用CSS灵活的对页面进行布局:

(1)流体布局,扩展浏览器窗口时,页面中的内容会根据一定规则自动扩展以适应页面

(2)冻结布局,通过设定页面宽度,所有页面元素都将固定在页面上,不随浏览器窗口大小而改变布局

(3)凝胶布局,锁定页面内容区域的宽度,但外边距会根据窗口大小进行扩展收缩,从而使得页面在浏览器中居中

(4)绝对定位,使得元素相对于页面固定

(5)固定定位,使元素相对于浏览器窗口固定不动

(6)相对定位

(7)表格显示

(8)浮动布局

2.3 CSS适配

CSS可以灵活适配,可以为一个HTML页面设置多个样式表(或者在CSS中设置@media规则),用于不同的场景展示、匹配不同的设备或者适应不同的窗口宽度。

2.4 产品工作中的应用

(1)在详细的产品设计实现方案中,不仅要定义页面具有哪些元素,也要定义这些元素的样式、外观、动效等。

在技术实现上,这是两个不同的层面,由不同的语言来实现;因而在文档写作中,也应该将元素与其样式区分开来进行描述,而不是将所有说明混杂在一起(虽然这个工作往往需要和设计进行配合)。

例如在描述按钮时,不仅要指明按钮元素的基本属性(例如按钮文本、按钮类别),也应该指出按钮在不同状态的不同样式。

(2)在宏观层面,随着设备形态的多样化,样式适配也变成了一个很大的主题,也应是产品设计中应该考虑的重要方面。

以网站设计而言,同样的内容元素,在手机和PC上往往需要定义不同的样式,对此有很多技术实现方案,产品经理应对样式适配有基本认知,才能与技术共同商定适配方案。

三、JavaScript

3.1 简介

前面提到,使用HTML标记和CSS可以帮助搭建web页面,而JavaScript的使用,可以为这些页面增加行为和功能(比如对用户行为作出响应、处理事件、更新页面、与服务端通信),从而成为真正意义上的web应用。

HTML5是HTML的最新版本,但实际上当我们谈论HTML5时,不仅仅指代标记,而是HTML标记、CSS样式、JavaScript脚本这些技术的结合,这些技术共同帮助构件web应用。

通过在代码中引用JavaScript文件或者直接将脚本放在<script>元素中,就可以在web页面中增加JavaScript。

3.2 JavaScript的工作方式:通过DOM对页面进行更新

浏览器在加载页面时,对于HTML中每一个元素,会创建一个表示该元素的对象,把它与所有其他元素一起放在一个类似树的结构中,这个树即为DOM(文档对象模型 Document Object Model),DOM是浏览器对于页面结构的内部表示。

JavaScript可以通过DOM对页面元素进行访问、修改、增删。例如,可以使用document.getElementById在DOM中查找元素,使用元素的innderHTML属性修改其内容,然后浏览器会近乎实时的对DOM以及页面进行更新。

3.3 处理事件

浏览器在显示页面时,会有许多事件发生,例如按钮点击事件、数据到达事件、时间到期事件等,使用JavaScript编写事件处理程序,可以对这些事件进行处理。

以表单的按钮点击事件为例进行说明:用户在输入框输入信息,点击按钮提交信息后,可以在当前页查看已经提交的信息。

实现思路如下:首先通过DOM获取按钮元素,并为按钮的onclick属性设置一个处理程序。

该处理程序需要通过DOM访问输入元素,并通过输入元素的value属性获取用户输入值,最后再通过DOM增加到页面中。这样在用户点击按钮时,就会执行该处理程序,获取用户输入并增加到页面中,以此实现用户与系统的交互。

3.4 JavaScript API

通过使用JavaScript API(API即应用编程接口,提供一组对象、方法和属性,可以用来访问这些技术的所有功能;对象可以理解为是属性的集合)可以为页面增加更多新的功能,如视频播放、本地存储、地理定位等。

以地理定位为例,通过调用地理定位API,使用其getCurrentPosition方法可以获取当前位置信息(浏览器可以通过IP定位、GPS定位等方式获取位置信息)并进行处理和显示;使用watchPosition方法可以对位置更新进行实时监控和报告;使用clearWatch以停止监视位置。

3.5 前后端通信

(1)Ajax(XMLHttpRequest)

前端(比如浏览器)向服务器请求页面或者数据资源,服务端接受请求并执行服务端程序,捕获程序的输出作为响应发回前端,前端监测到数据到达后,再执行处理程序对这些数据进行处理,最终更新DOM和页面。

这种获取数据的模式称为Ajax,在应用中可以使用这种方式更新内容,而无需重新加载页面。

那么如何使用JavaScript发送请求?

首先创建一个请求对象,指明请求方法和资源地址,同时提供一个处理程序,然后发出请求,等待数据到达。数据到达时,就会调用这个处理程序,在请求对象的responseText属性中获取传回的数据并进行处理。

浏览器主要使用两种方法发送请求:GET和POST

使用POST和GET方法都可以向服务端发送请求,不过采用了不同的方式。POST会打包要传递到服务端的数据,并在后台把他们发送到服务器;GET也会打包数据,但会把这些数据追加到URL的最后,然后向服务器发送请求。

如果要传递的数据应当是私有的,或者数据很多,就应当使用POST;如果返回的页面要支持添加书签,就需要使用GET方法。

(2)JSONP

除了提供HTML和JavaScript的服务器外,浏览器不允许从其他不同的服务器获取数据,这是浏览器的安全策略。如果页面和要请求的数据同在一个服务器上,可以使用Ajax请求数据,如果页面和要请求的数据不在同一服务器上,则可以使用JSONP请求数据。

JSONP是一种使用<script>标记获取数据的方法,通过在请求URL后指定回调函数,将返回的数据包装在一个函数调用中进行处理。

例如,我们的网站从微博获取用户最近动态,就是一个跨域(服务器)请求数据的应用。

(3)Web Socket

Ajax和JSONP都使用了一个基于HTTP的请求/响应模型。也就是说,每次需要从服务端获取资源时,都要使用浏览器作出请求得到相关页面和数据。

对于一些数据更新比较频繁的应用,浏览器需要不断的发送请求询问服务端是否有新数据,在这种应用场景下,Web Socket或许是一个更佳的通信方案。

Web Socket是一个新增的API,允许与一个服务器的连接保持打开,这样在有新数据时,服务器就会主动把数据发给前端,就像浏览器与服务器之间的一个接通的电话线。

Web Socket提供了实时交互通信的能力,允许服务器主动发送信息给客户端,是一种区别于HTTP的全新双向数据流协议。

3.6 本地存储

上面提及页面从服务器获取数据,除此之外,还可以使用本地存储获取数据,从而减少与服务端的通信,打造更好的用户体验与更广泛的应用场景。

(1)浏览器cookie

服务器随响应发送一个cookie给浏览器,cookie中以键值对形式存储一些信息。浏览器在本地存储cookie,下次发出请求时会将cookie发回服务器。cookie是按域存储的,而且只能发送给这个域,因而不同域之间的cookie无法互相访问。使用cookie可以实现个性化的体验、维护游戏状态、存储用户数据等等。

(2)web存储/local storage(本地存储)、session storage(会话存储)

使用JS的 web storage API,可以在浏览器中更好的存储数据。

每个浏览器都有一些本地存储空间(每个域都有超过5M的空间,存储在一个域的数据对另一个域是不可见的),使用setItem方法可以在localstorage中存储一个键值对,使用getItem方法可以从本地存储中获取某个键对应的值,使用remove方法可以删除本地存储中某一键对应的数据项。

session storage与local storage非常相似,唯一的区别在于:在用户与浏览器会话期间,session storage可以在本地存储信息,一旦会话结束(即关闭浏览器窗口),这些信息将删除;而local storage将永久存储信息,除非用户手动删除缓存。

3.7 web工作线程

JavaScript是单线程的,如果要执行复杂的运算,可以会花费太多时间以至于无法及时作出页面响应。这时可以使用web工作线程,他在一个单独的线程处理耗时的任务,所以主代码可以继续运行以提高页面的响应性。每个工作线程在他自己的线程中运行,如果你的计算机有一个多核处理器,工作线程会并行运行,这回提高运算速度。

下面简单介绍一下web工作线程的工作方式。

在主代码中使用构造函数创建一个或者多个工作线程对象,并指定工作线程要执行的JavaScript文件。

主代码和工作线程代码通过消息通信,使用postmessage发送信息,使用onmessage接收信息。

主代码通过发送一个消息让工作线程开始工作,即执行其JavaScript文件;工作线程完成工作后,会发回消息,并传入其运算结果。主代码得到这些结果,执行相应的处理程序,将结果展现在页面中。

3.8 产品工作中的应用

软件产品的设计可以分为内容、形态、行为三个领域。前两者是HTML和CSS的主要工作,而软件行为的设计就是JS(JavaScript)的主要工作。

在内容层面,通过JS进行前后端通信,可以从服务端获取最新的数据并动态的为页面增加内容。

因而在产品设计中,我们应该考虑页面信息的来源,是写死在前端,还是请求服务端数据接口,是否需要搭建相应的管理后台。通过JS进行前后端通信,还可以将用户输入等信息上报服务端并进行存储,这亦是产品方案中应该考虑的地方。

在功能或行为层面,使用JS进行前后端通信,一些功能入口也可以通过服务端进行灵活的配置,例如为不同的用户角色提供不同的功能入口或功能限制。

页面对用户的响应也都是通过JS来实现,例如对表单输入进行校验并反馈,这些逻辑判断和运算都是通过JS完成。对此,产品经理往往需要通过流程图、状态图等,进行逻辑与运算规则的说明。

四、one more thing

上面分别提及在内容、形态、行为三个设计领域,技术在产品工作中的具体应用。在更加抽象的层面,技术的学习让我更加了解互联网产品的本质–信息。在团队配合、项目流程上,技术与设计的结合同样具有价值:

(1)帮助从技术的角度初步评估产品方案,用于评估方案的成本和性价比,排列优先级和进行版本规划

(2)与技术团队更高效的配合,随着技术发展和不断成熟,有越来越多的工具可以帮助快速开发,懂得技术的开发原理和开发手段,才可以采用更加灵活的方式与技术配合。

总结

本文主要探讨了:

  1. 产品经理学习技术的价值
  2. 前端开发的基本知识和原理
  3. 如何借助前端开发的技术知识更好的进行产品方案设计

下一次的分享中将会对后端,以及前后端交互的技术知识和应用进行总结,感兴趣的小伙伴可以关注我或者我的专栏。

写作本文着实花了不少时间,一方面在于其中涉及很多技术语言;但更主要的原因在于写作过程中涉及到技术思维、设计思维的来回切换和融合,自认为本文在这一方面仍然有待提高。

学习技术给我带来很多层面的收获,让我得以层层深入,庖丁解牛似的看清产品的内部构造;也让我可以从不同角度看待技术、设计、产品在软件产业不同阶段中扮演的角色,对团队组织构成有了新的理解。

最后以一句我的名言结尾:对于设计的追问会带你走向技术,对于技术的追问会带你走向设计。

参考资料

《Head First HTML与CSS》

《Head First HTML5 Programming》

写了30+产品需求文档后,我对PRD有了新的认知

WebSocket简介及应用实例

本文由 @lemon 原创发布于人人都是产品经理。未经许可,禁止转载

题图来自Unsplash,基于CC0协议