CSS和JavaScript的圆角

圆角是最常用的CSS技术之一。 与CSS中的许多内容一样,可以通过多种方法来解决此问题。 在本文中,我将介绍一些常用技术的优缺点,并介绍一种同时利用CSS和JavaScript的新技术。

在开始使用CSS之前,让我们想起解决此问题的老式方法,该方法使用布局表:

<table width="200" cellpadding="0" cellspacing="0"> 
<tr> 
  <td width="15"><img src="tl.gif" alt="" /></td> 
  <td bgcolor="#1b5151"></td> 
  <td width="15"><img src="tr.gif" alt="" /></td> 
</tr> 
<tr bgcolor="#1b5151"> 
  <td>&nbsp;</td> 
  <td>Content goes here</td> 
  <td>&nbsp;</td> 
</tr> 
<tr bgcolor="#1b5151"> 
  <td><img src="bl.gif" alt="" /></td> 
  <td></td> 
  <td><img src="br.gif" alt="" /></td> 
</tr> 
</table>

几年前,这是一个可以接受的解决方案。 如今,这是一个丑陋的骇客:对于相对不重要的视觉装饰,这是很多多余的标记。 实际上,上述代码甚至无法在使用严格doctype的文档中按预期方式工作-由于图像是内联元素,因此在图像下方会出现小间隙,这是因为图像是内联元素,因此在图像下方留有空间字母“ y”和“ j”上的“尾巴”。 正如Eric Meyer在“ 图像,表格和神秘间隙”中所解释的,该解决方案是在样式表中添加以下规则:

td img { display: block; }

这产生所希望的结果,如图这里

但是,现在我们正在使用CSS hack来修复丑陋的表格hack! 让我们看看仅使用CSS来实现相同效果的方法。

通常,任何装饰图像都应在现有页面元素上实现为CSS背景图像,而不是使用<img>标记正确放置到页面中。 很容易确定图像是装饰性的还是包含实际内容:问自己是否缺少图像会对页面的整体内容有任何影响。 如果是圆角,答案显然不是。

CSS背景图片非常强大。 您只需要查看CSS Zen Garden上展示的许多精彩设计,就可以证明这一点。 使用CSS,可以将背景图像应用于页面上的任何元素。 此外,它可以水平,垂直或根本不重复; 它可以使用绝对测量值定位在图像的背景区域内,也可以相对于四个角之一定位; 当元素的内容滚动时,甚至可以将其固定在适当的位置。 不幸的是,CSS 2施加了一个小但重要的限制:您只能将单个背景图像应用于页面上的每个元素。 为了在<div>上正确渲染圆角,我们需要应用四个背景图像,每个角上一个。

定宽框

如果我们要应用装饰角的盒子的宽度固定,那么一半的问题已经解决。 如果我们知道该框将始终为200像素宽,而不是创建四个背景图像(每个角一个),则可以创建两个:一个用于框的顶部,一个用于框的底部。 现在的挑战减少到将两个背景图像应用于我们的<div> 。 现在是时候利用我们的标记了。

如果一个圆角的盒子不包含任何内容,那将不会很有趣。 考虑以下:

<div class="rounded"> 
<h3>Exciting features!</h3> 
<p>Your new Widget2000 will...</p> 
<ul> 
 <li>... clean your shoes</li> 
 <li>... walk your dog</li> 
 <li>... and balance your cheque book!</li> 
</ul> 
</div>

很简单吧? 框的标题位于<h3> (我假设<h1><h2>在页面的层次结构中已被使用过),其后的内容是一个段落和一个无序列表。 解决我们两个背景问题的关键在于<h3> ,它位于框顶部。 我们要做的就是在<h3>的顶部应用背景图像,在包含的<div>的底部应用背景图像,效果就完成了:

div.rounded { 
  width: 200px; 
  background: #1b5151 url(200pxbottom.gif) no-repeat bottom center; 
  padding-bottom: 15px; 
} 
div.rounded h3 { 
  padding-top: 15px; 
  background: transparent url(200pxtop.gif) no-repeat top center; 
}

单击此处查看结果。

结构良好的文档通常到处都是这样的钩子,可以仔细利用它们以应用多个背景并实现特定的视觉效果。 学会识别它们是使用CSS的重要部分。

嵌套元素

将四个背景应用于单个div仍然无法实现。 但是,如果我们嵌套四个div,每个背景一个,该怎么办? 这样做可以解决我们的问题,但是要以没有结构价值的附加标记为代价:

<div class="rounded"><div><div><div> 
Content goes here 
</div></div></div></div>

并且,在CSS中:

div.rounded { 
  width: 200px; 
  background: #1b5151 url(tr.gif) no-repeat top right; 
} 
div.rounded div { 
  background: transparent url(tl.gif) no-repeat top left; 
} 
div.rounded div div { 
  background: transparent url(br.gif) no-repeat bottom right; 
} 
div.rounded div div div { 
  background: transparent url(bl.gif) no-repeat bottom left; 
  padding: 15px; 
}

代码显示如图这里

应该清楚这里发生了什么。 四个div中的每个div被分配一个圆角背景图像,分别位于右上角,左上角,右下角和左下角。 尽管包含div的宽度设置为200像素,但可以很容易地将其设置为更灵活的方式以用于液体设计-无论包含div的大小如何,拐角仍将起作用。

现在,我们有了一个解决问题的方法,该方法比原始表示例使用的标记少得多。 但是,它仍然不是完美的:它使用了三个额外的div,这对整个文档结构没有任何价值。 我们可以做得更好吗? 现在该看看JavaScript。

