防御性编程是一种细致、谨慎的编程方法(习惯)。我们在写代码时常会有“以防万一”的心态,把以防万一有可能出现的情况提前考虑进去,规避以免以防万一出现带来的问题。
应用防御性编程技术,你可以侦测到可能被忽略的错误,防止可能会导致灾难性后果的“小毛病”的出现,在时间的运行过程中为你节约大量的调试时间。
比如我们在写下面这个效果时,如果只是按设计师设计效果来开发,我们就不会考虑标题内容过长的问题。但是在实际的应用中,数据是从后台加载而来,标题的字数就有可能过长,过长之后就会导致标题溢出折行的效果如下图,带来不好的体验。
如果站在防御式编程的角度来思考,那我们就会提前把这种问题规避掉。如果标题过长,我们可以使用...省略号来处理。而不是等到项目上线,实际问题发生时,再来修改代码。
防御式CSS是一个片段的集合,可以帮助我们规避“以防万一”产生的问题。
我们在CSS布局时,是按照设计师的效果来开发的,但是实际的网页内容是动态的,网页上的内容是可以改变的,如:文字数量,图片尺寸、窗口大小等,再加上用户的一些意想不到的行为和运行环境,从而造成CSS布局的效果并没有按照我们预期的效果显示。
我们可以通过添加某些CSS代码,来避免这种情况带来的问题。防御式CSS是实现项目稳定性建设重要但极其容易忽视的一环。
接下来我们分享9个应用场景下,具有防御式的CSS代码。
我们设计时的理想效果是标题文字不超过8个字,正好显示完整。但实际应用时,有可能标题内容过长造成换行显示。我们可以添加文字溢出显示..省略号来解决。
<style>
body,
h3 {
margin: 0;
padding: 0;
}
.box {
width: 150px;
height: 150px;
position: relative;
margin: 40px auto;
}
.box h3 {
height: 30px;
line-height: 30px;
font-weight: 100;
width: 100%;
background-color: rgba(0, 0, 0, 0.5);
font-size: 16px;
color: #fff;
position: absolute;
bottom: 0;
text-align: center;
/*以防万一,标题过长时,用...省略号显示*/
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
</style>
<body>
<div class="box">
<img src="images/flex-06.jpg" alt="" />
<h3>"以防万一"标题过长产生的问题</h3>
</div>
</body>
在这个效果中,我们并不希望标签延伸到最右侧,我们希望内容过长时,可以在一定的长度时就折行显示。我们可以通过添 max-width属性来避免这种“以防万一”的问题。
同类的应用还有 min-width,在此就不演示了
<style>
.box {
width: 250px;
height: 250px;
position: relative;
}
.box span {
position: absolute;
background-color: rgba(119, 245, 197, 0.8);
line-height: 1.3;
font-size: 12px;
padding: 5px 10px;
border-radius: 0 50px 50px 0px;
left: 0px;
top: 5px;
/*以防万一标签内容过长,控制最大宽度,内容过多折行显示*/
max-width: 70%;
}
</style>
</head>
<body>
<div class="box">
<img src="images/ms.jpg" alt="" />
<span>植物奶油 巧克力 草莓 榴莲 花生 芝麻 小米 鸡蛋</span>
</div>
</body>
我们预想的是用户按1:1的大小来上传头像图片,但实际用户上传的头像比例是五花八门,就会造成图片被拉伸或挤压变形。我们可以添加Object-fit:cover来等比例裁剪图片尺寸,这样图片就不会被拉伸或压缩,不过会有一部分图片被裁剪掉。
<style>
.box {
width: 200px;
height: 200px;
border-radius: 50%;
overflow: hidden;
}
.box img {
width: 100%;
height: 100%;
/*保持图片原有尺寸来裁剪*/
object-fit: cover;
}
</style>
<body>
<div class="box">
<img src="images/tx2.png" alt="" />
</div>
</body>
当图片上有文字时,如果图片加载失败,而外层容器的背景色和文字颜色接近,那么文字的展示效果就不理想;此时我们可以给图片加上对应的背景色。
这个效果大家只需做个了解就好。通常如果图片上有文字,设计师在设计效果图时都会在图片和文字中间加上一层黑色的半透明遮罩层,这样即使图片加载不出来,也不影响文字的展示效果。
<style>
.box {
width: 250px;
height: 156px;
position: relative;
}
.box img {
width: 100%;
height: 100%;
object-fit: cover;
/*"以防万一"图片加载失败,加上背景色,保证文字能正常显示*/
background-color: #666;
}
.box h3 {
width: 100%;
font-size: 20px;
text-align: center;
position: absolute;
top: 40px;
color: #fff;
}
</style>
<body>
<div class="box">
<img src="images/rotate3.webp" alt="" />
<h3>美丽的风景图</h3>
</div>
</body>
在内容比较长的情况下,可以通过设置 overflow-y控制滚动条是否展示。但是这里更推荐将overflow-y的值设置为 auto。如果你将overflow-y显式设置为 scroll时,不管容器内容长短,滚动条都会展示出来,这种体验是不好的
<style>
.box {
width: 160px;
padding: 20px;
height: 200px;
background-color: skyblue;
line-height: 2;
border-radius: 20px;
}
.box .content {
padding-right: 10px;
max-height: 100%;
/*以防万一,用户内容不足时,不需要显示滚动条,只有内容溢出时才显示*/
overflow-y: auto;
}
/* 整个滚动条*/
.content::-webkit-scrollbar {
width: 5px;
padding: 0px 20px;
}
/* 滚动条轨道*/
.content::-webkit-scrollbar-track {
border-radius: 10px;
background-color: #000;
margin: 20px 0px;
}
/*滚动条上的滚动滑块*/
.content::-webkit-scrollbar-thumb {
width: 14px;
border-radius: 10px;
background-color: #ddd;
}
</style>
<body>
<div class="box">
<div class="content">
在内容比较长的情况下,可以通过设置
overflow-y控制滚动条是否展示。但是这里更推荐将
</div>
</div>
</body>
当内容不足时不会出现滚动条,文字占据的宽度要宽些。当内容溢出出现滚动条时,因为滚动条要占据一部分空间,则会造成文字占据的空间变窄,因而会造成重排。我们可以元素添加scrollbar-gutter:stable;来避免这个问题。
scrollbar-gutter属性有三个值
没有加scrollbar-gutter时,未出现滚动条和出现滚动条之间的差别
加上scrollbar-gutter:stable;后,出现滚动条和没有出现滚动,前后文字显示效果没有差异
<style>
.box {
width: 160px;
padding: 20px;
height: 200px;
background-color: skyblue;
line-height: 2;
border-radius: 20px;
}
.box .content {
max-height: 100%;
/*以防万一,用户内容不足时,不需要显示滚动条,只有内容溢出时才显示*/
overflow-y: auto;
/*预留好滚动条位置,必免引起重排*/
scrollbar-gutter: stable;
}
.content::-webkit-scrollbar {
width: 10px;
}
.content::-webkit-scrollbar-track {
border-radius: 10px;
background-color: #000;
margin: 20px 0px;
}
.content::-webkit-scrollbar-thumb {
width: 14px;
border-radius: 10px;
background-color: #ddd;
}
</style>
<body>
<div class="box">
<div class="content">
当内容不足时不会出现滚动条,文字占据的宽度要宽些。当内容溢出出现滚动条时,因为滚动条要占据一部分空间,则会造成文字占据的空间变窄,因而会造成重排。
</div>
</div>
</body>
我们会发现当子元素滚动到顶部或底部继续滚动滚轮时,会导致父元素的滚动,但这种行为有时会影响页面体验。在子元素上应用overscroll-behavior: contain就可以禁止掉这一行为。
<style>
body {
height: 2000px;
}
.box {
height: 400px;
width: 200px;
margin: 0px auto;
overflow-y: auto;
background-color: skyblue;
/*当滚动到滚动条底部和顶部时,会触发父元素的滚动条滚动*/
overscroll-behavior-y: contain;
}
</style>
<body>
<div class="box">
<p>1</p>
<p>2</p>
<p>3</p>
<p>4</p>
<p>5</p>
<p>6</p>
<p>7</p>
<p>8</p>
<p>9</p>
<p>10</p>
<p>11</p>
<p>12</p>
<p>13</p>
<p>14</p>
<p>15</p>
<p>16</p>
<p>17</p>
<p>18</p>
<p>19</p>
<p>20</p>
<p>21</p>
<p>22</p>
<p>23</p>
<p>24</p>
<p>25</p>
<p>26</p>
<p>27</p>
<p>28</p>
<p>29</p>
<p>30</p>
<p>31</p>
<p>32</p>
</div>
</body>
如果我们每一行显示的个数为n,那我们可以最后一行子项的后面加上n-2个span元素,span元素的宽度和其它子项元素宽度一样,但不用设置高度。
为什么是添加n-2个span元素呢?
当最后一行只有1个子元素时,他会默认靠左,不用处理
当最后一行子元素正好时,我们就不用关心这个问题。
所以要去掉这两种情况,只需要加n-2个span元素就好
<style>
.container {
width: 500px;
display: flex; /*弹性布局*/
justify-content: space-between; /*两端对齐*/
flex-wrap: wrap; /*超出部分换行*/
}
.item {
width: 120px;
height: 100px;
background-color: pink;
margin-top: 10px;
}
.container span {
width: 120px; /*span宽和子项宽一样*/
}
</style>
</head>
<body>
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<!--以防万一,子项个数不够,最后一排出现两端对齐,达不到预期效果-->
<span></span>
<span></span>
</div>
</body>
当我们想尽可能多的在一行显示子项的个数时,有可能会出现子项个数不满一行的情况。那这个时候利用网格布局,使用auto-fill和auto-fit就会是两个完全不同的效果。
以下情况只会出现在子项内容不能占满一行时。也就是说万一内容不能占满一行,则使用auto-fill就会出现空白问题。我们把auto-fill改成auto-fit就解决了这个问题
<style>
.container {
width: 100%;
display: grid;
/*grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));*/
/*以防万一,子项不足占据一行时*/
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
grid-template-rows: 250px;
grid-auto-flow: row;
grid-auto-rows: 250px;
gap: 10px;
}
.container .item:nth-child(even) {
background-color: skyblue;
}
.container .item:nth-child(odd) {
background-color: pink;
}
</style>
<body>
<div class="container">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
</body>
为帮助到一部分同学不走弯路,真正达到一线互联网大厂前端项目研发要求,首次实力宠粉,打造了《30天挑战学习计划》,内容如下:
HTML/HTML5,CSS/CSS3,JavaScript,真实企业项目开发,云服务器部署上线,从入门到精通
共4大完整的项目开发 !一行一行代码带领实践开发,实际企业开发怎么做我们就是怎么做。从学习一开始就进入工作状态,省得浪费时间。
从学习一开始就同步使用 Git 进行项目代码的版本的管理,Markdown 记录学习笔记,包括真实大厂项目的开发标准和设计规范,命名规范,项目代码规范,SEO优化规范
从蓝湖UI设计稿 到 PC端,移动端,多端响应式开发项目开发
这些内容在《30天挑战学习计划》中每一个细节都有讲到,包含视频+图文教程+项目资料素材等。只为实力宠粉,真正一次掌握企业项目开发必备技能,不走弯路 !
过程中【不涉及】任何费用和利益,非诚勿扰 。
我在MiniTest::Spec和Capybara中使用以下规范:find_field('Email').must_have_css('[autofocus]')检查名为“电子邮件”的字段是否具有autofocus属性。doc说如下:has_css?(path,options={})ChecksifagivenCSSselectorisonthepageorcurrentnode.据我了解,字段“Email”是一个节点,因此调用must_have_css绝对有效!我做错了什么? 最佳答案 通过JonasNicklas得到了答案:No
我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当
我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm
我有一个驼峰式字符串,例如:JustAString。我想按照以下规则形成长度为4的字符串:抓取所有大写字母;如果超过4个大写字母,只保留前4个;如果少于4个大写字母,则将最后大写字母后的字母大写并添加字母,直到长度变为4。以下是可能发生的3种情况:ThisIsMyString将产生TIMS(大写字母);ThisIsOneVeryLongString将产生TIOV(前4个大写字母);MyString将生成MSTR(大写字母+tr大写)。我设法用这个片段解决了前两种情况:str.scan(/[A-Z]/).first(4).join但是,我不太确定如何最好地修改上面的代码片段以处理最后一种
我们的git存储库中目前有一个Gemfile。但是,有一个gem我只在我的环境中本地使用(我的团队不使用它)。为了使用它,我必须将它添加到我们的Gemfile中,但每次我checkout到我们的master/dev主分支时,由于与跟踪的gemfile冲突,我必须删除它。我想要的是类似Gemfile.local的东西,它将继承从Gemfile导入的gems,但也允许在那里导入新的gems以供使用只有我的机器。此文件将在.gitignore中被忽略。这可能吗? 最佳答案 设置BUNDLE_GEMFILE环境变量:BUNDLE_GEMFI
这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub
我正在玩HTML5视频并且在ERB中有以下片段:mp4视频从在我的开发环境中运行的服务器很好地流式传输到chrome。然而firefox显示带有海报图像的视频播放器,但带有一个大X。问题似乎是mongrel不确定ogv扩展的mime类型,并且只返回text/plain,如curl所示:$curl-Ihttp://0.0.0.0:3000/pr6.ogvHTTP/1.1200OKConnection:closeDate:Mon,19Apr201012:33:50GMTLast-Modified:Sun,18Apr201012:46:07GMTContent-Type:text/plain
我有一个div,它根据表单是否正确提交而改变。我想知道是否可以检查类的特定元素?开始元素看起来像这样。如果输入不正确,添加错误类。 最佳答案 试试这个:browser.div(:id=>"myerrortest").class_name更多信息:http://watir.github.com/watir-webdriver/doc/Watir/HTMLElement.html#class_name-instance_method另一种选择是只查看具有您期望的类的div是否存在browser.div((:id=>"myerrortes
无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD
matlab打开matlab,用最简单的imread方法读取一个图像clcclearimg_h=imread('hua.jpg');返回一个数组(矩阵),往往是a*b*cunit8类型解释一下这个三维数组的意思,行数、数和层数,unit8:指数据类型,无符号八位整形,可理解为0~2^8的数三个层数分别代表RGB三个通道图像rgb最常用的是24-位实现方法,即RGB每个通道有256色阶(2^8)。基于这样的24-位RGB模型的色彩空间可以表现256×256×256≈1670万色当imshow传入了一个二维数组,它将以灰度方式绘制;可以把图像拆分为rgb三层,可以以灰度的方式观察它figure(1