the simpler answer to your question is "Yes" and I'll elaborate on this with several examples below. A <style>
tag will work wherever you place it within either the <head>
or the <body>
.
A style tag placed in the <body>
tag technically does violate HTML syntax rules, it's surprisingly common in practice, even among some larger corporations.
There are several different methods for including <body>
-level <style>
tags in your project.
1. Pure HTML <style>
tags (the static method)
If you have all the styles you need already written up and there are no dynamic pieces needed, you can simply write those styles into a <style>
tag statically and include those in the code, as seen in this example below:
<html>
<head></head>
<body>
<div class="custom-widget">
<h1>This is a title</h1>
<p>This is some text.</p>
<style>
.custom-widget {
display: block;
padding: 20px;
border: 5px double red;
}
.custom-widget h1 {
text-transform: uppercase;
}
.custom-widget h1::first-letter {
font-size: 150%;
}
.custom-widget p {
font-style: italic;
}
</style>
</div>
</body>
</html>
2. Writing the styles into a <style>
tag as text using JavaScript
If you need to load the styles into your <style>
tag dynamically and you simply need plain text styles that you will not need to change much after creating them. You can create the <style>
block and then inject the CSS styles as plain text as desired, as seen in this example below:
const counter = document.getElementById('counter');
let count = +counter.dataset.count;
const customWidgetStyle = document.querySelector('.custom-widget style'),
countdown = setInterval(() => {
if (count--) {
counter.innerText = `Importing CSS in ${count}…`;
} else {
clearInterval(countdown);
counter.remove();
customWidgetStyle.innerHTML = `
.custom-widget {
display: block;
padding: 20px;
border: 5px double red;
}
.custom-widget h1 {
text-transform: uppercase;
}
.custom-widget h1::first-letter {
font-size: 150%;
}
.custom-widget p {
font-style: italic;
}
`;
}
}, 1000);
<html>
<head></head>
<body>
<div class="custom-widget">
<h1>This is a title</h1>
<p>This is some text.</p>
<style></style>
</div>
<span id="counter" data-count="3">Importing CSS in 3…</span>
</body>
</html>
3. Creating cssRules styles into a <style>
tag using the JavaScript CSSStyleSheet.insertRule()
method
If you need even more flexibility with how you add your styles, you can use the CSSStyleSheet.insertRule()
(MDN docs), which will dynamically allow you to add and manage the styles more granularly. This may be overkill for your specific need but there's a lot of power, flexibility, and control when working with the CSSOM.
Here is an example of this method, in which I use an addStylesheetRules
function example defined on the MDN docs page for insertRule under the heading Examples, here:
const addStylesheetRules = (rules, stylesheet) => {
if (stylesheet === undefined) {
const style = document.createElement('style');
stylesheet = style.sheet;
document.head.appendChild(style);
}
for (let i = 0; i < rules.length; i++) {
let j = 1,
propStr = '';
rule = rules[i];
const selector = rule[0];
if (Array.isArray(rule[1][0])) {
rule = rule[1];
j = 0;
}
for (let pl = rule.length; j < pl; j++) {
const prop = rule[j];
propStr += prop[0] + ': ' + prop[1] + (prop[2] ? ' !important' : '') + ';\n';
}
stylesheet.insertRule(selector + '{' + propStr + '}', stylesheet.cssRules.length);
}
}
const customWidget = document.querySelector('.custom-widget'),
customWidgetStyleTag = document.createElement('style');
customWidget.appendChild(customWidgetStyleTag);
const customWidgetStylesheet = customWidgetStyleTag.sheet;
addStylesheetRules([
['.custom-widget',
['display', 'block'],
['padding', '20px'],
['border', '5px double red']
],
['.custom-widget h1',
['text-transform', 'uppercase']
],
['.custom-widget h1::first-letter',
['font-size', '150%']
],
['.custom-widget p',
['font-style', 'italic']
]
], customWidgetStylesheet);
<html>
<head></head>
<body>
<div class="custom-widget">
<h1>This is a title</h1>
<p>This is some text.</p>
</div>
</body>
</html>
Please let me know if there is any more context I can add to better answer your question.