CSS に定義されているルールが別の CSS に干渉させない現実的方法

スクラッチで構築するWEBサイトでも、運営中にスタイルが破たんする事があるとすれば、いわんやワードプレスをや なわけで、コア、プラグイン、テーマが織りなすスタイルのコラボレーションは、特別な決まりなく行われており、ちょっとしたサーカスです。

さて、そんな中で「俺流のデザインを実現する」と心に決めたあなたは、どのように破たんを免れながら、俺流のデザインを発展させていくことが出来るのか

CSS に定義されているルールが別の CSS に干渉(コンフリクト)してしまう問題はよく指摘されることです。こういった問題を運用面で工夫する方法として、BEM等、クラス属性をどのように記述すると、干渉リスクを低減できるかといった方法論が数多く提案されています。

しかし、現時点で「CSSのコンポーネント化」を完全に実現する方法はありません。firefox54まであったscopted属性等も最新バージョンではサポートされなくなったようです。(scoped

本命と目されている Shadow DOMも、ブラウザサポートが十分ではなく、現実に利用できる環境になさそうです。

現時点で、確実にCSSの干渉をコントロールするには、html5のiframeぐらいしかないのかもしれません。私には、html4のiframeへの偏見があり、自省と備忘を兼ねて、メモに残します。

html5のiframeには、srcdoc属性と、seamless属性が追加されています。

html4のiframeは、src属性にURLを指定して、外部のファイルを呼び出して表示するものでしたが、srcdoc属性を使うとiframeに表示する内容を属性値として直接記述する事が可能になりました。この中にスタイル記述する事もできるので、その要素内だけに特別なスタイルを適用することが可能になります。

IEがサポートしていないという問題はありますが(srcdoc)わずかなjavascriptで、対応させることも可能なようです。
JavaScript:iframe:外部のページを埋め込むのではなく、HTMLをそのまま埋め込みたい

seamless属性を使うと、通常コントロールできない iframe内の要素やクラスに対して、親のスタイルが適用できるようになる興味深い属性です。(条件はあります seamless 属性 )


実際に書いてみた。思ったより以上に実用的かも、Raindropsテーマのように、配色設定がたくさんあって、「どんな配色中でも、俺は、染まらない」といったブロックが必要な場合なんかでいいかも、

実際にやってみる前は、干渉させないという場面をトラブルとしてしかとらえていなかったけど、チョット新鮮

注意、Raindropsテーマ用のコードなので、読み替えお願いします。

 add_action( 'raindrops_append_entry_content', 'show_recent_posts_module' );
 
function show_recent_posts_module(){
	
	if ( is_single( 8049 ) ) {
		
		$style_args= array('--width'=>'300px', '--height'=> '100px', '--margin'=>'10px');
		$posts_args= array(
				'numberposts'=> 3,
				'post_status'=> 'publish',
			);
		echo '<h3>新着記事</h3>';
		recent_posts_module( $posts_args, $style_args );
	}
}
function recent_posts_module( $posts_args, $style_args ) {

	$element_result	= '';
	$element		= '<li><a target="_top" href="%1$s">%2$s</a></li> ';
	$id				= 'nobita' . uniqid();
	$html			= '<iframe id="%1$s" style="%4$s" allowFullScreen srcdoc="<style>%2$s</style><ul>%3$s</ul>" ></iframe>';
	$style			= '%1$s:%2$s;';

	$recent_posts	= wp_get_recent_posts( $posts_args, ARRAY_A );
	
	/**
	 * Make Style
	 */
	$style_result	= <<<CSS
		
		ul{	display:flex;	margin:0;padding:0;		flex-wrap:wrap;	align-items: center;	justify-content: center;}
		li{	flex:0 0 auto;	display:flex;	align-items: center;	justify-content: center;	border:1px solid #ccc;
			list-style:none;	background:#000;	padding:1em;	box-sizing:border-box;}
		li a{color:#ccc;}
		li:first-child{	margin-left:0;}
		li:last-child{	margin-right:0;}
CSS;

	$style_result .= ':root{';
	foreach ( $style_args as $key=> $val ) {
		$style_result .= sprintf( $style, $key, $val );
	}
	$style_result .= '}';

	$style_result .= 'li{';
	foreach ( $style_args as $key=> $val ) {
		$style_result .= sprintf( $style, ltrim( $key, '--' ), 'var(' . $key . ',' . $val . ')' );
	}
	$style_result .= '}';

	/**
	 * Content
	 */
	if ( is_array( $recent_posts ) ) {

		foreach ( $recent_posts as $recent ) {

			$element_result .= sprintf( $element, wp_get_shortlink( $recent[ "ID" ] ), $recent[ "post_title" ] );
		}
	}

	$element_result= str_replace( '"', "'", $element_result );

	wp_reset_query();

	printf( $html, $id, $style_result, $element_result, 'width:100vw;border:none;height:140px;overflow:' );
	/**
	 * Scripts
	 */
	$script= <<<JAVASCRIPT
		<script type="text/javascript">
			(function () {
				var iframe= document.getElementById("$id");
				if (iframe.contentWindow.document.body) {
					if (iframe.contentWindow.document.body.innerHTML != "") {
						return;
					}
				}
				iframe.contentWindow.document.open();
				iframe.contentWindow.document.write( iframe.getAttribute("srcdoc") );
				iframe.contentWindow.document.close();
			})();
		</script>
JAVASCRIPT;
	echo $script;
}

新着記事

コメントは受け付けていません。