使用DOM

使用JavaScript和DOM,可以在浏览器加载文档后操纵文档的结构。 圆角是一种呈现效果,可以对非JavaScript用户代理隐藏,而不会显着降低其网站的整体体验,因此使用JavaScript进行这种转换不会产生道德问题。 我们的最终解决方案只需要源文档中的单个<div> 。 我们将使用JavaScript动态添加圆角效果所需的三个多余的div。

这是标记:

<div class="rounded"> 
Content goes here. 
</div>

我认为您会同意,除了将内容在结构上更好地定义为段落之外,也许可以将<div>替换为<p> ,我们没有什么能使它变得更简单了。 进行此切换留给读者练习。

现在是JavaScript:

function roundedCorners() { 
  var divs = document.getElementsByTagName('div'); 
  var rounded_divs = []; 
  /* First locate all divs with 'rounded' in their class attribute */ 
  for (var i = 0; i < divs.length; i++) { 
    if (/broundedb/.exec(divs[i].className)) { 
      rounded_divs[rounded_divs.length] = divs[i]; 
    } 
  } 
  /* Now add additional divs to each of the divs we have found */ 
  for (var i = 0; i < rounded_divs.length; i++) { 
    var original = rounded_divs[i]; 
    /* Make it the inner div of the four */ 
    original.className = original.className.replace('rounded', ''); 
    /* Now create the outer-most div */ 
    var tr = document.createElement('div'); 
    tr.className = 'rounded2'; 
    /* Swap out the original (we'll put it back later) */ 
    original.parentNode.replaceChild(tr, original); 
    /* Create the two other inner nodes */ 
    var tl = document.createElement('div'); 
    var br = document.createElement('div'); 
    /* Now glue the nodes back in to the document */ 
    tr.appendChild(tl); 
    tl.appendChild(br); 
    br.appendChild(original); 
  } 
} 
/* Run the function once the page has loaded: */ 
 
window.onload = roundedCorners;

该脚本分为两个逻辑部分。 第一部分遍历文档中的所有<div>元素,构建一个在其class属性中包含'rounded'元素的数组(请记住,元素可以具有多个由空格分隔的类)。 脚本的第二部分依次遍历这些元素中的每一个,创建了三个附加的div,并将它们包装在原始元素周围。 让我们更详细地看一下代码:

original.className = original.className.replace('rounded', '');

在这里,我们从原始<div>完全删除了"rounded"类。 原因将在CSS中明确; 本质上,我们不希望应用原始样式再影响该元素。

var tr = document.createElement('div'); 
tr.className = 'rounded2';

我们创建了最外面的<div> ,它将用于应用右上角的背景图像以及盒子的整体宽度。 注意,我们已经将该类设置为'rounded2'; 这将在我们的CSS中定义,与提供给未启用JavaScript的客户端的'rounded'类的细微差别。

/* Swap out the original (we'll put it back later) */ 
original.parentNode.replaceChild(tr, original);

W3C DOM没有提供将文档中的节点替换为另一个节点的直接方法。 相反,您必须使用节点的replaceChild()方法将其子节点之一替换为另一个节点。 替换您要查看的节点的有用技巧是使用parentNode属性访问其自身的父节点,然后使用/#c#.replaceChild将该节点交换为其他节点。 如果这对您没有意义,请不要担心-只需将上述行视为将我们的原始节点替换为我们刚刚创建的新tr节点即可。

/* Create the two other inner nodes */ 
var tl = document.createElement('div'); 
var br = document.createElement('div'); 
/* Now glue the nodes back in to the document */ 
tr.appendChild(tl); 
tl.appendChild(br);

现在,我们创建了三个新的<div>元素并将其插入到文档中。 剩下的就是重新插入我们的原始节点,并完成其内容:

br.appendChild(original);

在这一点上,我们的实际文档树几乎与上面四个嵌套的<div>示例中的树相同,唯一的区别是外部元素的类为'rounded2'而不是'rounded' 。 这是CSS:

div.rounded { 
  width: 170px; 
  padding: 15px; 
  background: #1b5151; 
} 
 
div.rounded2 { 
  width: 200px; 
  background: #1b5151 url(tr.gif) no-repeat top right; 
} 
div.rounded2 div { 
  background: transparent url(tl.gif) no-repeat top left; 
} 
div.rounded2 div div { 
  background: transparent url(br.gif) no-repeat bottom right; 
} 
div.rounded2 div div div { 
  background: transparent url(bl.gif) no-repeat bottom left; 
  padding: 15px; 
}

这是结果。

第一组规则div.rounded仅在不执行JavaScript的浏览器中使用。 请注意,宽度为170像素,填充为15像素,这总计为200像素(宽度加上左右填充)。 如果您需要在IE 5 / Windows中使用此方法(对填充值的解释不同),则需要应用臭名昭著的Box Model hack 。 您已经在上一个示例中看到了第二组规则。

展望未来

以上技术将在所有现代浏览器以及所有将来支持CSS2和DOM 2标准的浏览器中使用。 CSS 3引入了许多实现此效果的新方法,这将使上述技术过时。 CSS不仅具有本机圆角支持 (已在Mozilla系列浏览器中提供),还具有强大的:: outside伪元素 ,该伪元素允许以类似于本文所示JavaScript示例的方式插入其他可样式化元素。 如果这还不够的话, 边框图像将几乎允许您想到的任何边框装饰。

不幸的是,要获得CSS 3支持还需要很多年。 在此之前,JavaScript能够胜任某些工作。

From: https://www.sitepoint.com/rounded-corners-css-javascript/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值