HTML / 屬性
===
###### tags: `frontend / HTML`
###### tags: `frontend`, `HTML`
<br>
[TOC]
<br>
## entity name
- [[HTML] Living Standard — Last Updated 15 September 2022](https://html.spec.whatwg.org/multipage/named-characters.html)
- 背斜線:[\\ represents reverse solidus (backward solidus)](https://stackoverflow.com/a/32329887/4359712)
- Slash : / : \/ : \/
- Backslash : \ : \\ : \\
<br>
## 全域屬性
- ### [HTML Global Attributes](https://www.w3schools.com/tags/ref_standardattributes.asp)
- class
- id
- title
<br>
## 比較
### innerText vs. innerHTML vs. textContent
- ### [What’s Best: innerText vs. innerHTML vs. textContent](https://betterprogramming.pub/903ebc43a3fc)
- innerText: 頁面渲染後的純文字 (包含換行)
- innerHTML: 頁面渲染前的原始碼
- textContent: 頁面渲染前的原始碼,但要去掉 tag,且包含 script, css 的內容
- ### 測試範例
```html=
<div class="box">
<h2> 星期六</h2>
<script>const x = 0;</script>
<p> 待在家寫 code </p>
</div>
```

<br>
### pre, xmp
- [Html之pre、xmp標籤_感覺沒什麼用_例項](https://www.796t.com/content/1549137637.html)
<br>
<hr>
<br>
## label & inputs[name=radio|checkbox]
### label 與 input 所觸發的事件順序為何
- ### 結論:
- 一般行為
```
<label onclick="labelClicked()">
Click me:
<input type="radio" name="option" onclick="inputClicked()">
</label>
```
- 點擊 "Click me" 文字,觸發:
- Label clicked (label 會觸發 input -> Input clicked)
- Input clicked
- Label clicked (input 會向上傳遞事件 -> label clicked)
- 點擊 "radio" 按鈕,觸發:
- Input clicked
- Label clicked (input 會向上傳遞事件 -> label clicked)
- 使用 event.stopPropagation
```
<script>
function inputClicked() {
console.log('Input clicked'); event.stopPropagation();
}
function labelClicked() {
console.log('Label clicked'); event.stopPropagation();
}
</script>
<body>
<label onclick="labelClicked()">
Click me:
<input type="radio" name="option" onclick="inputClicked()">
</label>
</body>
```
- 點擊 **"Click me"** 文字,觸發:
- Label clicked (label 會觸發 input -> Input clicked)
- Input clicked
- ~~Label clicked (input 會向上傳遞事件 -> label clicked)~~
(因 `event.stopPropagation()`)
- 點擊 **"radio"** 按鈕,觸發:
- Input clicked
- ~~Label clicked (input 會向上傳遞事件 -> label clicked)~~
(因 `event.stopPropagation()`)
- ### Question1
當在文字上點一下時,所觸發的 click 順序,是 `<label>` 先?還是 `<input>` 先?
- ### ChatGPT4
當你在包含 `input` 元素的 `label` 上點擊時,觸發的 `click` 事件順序通常是首先在 `input` 元素上觸發,然後是 `label` 元素。這是因為當 `label` 與特定的表單元素(如 `input`)關聯時,點擊 `label` 會自動將焦點和事件傳遞到相關的 `input` 元素。
這個行為基於 HTML 標準和瀏覽器的實現,目的是增加表單元素的可用性,尤其是對於視力不佳或使用屏幕閱讀器的用戶來說,點擊更大的 `label` 區域比單獨的小 `input` 元素要容易得多。
實驗驗證點擊順序
你可以通過下面的簡單實驗來觀察 click 事件的觸發順序:
```html=
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Click Event Order</title>
<script>
function inputClicked() {
console.log('Input clicked');
}
function labelClicked() {
console.log('Label clicked');
}
</script>
</head>
<body>
<label onclick="labelClicked()">
Click me:
<input type="radio" name="option" onclick="inputClicked()">
</label>
</body>
</html>
```
在這個例子中,當你點擊 `label` 內的文字或 `input` 時,你會在控制台看到打印的信息。從這個輸出你可以觀察到事件觸發的順序。
### 注意
如果你在 `input` 的 `click` 事件處理器中使用了 `event.stopPropagation()`,則可以阻止事件繼續傳播到 `label`:
```javascript
function inputClicked(event) {
console.log('Input clicked');
event.stopPropagation(); // 阻止事件冒泡
}
```
這樣就只會觸發 `input` 的 `click` 事件,而不會觸發 `label` 的 `click` 事件。這在某些需要精確控制事件處理順序和行為的場景下非常有用。
- ### Question2
為何點選 label 中的文字,會觸發 input 的 click 事件?
- ### ChatGPT4
當你點擊一個包含 `input` 元素(如 `radio` 或 `checkbox`)的 `label` 時,會自動觸發相關 `input` 元素的 `click` 事件,這是由 HTML 標準中對於 `label` 元素的行為所定義的。這種設計主要是為了提高表單可用性,使得用戶能夠更容易地與表單控件互動,特別是在較小的螢幕或者使用輔助技術的情況下。
### 原理解釋
當 `label` 與某個 `input` 元素關聯時(無論是通過將 `input` 放置於 `label` 內部,或者透過 `for` 屬性指定 `input` 的 `id`),點擊 `label` 會自動將事件傳遞給 `input`。具體行為包括:
1. **焦點管理**:點擊 `label` 會使相關聯的 `input` 獲得焦點。
2. **狀態切換**:對於開關型控件如 `checkbox` 和 `radio`,點擊 `label` 會切換其選中狀態。
3. **事件觸發**:點擊 `label` 會觸發相關 `input` 的 `click` 事件,這使得為 `input` 元素綁定的事件處理器可以被執行。
### HTML 標準中的描述
根據 HTML 標準,當 `label` 被觸發(點擊)時,會執行以下步驟:
- 如果 `label` 元素有一個 `for` 屬性,且該屬性的值是頁面上某個 `input` 元素的 `id`,則這個 `input` 元素會被觸發。
- 如果 `label` 元素不含 `for` 屬性,但包含一個或多個 `input` 元素,則點擊 `label` 會觸發最靠近 `label` 開始標籤的 `input` 元素。
### 實際應用
這種行為允許開發者設計更加友好的用戶界面,特別是在表單元素較小或難以直接點擊的情況下。用戶可以簡單地點擊較大的 `label` 區域來進行選擇,無需精確點擊小的 `input` 控件,從而提高整體的用戶體驗。
<br>
<hr>
<br>
## iframe
> spec: [4.8.5 The iframe element](https://html.spec.whatwg.org/multipage/iframe-embed-object.html#the-iframe-element)
### iframe 用法
- ### [HTML \<iframe\> 內嵌框架 (Inline Frame)](https://www.fooish.com/html/iframe-tag.html)
<iframe width="100%" src="http://www.fooish.com/">
你的瀏覽器不支援 iframe
</iframe>
<br>
### 來源提供者
- ### [被嵌入在 iframe 的我們如果顯示不出來要怎麼調整設定呢?](https://medium.com/%E7%A8%8B%E5%BC%8F%E8%A3%A1%E6%9C%89%E8%9F%B2/a0c5ce800bc2)
> 以 Google 為例,打開網頁檢視工具,可以看到 Google 搜尋引擎的網頁 header 設定如下:
> `X-Frame-Options: SAMEORIGIN`
<br>
### iframe 使用者
- ### 測試 https://www.google.com 範例
- Response Headers
- x-frame-options: SAMEORIGIN

- www.google.com 拒絕連線
```html
<iframe id="google" src="https://www.google.com"></iframe>
```
[](https://i.imgur.com/jYWfjRe.png)
- ### 測試 githubusercontent: html 範例
> 來源:[Plot classification probability](https://github.com/tsungjung411/jupyterlab-extension/blob/main/ml_examples/Scikit-Learn/Classification/plot_classification_probability.html)
<iframe width="560" height="315" src="https://raw.githubusercontent.com/tsungjung411/jupyterlab-extension/main/ml_examples/Scikit-Learn/Classification/plot_classification_probability.html" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
- Refused to display 'https://raw.githubusercontent.com/' in a frame because it set 'X-Frame-Options' to 'deny'.

- ### [Github gist page won't load in iframe](https://stackoverflow.com/questions/7649361/github-gist-page-wont-load-in-iframe)
> Github has added the X-Frame-Options: deny HTTP header, which prevents the page from being embedded in a page (such as a frame).

- ### 測試 githubusercontent: image 範例 (OK)
- [Embedding an image stored in github](https://stackoverflow.com/questions/52876285)
```
<img src="https://raw.githubusercontent.com/madelinekinnaird/Gerrymandr/master/images/az1.PNG"
```

- ### [Set content of iframe](https://stackoverflow.com/questions/8240101) :+1: :+1: :+1: :100:
```javascript=
var html_string= "content";
document.getElementById('output_iframe1').src
= "data:text/html;charset=utf-8,"
+ escape(html_string);
```
```javascript=
var html_string= "content";
document.getElementById('output_iframe1').src
= "data:text/html;,"
+ escape('Hello! My name is <b>Fzz</b>.');
```
- "data:text/html," 這樣也可,總之要有 `,`
- 原因在此


- ### 完整程式碼
```javascript
function loadContentViaFetch(iframeId) {
const iframe = document.getElementById(iframeId);
console.log('iframe:', iframe);
fetch(iframe.src)
.then(response =>{
console.log('response:', response);
if (response.ok) {
response.text()
.then(text => {
iframe.src = buildHtmlContent(text);
}).catch(function(errorObject) {
console.log('errorObject:', errorObject);
iframe.src = buildHtmlContent(
'<b>'+ errorObject.message + '</b>'
+'<br><pre>' + errorObject.stack + '</pre>');
});
} else {
iframe.src = buildHtmlContent('<b>' + response.statusText + '</b>');
}
}).catch(function(errorObject) {
console.log('errorObject:', errorObject);
iframe.src = buildHtmlContent(
'<b>'+ errorObject.message + '</b>'
+'<br><pre>' + errorObject.stack + '</pre>');
});
}
function buildHtmlContent(content, charset=null) {
var metadata = '';
if (charset) {
metadata = `charset=${charset}`
}
return `data:text/html;${metadata},${escape(content)}`;
}
```
- 看起來 charset 好像有編碼問題
- 沒用反而是正常
- ### 測試檔`test.htm`
> **資料來源**:Scikit-Learn (sklearn) / Classification / Classifier comparison
> - [from archive](https://scikit-learn.org/stable/_downloads/6f1e7a639e0699d6164445b55e6c116d/auto_examples_jupyter.zip)
> - [from web](https://scikit-learn.org/stable/auto_examples/classification/plot_classifier_comparison.html)
> - 關鍵字:`# Code source: Gaël Varoquaux`
>
> <br>
>
> **說明**:用 charset 反而有編碼問題
>
```html=
<iframe id="iframe1" style="width: 100%; height: 3em;"></iframe>
<iframe id="iframe2" style="width: 100%; height: 3em;"></iframe>
<iframe id="iframe3" style="width: 100%; height: 3em;"></iframe>
<script>
text = '<span># Code source: Gaël Varoquaux</span>';
iframe1 = document.getElementById('iframe1')
iframe1.srcdoc = text;
iframe2 = document.getElementById('iframe2')
iframe2.src = 'data:text/html,' + escape(text);
iframe3 = document.getElementById('iframe3')
iframe3.src = 'data:text/html;charset=utf-8,' + escape(text);
</script>
```

<br>
<hr>
<br>
## ruby
### ruby 緣由
- ### Question
```
<ruby>
私 <rp>(</rp><rt>わたし</rt><rp>)</rp>
</ruby>
```
日文漢字的假名,html 有 Ruby 語法可呈現,為何叫 ruby ?
- ### ChatGPT4
`<ruby>` 標籤在 HTML 中用於呈現東亞文字的發音標註,特別是用於中文、日文和韓文等語言。這些標註通常顯示在文字的上方或下方,提供該文字的讀音或解釋。在日文中,這種格式被稱為振假名(ふりがな, furigana),主要用於給漢字標註平假名或片假名以指示讀音。
### 為何叫 ruby?
名稱 "ruby" 的來源並不是因為寶石紅寶石(ruby),而是源於印刷和排版術語。在排版中,"ruby text" 是指出現在主要文字上方或下方的小字,用於註釋或解釋。這個名稱最初來自於英文排版術語,在英文排版中,“ruby”指的是一種小號的印刷字體,這種字體在過去曾經被用來印刷邊注或註釋。因此,當設計 HTML 標準來支持類似的文字標註功能時,這個術語被借用來命名 `<ruby>` 標籤標籤。
### HTML 中的 `<ruby>` 標籤
`<ruby>` 標籤內部通常包括三種元素:
- **`<rt>`(Ruby Text)**:用於包含每個基礎字符或字符組的發音或解釋。
- **`<rp>`(Ruby Parenthesis)**:用於在不支持 `<ruby>` 的瀏覽器中顯示括號,以便用戶能理解 `<rt>` 中的文本是註釋或發音。
例如,上述的 HTML 代碼:
```html=
<ruby>
私 <rp>(</rp><rt>わたし</rt><rp>)</rp>
</ruby>
```
這在支持 `<ruby>` 的瀏覽器中會將 "わたし" 顯示在 "私" 的上方,如果瀏覽器不支持 `<ruby>`,則會顯示為 "私(わたし)",保證信息的可訪問性。这种方式提供了对文本的额外说明,帮助读者理解文本的正确读音或意义,尤其是在学习语言阶段非常有用。
<br>
<hr>
<br>
## span
### 容器內置中對齊
> - 行內元素:不受水平對齊屬性的影響
- ### Question
```
<span>123<br>abcdefghijk</span>
```
要如何讓 `<br>` 上下兩段文字置中對齊?
- ### ChatGPT4
要使 `<span>` 標籤內的文字,包括 `<br>` 標籤前後的內容,在水平方向上居中對齊,你可以使用 CSS 來達成這個效果。通常 `<span>` 是行內元素,它不會受到水平對齊屬性的影響。為了使內部的文字居中,你可能需要將 `<span>` 改為行內塊元素或塊級元素,並適用對應的對齊屬性。
以下是一個簡單的示例,展示如何設定 CSS 使 `<span>` 內的內容居中:
```html=
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Center Text with Break</title>
<style>
.center-text {
display: block; /* 將 span 轉換為塊級元素 */
text-align: center; /* 文字居中對齊 */
margin: auto; /* 自動邊距以在容器中水平居中 */
width: 100%; /* 寬度設為 100% */
}
</style>
</head>
<body>
<div>
<span class="center-text">123<br>abcdefghijk</span>
</div>
</body>
</html>
```
### 解釋 CSS 屬性:
- `display: block;`:將 `<span>` 從行內元素轉變為塊級元素。塊級元素會佔滿可用的水平空間,並允許我們設定寬度和自動邊距。
- `text-align: center;`:這個屬性會使得所有內部文本(包括 `<br>` 分隔的文本)在水平方向上居中對齊。
- `margin: auto;`:這樣設定邊距可以使塊級元素在其父容器中水平居中。
- `width: 100%;`:將寬度設為 100% 確保 `<span>` 充滿其父元素的寬度,這樣 `text-align: center;` 才能正確居中文本。
通過這種方式,你可以使 `<span>` 標籤內的內容在斷行後仍然保持居中對齊,適用於多種布局和設計需求。
<br>
<hr>
<br>
## textarea
### 變更文字後,textContent 屬性依舊
- ### Question
```
<textarea id="abc">123</textarea>
```
為何在 textarea 變更文字,拿到的 textContent 卻依舊是 123 ?
- ### ChatGPT4
當你在 HTML 中使用 `<textarea>` 標籤時,初始的文字內容通常是在標籤之間定義的。例如,在你的代碼中:
```html=
<textarea id="abc">123</textarea>
```
123 是 `<textarea>` 的初始內容。當你通過用戶界面改變 `<textarea>` 中的內容後,這些變化實際上是反映在 `<textarea>` 的 `value` 屬性中,而不是其 `textContent` 或 `innerText`。這是因為 `<textarea>` 元素特別地使用 `value` 屬性來存儲和檢索其內容。
因此,當你嘗試使用 JavaScript 獲取 `<textarea>` 中變更後的文字時,應該使用 `value` 屬性而不是 `textContent`。以下是如何正確做到這一點的例子:
```javascript=
// 獲取 textarea 元素
var textarea = document.getElementById('abc');
// 正確的方式來獲取當前在 textarea 中的文字
var currentText = textarea.value;
console.log(currentText); // 這將顯示用戶當前在 textarea 中輸入的文字
```
這段代碼使用 `document.getElementById()` 來獲取 `<textarea>` 元素,然後使用 value 屬性來讀取和輸出用戶當前輸入的文字,無論它是否已經被改變。
如果你使用 textContent 或 innerText,你會發現它們返回的是元素創建時的內容,而不是用戶當前的輸入,這在 `<textarea>` 的情況下通常不是你想要的結果。
<br>
<hr>
<br>
## case study
### TOKENS + CHARACTERS
- ### Question1
<img src="https://hackmd.io/_uploads/SJMFGw8W0.png" style="border: 1px solid #000;"><br>
資訊是這樣:
TOKENS 23
CHARACTERS 13
但我想把它 layout 成圖片所示
- ### Q1: ChatGPT4
看來你希望將文字資訊的佈局設計成上傳圖片中的樣式。圖片顯示了「TOKENS」和「CHARACTERS」的計數,它們被佈局成兩列,數字位於文字標籤的下方。
為了實現這樣的設計,我們可以使用 HTML 與 CSS。這裡提供一個基礎的範例代碼,你可以根據自己的需求進行調整:
```html=
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Token and Character Count</title>
<style>
.count-container {
display: flex;
justify-content: space-around;
align-items: center;
font-family: 'Arial', sans-serif;
color: #213547;
}
.count-block {
text-align: center;
}
.count-number {
font-size: 2em;
margin: 0;
}
.count-label {
margin: 0;
}
</style>
</head>
<body>
<div class="count-container">
<div class="count-block">
<p class="count-number">23</p>
<p class="count-label">TOKENS</p>
</div>
<div class="count-block">
<p class="count-number">13</p>
<p class="count-label">CHARACTERS</p>
</div>
</div>
</body>
</html>
```
在這段代碼中:
- 使用了 `.count-container` 類別來創建一個 flex 容器,它會將子元素 `.count-block` 水平並排顯示。
- 每個 `.count-block` 包含一個數字(`.count-number`)和一個標籤(`.count-label`),並且將文本置中。
- CSS 被用來設定字體、大小、顏色等屬性,以符合你圖片中的設計。
如果你需要進一步的幫助或者有具體的設計需求,比如顏色、字體大小或者間距等,請告訴我,我可以提供更具體的幫助。
- ### Question2
詳細解說一下 .count-container 原理
- ### Q2: ChatGPT4
當然可以。.count-container 類別是一個 CSS 宣告,主要用於控制其內部子元素的布局和對齊方式。下面是詳細解釋:
```css=
.count-container {
display: flex;
justify-content: space-around;
align-items: center;
font-family: 'Arial', sans-serif;
color: #213547;
}
```
- **`display: flex;`**:
這個屬性將元素設定為一個彈性容器。這意味著,其直接子元素將成為彈性項目(flex items),你可以使用 Flexbox 相關屬性來控制這些子元素的位置和對齐方式。
- **`justify-content: space-around;`**:
這個屬性定義了如何沿著彈性容器的主軸(在預設情況下為水平方向)分配子元素之間以及子元素與容器邊緣之間的空間。`space-around` 的值會導致子元素周圍有相等的空間。換句話說,每個子元素將有相同大小的空間在其兩邊,使得元素之間的間距看起來均等。
- **`align-items: center;`**:
這個屬性決定了子元素在彈性容器的交叉軸(垂直於主軸)上的對齐方式。設定為 `center` 表示所有子元素都會在容器的中心線上垂直對齐。
- **`font-family: 'Arial', sans-serif;`**:
這個屬性指定了容器內所有文字的字體。如果系統中安裝了 Arial 字體,則會使用它;如果沒有,則會回退到無襯線(sans-serif)的默認字體。
- **`color: #213547;`**:
這個屬性設定了容器內所有文字的顏色,這裡使用的是一個深藍灰色的色碼。
總之,`.count-container` 是用於定義一個水平布局,其中子元素平均分散並垂直居中對齐的彈性盒子模型。这种布局非常適合用來創建像是功能區、導航菜單或資訊展示卡等元素。
- ### Question3
如果我想讓 `TOKENS` 和 `CHARACTERS` 靠在一起,並置中,但中間只間隔 3em,要如何做?
- ### Q3: ChatGPT4
為了讓 `TOKENS` 和 `CHARACTERS` 靠在一起並且置中,同時它們之間有固定的間隔(如 3em),你可以對 `.count-container` 類別和 `.count-block` 類別進行一些調整。以下是更新後的 CSS 代碼:
```css=
.count-container {
display: flex;
justify-content: center; /* 讓子元素水平居中 */
align-items: center; /* 子元素垂直居中 */
font-family: 'Arial', sans-serif;
color: #213547;
}
.count-block {
margin: 0 1.5em; /* 每個 count-block 的左右外距設為 1.5em,兩個加起來正好是 3em */
text-align: center;
}
.count-number {
font-size: 2em;
margin: 0;
}
.count-label {
margin: 0;
}
```
在這裡,我們使用了 `justify-content: center;` 來確保所有 `.count-block` 元素在 `.count-container` 中水平居中。`.count-block` 元素左右的外距(margin)設為 1.5em,這樣,當它們並排時,兩者之間的空隙會是 3em。
這個設定會將 `TOKENS` 和 `CHARACTERS` 兩個元素拉到一起並保持它們在容器中心的位置,同時它們之間會有一個固定的 3em 空隙。
- ### 背景知識
- [justify-content 屬性介紹](https://w3c.hexschool.com/flexbox/4a029043)
<br>
### radio button
- ### Question1
<img src="https://hackmd.io/_uploads/r14V6FP-A.png" style="border: 1px solid #000;">
實作圖中三個 radio button
點文字也可以選
- ### [ChatGPT4]
要實作能夠點擊文字也能選擇的 radio buttons,你需要為每個 radio button 搭配一個 `<label>` 元素。這樣,當使用者點擊標籤中的文字時,相應的 radio button 也會被選中。這裡是一個基本的實現方式:
```html=
<!-- 確保每個 radio input 的 name 屬性相同,這樣它們就會被視為一組 -->
<form>
<label>
<input type="radio" name="option" value="text">
Text
</label>
<label>
<input type="radio" name="option" value="tokenIds">
Token IDs
</label>
<label>
<input type="radio" name="option" value="hide">
Hide
</label>
</form>
```
這裡的每個 `<input>` 都被包含在一個 `<label>` 元素裡。當 ` 被點擊時,它會自動選擇或取消選擇其內部的 ` 元素。為了使 radio buttons 作為一組互斥選項工作,它們需要有相同的 name 屬性值。
如果你想要添加一些自定義樣式以匹配你的設計需求(比如上傳的圖片),你可以添加 CSS。以下是一個簡單的 CSS 樣式例子:
```css=
/* 樣式化所有的標籤和內部的 radio buttons */
label {
margin-right: 20px; /* 或你希望的任何間隔 */
cursor: pointer; /* 當鼠標懸停時顯示指針形狀 */
}
/* 隱藏原生的 radio button */
input[type="radio"] {
display: none;
}
/* 當 radio button 被選中時,使用一個自定義的圖標或背景來顯示它 */
input[type="radio"]:checked + label {
background: url('checked_icon.png') no-repeat;
/* 添加所需的 CSS 以正確顯示你的自定義圖標 */
}
```
請注意,上面的 CSS 中用到了 `background: url('checked_icon.png') no-repeat;`,這需要你有一個選中狀態的圖標圖片。此外,實際的實現會根據你的具體需求和你所擁有的圖標或設計來調整。
這個例子並不包括實際的交互邏輯或 JavaScript,如果你需要幫助來實現這一部分(比如當選項改變時執行一些操作),請提供更多的信息或詢問具體的問題。