Claude.aiの「Artifacts」、皆さん使ってますか?
HTMLの生成をお願いすると、上手にHTMLを生成してくれます。
さらに、HTMLのプレビューまで切り替えられます。
これは一体どういうテクノロジーでできているのでしょうか??
開発者ツールで確認
ブラウザの開発者ツールを使って、プレビュー部分がどうやってできているか見てみます。
すると、iFrameが見つかりました。
iFrameの「srcdoc」属性にHTMLがセットされていることがわかりました。
iFrameの仕様を確認
MDNドキュメントで、iFrameの仕様を確認します。
srcdoc属性の説明は以下のとおりです。
埋め込むインライン HTML で、 src 属性を上書きします。ブラウザーが srcdoc 属性に対応していない場合は、 src 属性の URL で代替されます。
srcdocにHTMLを埋め込むことができそうです。
やってみた
最低限のHTMLを書いてみました。Bodyの中はiFrameのみです。srcdocに太字にした文字をセットしてみました。
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<title>Page Title</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<link rel='stylesheet' type='text/css' media='screen' href='main.css'>
</head>
<body>
<iframe srcdoc="<html><b>Hello, World!</b></html>"></iframe>
</body>
</html>
期待したとおりに出ましたね。
Claudeが作ってくれたHTMLを貼り付けてみましょう
HTML
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<title>Page Title</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<link rel='stylesheet' type='text/css' media='screen' href='main.css'>
</head>
<body>
<iframe width="600" height="400" srcdoc="<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ログイン</title>
<style>
body {
font-family: Arial, sans-serif;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background-color: #f0f0f0;
}
.login-container {
background-color: white;
padding: 2em;
border-radius: 5px;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
}
h2 {
text-align: center;
color: #333;
}
form {
display: flex;
flex-direction: column;
}
label {
margin-top: 1em;
}
input {
padding: 0.5em;
margin-top: 0.5em;
}
button {
margin-top: 1em;
padding: 0.5em;
background-color: #007bff;
color: white;
border: none;
border-radius: 3px;
cursor: pointer;
}
button:hover {
background-color: #0056b3;
}
</style>
</head>
<body>
<div class="login-container">
<h2>ログイン</h2>
<form action="#" method="post">
<label for="username">ユーザー名:</label>
<input type="text" id="username" name="username" required>
<label for="password">パスワード:</label>
<input type="password" id="password" name="password" required>
<button type="submit">ログイン</button>
</form>
</div>
</body>
</html>"></iframe>
</body>
</html>
お~~~~
一見難しそうなブロック崩しも、同じ理屈でできています。
自作iFrameに移植👇️👇️👇️
おまけ
Reactでこんなのを作ると、リアルタイムで反映されて楽しいです。
import { useState } from "react"
function App() {
const [text, setText] = useState("")
return (
<>
<textarea value={text} onChange={e => setText(e.target.value)} style={{ width: "800px", height: "600px" }}></textarea>
<iframe srcDoc={text} style={{ width: "800px", height: "600px" }} ></iframe>
</>
)
}
export default App