0

Is there any easy way to take in a block of CSS from the user from an textarea and add this styling to the styling for a specific div?

See I'm creating a simple code preview tool like codePen, so far I have two textarea inputs, one for Html and one for CSS, as the user types in the Html input this updates the preview pane, this works, now I want to do it for CSS.

CSS textarea could contain a few blocks like:

h1 {
  font-size:23px;
}

.myClass {
    //Somestyle
}

Now I want this CSS to be contained in the

<div id="preview"></div>

So it doesnt effect the rest of the page, so a manual example would be

$('preview h1').css('font-size','23px');

Anyway to automate this?

4
  • what are you using for jQuery or JS to do this now...or do you want users to just write it for you? Commented Mar 6, 2014 at 17:27
  • 2
    Are you open to using an iframe instead? Commented Mar 6, 2014 at 18:10
  • Indeed as @Jacob suggests, an iframe seems like a good idea, and is what sites like jsfiddle or jsbin use... Commented Mar 6, 2014 at 18:11
  • Thanks for the reply, at the moment I'm simply updating the HTML preview by waiting until keyup stops for 3 seconds, this simply pulls the content from the text area and inserts it into the preview pain like so: var content = $('#textareaId').val(); $('#preview').html(content), of course I'd be open to using an iframe from the preview if this would be a feasible approach could you describe how this may be done? And would the preview reload be lagging. Commented Mar 7, 2014 at 0:32

4 Answers 4

1

Do it like this. Hope it works.

Add a style block for dynamic styling.

<style id="dynamicCss">
</style>

on the apply button click handler, set the style

$('#btnApplyStyle').click(function(){
   $('#dynamicCss').html('').html($('#txtaCustomCss').val());
});

See the Fiddle here. Please use developer tools to see the new style tag added to head section.

This script simply adds rule to the document. If you don't want that behavior, you can use this plugin in combination with my logic to set scope for rule. You will need to place the style tag inside of the container and add a scoped attribute to style for it to work. Please see the documentation.

Sign up to request clarification or add additional context in comments.

4 Comments

That would work also but it will affect all the DOM on the page no? =S
Definitely. This script simply adds rule to the document.
That looks sweet!, thanks for the feedback, I't does more than I need, I'd still like to find out how this is done w/o digging into that code for the plugin my JavaScript is limited at present.
Thanks. If you want to apply scope to the rules, then I think you will manually need to modify the selectors in custom CSS rules to prepend with the container selector. Like if the textbox rule is .custom{...} then you will need to manually change it to #container .custom{...} and like that. Will require more complex logic and script than the one in this answer.
0

If you want to use the iframe approach instead, you'll first need an HTML document to host inside of the iframe. The iframe document should be loaded for the same origin (protocol + domain) as the host document (cross-document cross-domain stuff is tricky otherwise). With your application, this is probably not an issue.

Host page:

<iframe id="preview" src="preview.html"></iframe>

To make things easier on yourself, this iframe document could load a script with convenience functions for injecting the HTML and CSS from the host.

preview.html:

<html>
    <head>
        <script src="preview.js"></script>
        <style type="text/css" id="page-css"></style>
    </head>
    <body></body>
</html>

preview.js:

function setHTML(html) {
    document.querySelector('body').innerHTML = html;
}

function setCSS(css) {
    var stylesheet = document.querySelector('#page-css');

    // Empty the stylesheet
    while (stylesheet.firstChild) {
        stylesheet.removeChild(stylesheet.firstChild);
    }

    // Inject new CSS
    stylesheet.appendChild(document.createTextNode(css));
}

Now, from the host page, you can call these functions whenever your text inputs change:

document.querySelector('#preview').contentWindow.setCSS(someCSS);

1 Comment

thank you very informative,I will try and implement this tomarrow!
0

This plugin may come in handy: https://github.com/websanova/wJSNova/downloads .

Comments

0

Edited

Insert the text of the rules in one of the existing cssStyleSheets you have.

It will be something like

window.document.styleSheets[0].insertRule("a{color:red;}",window.document.styleSheets[0].cssRules.length)

The first parameter is the rule to insert and the second is the index.

Fiddle

The only problem here is that this will affect all the DOM on the page maybe looking for a way to add the #preview before each css rule to get something like

 #preview h1{}

2 Comments

I believe that's not possible.
You're right i thought that it was only needed to add the css property to the h1.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.