Translate

2020年5月29日 星期五

CSS ::before and ::after

css 的 ::before 和 ::after 是我比較少接觸的 css 語法, 可以在元素前後加上一個不存在網頁元素中的物件,範例如下:


<style>
.txt
{
  color:#0000ff;
}
.txt::before
{
  content:"[" attr(btxt) "]";
/*
  content 一定要給值,語法有
  attr(屬性)
  url(網址) 可以秀圖片
*/
  color:#ff0000;
}
.txt::after
{
  content:"[" attr(atxt) "]";
  color:#00ff00;
}
</style>

<span class="txt" btxt="Before" atxt="After">我是文字</span><br>

我是文字

content 雖然可以用 url 秀圖片,但是無法調整圖片大小,如果要設定圖片大小,可以利用 background-image 來實現


<style>
.txt1
{
  color:#0000ff;
  position:relative;
}
.txt1::before
{
  content:"  [" attr(btxt) "]" ;
  color:#ff0000;
  display:inline-block;
  background-image: url("https://yiharng.github.io/bomb.png");
  background-repeat: no-repeat;
  background-size: 1.5em;
  height:2em;
}
.txt1::after
{
  content:"[" attr(atxt) "]";
  color:#00ff00;
}
</style>

<span class="txt1" btxt="Before" atxt="After">我是文字</span>

我是文字

CSS 的選擇器語法除了用 .class 還可以用 [] 來指定特定的attr , 如果搭配 hover 可以做到滑鼠移過去顯示說明的效果, 這個效果以前都是用 javascript 製作,其實 CSS 就可以做到了 !



<style>
span[stxt]:hover
{
  position:relative;
  color:#ff00ff;
  cursor:help;
}
span[stxt]:hover::after,
span[stxt]:focus::after
{
  position:absolute;
  background-color:#ffffcc;
  color:#0000ff;
  padding:0.5em;
  border:1px solid #000000;
  width:6em;
  text-align:center;
  left:0;
  top:1.2em;
}
span[stxt=ok1]:hover::after,
span[stxt=ok1]:focus::after
{
  content:"我是說明1";
}
span[stxt=ok2]:hover::after,
span[stxt=ok2]:focus::after
{
  content:"我是說明2";
}
</style>

<span stxt="ok1">我是文字1</span>
<span stxt="ok2">我是文字2</span>

我是文字1 我是文字2


::before 和 ::after 有個特別的功能是 counter , 我個人覺得這個其實就是 <ul> <ol> <li> 的原型

特別的是,自己寫有更靈活的設定,例如可以設定數字間隔,或多個計數器

範例如下 :



<style>

.nn,.f0
{
  counter-reset:var1 var2 2;
/*
  counter-reset:變數1 起始值 變數2 起始值
  沒有設定起始值就是 0
*/
}
.f1::before
{
  counter-increment: var1;
  content: counter(var1) ". ";
}
.f2::before
{
  counter-increment: var2 2;
  content: counter(var2,cjk-ideographic) ". ";
  color:#ff0000;
/*
  counter 語法 : counter(變數,list-style-type)
*/
}
.nn div{
  margin-left:1em;
}
</style>

<div class="nn">
開始
<div class="f0">
  <div class="f1">一樓</div>
  <div class="f1">一樓
    <div class="f0">
      <div class="f1">二樓</div>
      <div class="f1">二樓
        <div class="f0">
          <div class="f1">三樓</div>
          <div class="f1">三樓
            <div class="f2">F2</div>
            <div class="f2">F2</div>
            <div class="f2">F2</div>
          </div>
          <div class="f1">三樓</div>
        </div>
      </div>
      <div class="f1">二樓</div>
    </div>
  </div>
  <div class="f1">一樓</div>
</div>
結束
</div>
開始
一樓
一樓
二樓
二樓
三樓
三樓
F2
F2
F2
三樓
二樓
一樓
結束

list-style-type 的值如下:

disc , circle , square , armenian , cjk-ideographic , decimal , decimal-leading-zero , georgian , hebrew , hiragana , hiragana-iroha , katakana , katakana-iroha , lower-alpha , lower-greek , lower-latin , lower-roman , upper-alpha , upper-greek , upper-latin , upper-roman , none , inherit

除了 counter ,還有一個 counters 可以處理階層問題



<style>

.snn .sf0
{
  counter-reset:var1;
}
.snn .sf1::before
{
  counter-increment: var1;
  content: counters(var1,"-") ". ";
/*
  counters 語法 : counters(變數,連結字串,list-style-type)
*/
}
.snn div{
  margin-left:1em;
}
</style>

<div class="snn">
開始
<div class="sf0">
  <div class="sf1">一樓</div>
  <div class="sf1">一樓
    <div class="sf0">
      <div class="sf1">二樓</div>
      <div class="sf1">二樓
        <div class="sf0">
          <div class="sf1">三樓</div>
          <div class="sf1">三樓</div>
          <div class="sf1">三樓</div>
        </div>
      </div>
      <div class="sf1">二樓</div>
    </div>
  </div>
  <div class="sf1">一樓</div>
</div>
結束
</div>
開始
一樓
一樓
二樓
二樓
三樓
三樓
三樓
二樓
一樓
結束

這個功能的實用範例,是直接搭配 h1 和 h2 來實做章節



<style>

.hnn
{
  counter-reset: var1;
}
.hnn h1
{
  counter-reset: var2;
}
.hnn h1::before
{
  counter-increment: var1;
  content: "第" counter(var1) "章 " ;
}
.hnn h2::before
{
  counter-increment: var2;
  content: "第" counter(var1) "-" counter(var2) "節 ";
}
.hnn h2
{
  margin-left:1em;
}
.hnn span
{
  margin-left:3em;
}
</style>

<div class="hnn">
<h1>開始</h1>
  <h2>出發</h2>
    <span>一個旅程的開始
    </span>
  <h2>繼續</h2>
<h1>回程</h1>
  <h2>加油</h2>
  <h2>到家</h2>
</div>

開始

出發

一個旅程的開始

繼續

回程

加油

到家


取值和修改

javascript 有一個超強的指令,可以取得該元素所有的設定

window.getComputedStyle('元素', '::before 或 ::after')



<style>

.r6css1::before
{
  content: "[" attr(btxt) "]";
  color:#0000ff;
}
</style>

<div class="r6css1" btxt="我是Before">
  我是文字
</div>
<br>
<div class="r6css2">
</div>

<script>

(function()
{
  let dd=document.querySelector(".r6css1");
  let dd1=window.getComputedStyle(dd,"::before");
  $(".r6css2").html(
     "color:"+dd1.color+"<br>"
    +"content:"+dd1.content
  );
})() 

</script>
我是文字

color:rgb(0, 0, 255)
content:"[我是Before]"

::before 和 ::after 並不允許直接修改內容,最簡單的方法,是用新的 CSS 取代舊的

範例 :



<style>
.r7css1::before
{
  content: "[" attr(btxt) "]";
  color:#0000ff;
}
</style>
<style id="r7css_new">
</style>

<div class="r7css1" btxt="我是Before">
  我是文字
</div>
<br>
  <button id="r7b1">紅色</button>
  <button id="r7b2">綠色</button>

<script>

(function()
{
  let cc = document.getElementById('r7css_new').sheet;
  cc.insertRule(".r7css1::before{color:#0000ff;}", 0);  

  $("#r7b1").on("click",()=>
  {
    let cc = document.getElementById('r7css_new').sheet;
    cc.deleteRule(0);
    // 語法 deleteRule(索引)  
    cc.insertRule(".r7css1::before{color:#ff0000;}", 0);  
    // 語法 insertRule("css", 索引); 索引可省略
  });
  $("#r7b2").on("click",()=>
  {
    let cc = document.getElementById('r7css_new').sheet;
    cc.deleteRule(0);
    cc.insertRule(".r7css1::before{color:#00ff00;}", 0);  
  });
})() 

</script>
我是文字



沒有留言:

張貼留言