WordPress.org

Make WordPress Core

Opened 20 months ago

Closed 10 months ago

Last modified 7 months ago

#35395 closed feature request (fixed)

Provide a better gateway for code-based theme customizations with the Customizer

Reported by: celloexpressions Owned by: johnregan3
Milestone: 4.7 Priority: normal
Severity: normal Version:
Component: Customize Keywords: has-screenshots needs-patch
Focuses: Cc:

Description

The Theme Editor represents an important part of WordPress' mission to democratizing publishing, acting as a gateway for introducing users to their ability to create literally anything with WordPress by editing and writing code. Many developers of all abilities (including myself) got their start with PHP or other related technologies by editing themes with the theme editor in the WordPress admin.

At this point in the development of the WordPress ecosystem, we can do a much better job of introducing users to code-based customization for their sites. This ticket proposes leveraging the Customizer to offer instant live previews of code-based changes for improved user experience. Rather than blindly making edits that can completely take down a site where the user potentially has no idea what FTP even is, every change is instantly previewed and no changes are published until the user is ready to push them live.


Proposed solution: Custom CSS + Links to resources outside of core

WordPress can't reasonably teach users much about code within the software (although a plugin that does so would be very interesting to see). Additionally, when bridging the gap between advanced user and beginning developer, desired changes are likely to be limited to visual tweaks that are primarily theme-related. Therefore, I'm proposing to limit the scope of this new feature to a custom CSS editor.

The CSS editor would take inspiration from the many plugins (including Jetpack) offering similar solutions, but with an updated solution that offers instant previewing in the Customizer via postMessage setting transport. This is core territory rather than plugin territory because it is designed as the next generation of the existing theme editor in core, with a more refined feature set and more user-oriented focus. The theme editor is not proposed to be removed at this time, although that could be a future possibility depending on a variety of factors. Plugins could continue expanding this feature to incorporate additional uses.

Storing the CSS as a theme_mod facilitates custom CSS being theme-specific. However, the editor would be used to override theme styles rather than editing them directly to avoid the awkward experience of telling users that they can make changes but they may get overwritten during updates, which the theme editor does. Instead, custom CSS safely stays available on a per-theme basis after updating and switching themes. Other solutions such as a custom post type make the notion of having different sets of CSS styles for different themes difficult to implement. Projects such as Customizer Transactions (#30937, which would actually use post objects) and revisions for Customizer settings (#31089) would bring benefits offered by the custom post type approach to this feature, while storing the data in a more logical theme-related way.

To improve the user experience further, it is critical that a link to documentation and resources for learning CSS be included with useful help text inline alongside the CSS editor. This could initially be a codex page but would ideally live on a user or developer handbook of some sort eventually. Inline text must be much more succinct than the help tab on the existing theme editor, conveying what CSS is, where to learn about specific rules, and explaining that it's specific to each theme in only a few lines. My initial proposal is in the screenshots below.

Considering next steps when users begin moving beyond the basics of what can be done within a custom CSS editor like this, I also suggest providing an additional piece of help text underneath the editor (potentially only once a certain threshold of content is reached - the exact measure could be rough). Such a friendly tip could convey that if they're making a lot of progress with CSS, they should consider learning more about themes, child themes, storing CSS in files, etc. via an external link to a resource on WordPress.org. On multisite installations we would likely never show this message since the user probably can't make code changes there outside of this CSS editor. As with any customizer feature, custom CSS could be disabled with remove_section() on sites where administrative access is to be limited.

Technical Considerations with the initial patch:

  • Should we sanitize & validate user-input CSS? I believe the current theme editor doesn't do anything, and worst case scenario we could set up similar capability restrictions.
  • Should we include syntax highlighting? There are libraries available, if we want it it would require a compatible license or we could also roll our own. May be a future enhancement for later.
  • The patch leverages the existing textarea control for simplicity, as well as introducing a new core control type for help text. If we want to add syntax highlighting or other usability improvements such as vertical auto-resizing for the editor to avoid double scrollbars (since this is the only option in the section), we can do a custom control instead.
  • While we could bump the editor out of the standard Customizer sidebar to provide more horizontal space, the short line lengths typical in CSS lend themselves nicely to the amount of space provided by default.
  • I included help links within the translatable string as they would need to be localized; we may need to break these out separately though?
  • We should probably create a new page introducing CSS for the first link - nothing on the codex or handbook currently fits this purpose. There's a decent explanation on WordPress.com that could potentially be adapted and expanded in the theme developer handbook: .https://en.support.wordpress.com/custom-design/css-basics/
  • Live preview is not working when previewing a theme, I'm not sure why. It does work if the theme previously had custom CSS in it.

Attachments (12)

customize-css.diff (5.3 KB) - added by celloexpressions 20 months ago.
First pass.
customize-css-desktop.PNG (158.4 KB) - added by celloexpressions 20 months ago.
customize-css-mobile.PNG (263.1 KB) - added by celloexpressions 20 months ago.
35395.validation.gif (624.7 KB) - added by celloexpressions 13 months ago.
See 35395.diff.
35395.diff (8.2 KB) - added by celloexpressions 13 months ago.
Add validation for unclosed code comments and unbalanced braces. Also adds a shell sanitization function.
customizer-css-i2.png (765.9 KB) - added by folletto 11 months ago.
Customizer CSS design i2
35395-20161005.png (111.7 KB) - added by johnregan3 11 months ago.
35395 - 5 October 2016 screenshot
35395-notifications-demo.gif (1020.7 KB) - added by johnregan3 11 months ago.
Demonstration of firing notifications on save
35395-06-oct.gif (1.2 MB) - added by johnregan3 11 months ago.
Today's Demo. Note the new ability to use the help icon on Section titles, as well as the monospaced font to help indicate this is a code editor.
customizer-css-i2-mvp-reduction.png (97.6 KB) - added by folletto 11 months ago.
customizer CSS i2, MVP milestone
35395-line-numbers-07-oct.gif (2.7 MB) - added by johnregan3 11 months ago.
@folletto @cellodesigns - Here are the line numbers! You'll note the numbered column is a bit wider than in the comps. This is so it can be up to 3 characters wide (like "999").
35395-17-oct.gif (875.2 KB) - added by johnregan3 10 months ago.
Latest implementation. Note that we've opted to not create a new Code Editor control, so we're using a full-width textarea. This gif also demonstrates the basic validation we've added as well.

Change History (114)

@celloexpressions
20 months ago

First pass.

#1 @adamsilverstein
20 months ago

Haven't tried the patch yet, love the idea! +1

#2 @rabmalin
20 months ago

I really like the idea. When developing theme, it is generally considered as plugin territory. But I like to take it as an essential theme component. I always implement this feature in all my themes.

  • We should absolutely sanitize the input. In theme I use wp_filter_nohtml_kses() or wp_strip_all_tags(). But problem arise when escaping. May be we need to devise special escaping function considering some possible characters like ', ".
  • I would go for custom control for Custom CSS so that we can have larger scope for advancement like syntax highlighting, linting, line numbers, etc in the future.

This ticket was mentioned in Slack in #core by celloexpressions. View the logs.


20 months ago

#4 @ocean90
20 months ago

  • Keywords needs-patch added; has-patch removed

We should absolutely sanitize the input.

We've to validate and sanitize on input and output. Twenty Fifteen had stored unfiltered CSS but it got removed, see #30409 for background.

wp_filter_nohtml_kses()/wp_strip_all_tags are not enough for this use case. For inspiration you should take a look at Remote CSS Plugin, source available at https://meta.trac.wordpress.org/browser/sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-remote-css.

#5 @celloexpressions
19 months ago

More specifically, looks like that's just using whatever is in Jetpack: https://meta.trac.wordpress.org/browser/sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-remote-css/app/synchronize-remote-css.php#L51. Also suggested in the comment as an alternative: https://github.com/google/caja. Jetpack seems to use CSStidy, which seems excessive for core to say the least: https://github.com/Automattic/jetpack/tree/master/modules/custom-css/csstidy, https://github.com/Cerdic/CSSTidy.

Since this feature is proposed to fill similar uses to the existing theme editor, what arguments are there for being more careful here than there? Is it related to storing information in the database rather than directly in files? Can you clarify what specifically needs to be done beyond what wp_filter_nohtml_kses() / wp_strip_all_tags do?

Let's make sure any of these requirements or assumptions are clearly spelled out here so that we can come up with the simplest safe solution for core.

#6 @celloexpressions
19 months ago

  • Keywords dev-feedback added

Digging through the history of the sanitization issue with Twenty Fifteen, looks like the primary conversation is here: https://wordpress.slack.com/archives/core-themes/p1418320601000063.

Parsing that out, I think the best option is to add a sanitize_css function to core. If CSS is in fact as insecure as past discussions make it seem, this is a critical need/security hole in the countless themes and plugins that store unsanitized CSS in the database. If the people that were unaware of the security issues with this type of thing in the above-linked conversation were not familiar with it, I highly doubt that the majority of theme and plugin developers are. As a theme/plugin developer, doing no sanitization seems like the best/easiest option, but if core had sanitize_css, it would be easy to implement in those situations.

The rest of that discussion centered around an alternative solution for Twenty Fifteen, since it didn't really need to store its information as CSS. That's not the case here. Other than CSSTidy, I haven't found any specifics on what we would need to do for sanitize_css. However, breaking CSS into an array and then back out seems to be part of the process?

We need direction on what exactly we need to do in a sanitize_css function`, or if we should try something else, likely from @nacin and/or @ocean90. @mikeschroder also suggested a make/core post for additional discussion on this subject; once we can get an idea of what will be needed in terms of sanitization, we can bring these decisions and the proposed feature as a whole up for broader discussion there.

#7 @westonruter
18 months ago

  • Milestone changed from 4.5 to Future Release

This ticket was mentioned in Slack in #themereview by celloexpressions. View the logs.


13 months ago

#9 @celloexpressions
13 months ago

I'd really like to spend some time putting together a secure solution here soon so that we can get this into 4.7. But it's still unclear what exactly is required. If anyone can provide direction based on the questions in 5 and 6 that would be much appreciated.

@celloexpressions
13 months ago

Add validation for unclosed code comments and unbalanced braces. Also adds a shell sanitization function.

#10 @celloexpressions
13 months ago

  • Keywords has-patch has-screenshots added; needs-patch removed

35395.diff adds basic validation for balanced braces and unclosed code comments, providing user feedback when either of those common mistakes occur. It also adds an outline for sanitize_css.

CSSTidy checks everything against a whitelist of allowed properties and values. That seems wildly inappropriate for core, as we'd need to maintain the whitelist as CSS evolves. It also optimizes the CSS, which probably isn't necessary given the purpose of this feature.

What exactly is required for sanitizing CSS? @ocean90 @rabmalin do you have any additional information here? Let's put together an approach that is secure but doesn't go overboard and beyond the scope of security to unnecessarily modify the user's input.

This ticket was mentioned in Slack in #core by celloexpressions. View the logs.


12 months ago

This ticket was mentioned in Slack in #core-customize by celloexpressions. View the logs.


12 months ago

#13 @celloexpressions
12 months ago

Per the discussion in the customize meeting, linked above, we're planning to move forward with CSSTidy in core to support this and handle sanitization.

Additionally, due to problems with the amount of data stored in options, we'll need to use a post type with a post for each theme, which would also provide revisions directly.

While we'd ideally also bundle a code editor for this, that part isn't required for a first pass. We'll need to find the best 3rd-party CSS editor, or perhaps make our own since we only need CSS (see previously [14527]).

I probably won't have time to flesh out those pieces for 4.7; is anyone else interested in picking this up?

#14 @johnregan3
12 months ago

I'd be glad to take this one. As some of you may know, I've been working on similar functionality for the Simple Custom CSS plugin. https://github.com/johnregan3/simple-custom-css/pull/20

Last edited 12 months ago by johnregan3 (previous) (diff)

#15 @celloexpressions
12 months ago

  • Keywords needs-patch added; has-patch removed
  • Milestone changed from Future Release to 4.7
  • Owner set to johnregan3
  • Status changed from new to assigned

Thanks @johnregan3! Assigning to you and putting into 4.7 for now; we have at least a month before we'd need a complete patch to iterate on to make the 4.7 timeline. This would be considered a project, needing to be merged by the deadline prior to beta 1.

35395.diff is a decent starting point for the customizer integration with previewing via JS and selective refresh. There is major work to do now though, based on this week's meeting:

  • Integrate with CSSTidy and bundle CSSTidy with core. CSSTidy is licensed under GPL 2.1 or later; we need to verify if this is compatible with WordPress' "2 or later". Perhaps whoever manages the bundling of CSSTidy with Jetpack can assist with any other considerations here as well.
  • Leverage CSSTidy for sanitization, improve validation.
  • Use a custom post type for the setting, with a post associated with each theme. Leverage revisions here, but don't show any revisions UI for now.
  • Find or create documentation links for the proposed links in the UI.
  • (if time allows) integrate a code editor, and build a custom code editor control for it (needs research).

#16 @joyously
12 months ago

I didn't read all of the Slack discussions, but what is missing in these comments is

  1. Some indication of the order of the CSS being added. Does it come first before theme CSS or last or in between?

Since the C in CSS is cascading, when it is emitted is quite important. It could be a user option to have this CSS come out first or last. And this probably needs to be explained a little bit in the Help text.

  1. How is this CSS added? If it is stored in a post type, does the theme add it with bracketing style tags? Or does core do that? Or are the style tags part of the post content?

If the CSS were stored in a file, it would be included with a style tag with a src attribute. Any HTML tags in there would be CSS syntax errors. But if it is included inline with a plain style tag, the user could put an ending style tag and then other HTML including script tags, which would be valid. This is where security problems would arise.

#17 @westonruter
12 months ago

  • Keywords dev-feedback removed

@joyously the customizer-supplied CSS should be printed _after_ any enqueued stylesheets are printed. So it would come last in the cascade. I don't think there should be an option to come first, but rather to decide it comes last.

And yes, we talked about using a new custom post type for storing the theme CSS. The CSS would be stored in post_content and each theme would have their own instance of this post type to store the CSS for that theme (like a theme mod is tied to the theme). The post_content would not include the <style> tag. I would think the CSS would be printed into the document as a <style> element as opposed to link an external stylesheet, but maybe not. The CSSTidy library would ensure that only valid CSS is saved to avoid an XSS vulnerability as you've described.

#18 @joyously
12 months ago

@westonruter I think you have assumed there is no reason to ever need some CSS before all the other CSS? What about cases of avoiding a "flash of unstyled content"? or a small animation that is visible while the page loads? or other scenarios I haven't thought of? Anyway, it seems like the user should be able to choose.

And as for CSSTidy, do you actually have a good version to use? The one on GitHub is old, and the one I found that checks CSS online is also. I didn't try the GitHub one, but the online one (csstidyonline.com) did not reject my test of putting a couple of HTML tags in between two style blocks. It just complained about text-shadow; like I said, old.

I was not remarking on the use of a post type to store the CSS, except for how it would be emitted. But now that you mention it, I don't really like the idea of having styles stored separately from the theme. It makes it more difficult to duplicate or move the design to a different site. It's bad enough that the menus and widgets are tied by names to the theme, so they can't be generic. You have to configure them for each theme -- such a hassle. Adding more ways to store theme specific data seems like a bad idea.

#19 @westonruter
12 months ago

@joyously The vast majority of uses for this functionality would surely be wanting to tweak the styles of a theme's stylesheet. That is, to override and extend the cascade. If a user is experienced enough to know about FOUC then they'd just as well add that to their functions.php to output at the top of wp_head. That's my opinion on that.

I am not familiar with the state of CSSTidy. I just know that it is used by Jetpack for their CSS editing module.

As for storing the CSS in a custom post type as opposed to directly in a theme mod, the reason for doing this is for scalability. It is conceivable that a lot of CSS could be dumped into such a field and since theme mods are just options and also _autoloaded_ options, it is important that unbounded blocks of CSS to not be included in the theme mod itself. If the Memcached object cache plugin is used, and there are several themes that have lots of CSS, then the 1MB limit for a cache bucket could be breached and the site could crash since alloptions would no longer be cacheable. As for data portability, I don't think that will cause a problem. Consider the CSS being stored in a new post type called theme_css, where each theme has one and only one theme_css post created. The post_name for these posts can exactly correspond to the theme that it is associated with. In that way, the theme_css posts could be exported via the normal XML exporter and imported on another site, and the would then automatically be recognized because they'd have the post_name wouldn't change.

#20 @joyously
12 months ago

@westonruter said "The vast majority of uses for this functionality would surely be wanting to tweak the styles of a theme's stylesheet."
This is conjecture. I would submit that the novices would want the theme to do it, and just switch themes to get one that looks better. More experienced users would use a plugin to add CSS or find a theme with that option. Advanced users write their own theme or child theme, and don't need this at all. I would also submit that while it makes sense that the CSS must match the HTML that the theme outputs, this type of feature is more useful as a way to keep something constant regardless of theme. I could see users putting tweaks to plugin CSS in there and then having a big problem when they switch themes. I can also see theme support forums having a lot more issues because of the new place to store CSS that overrides all others (comes last).

I have a client that is a WordPress novice. I styled their site as they requested and the next year, they decided to switch themes without telling me. Most of their site was still operational, but widget areas were different and menu locations were different, so some of the content was missing or needing adjustment. I discovered this, not them. The novice expects all the content to be constant, and just the look to change, as advertised. It currently doesn't work that way, and the proposed change exacerbates the problem.

If this is really an area that core should be doing, why not make it theme independent? Or at least provide an option for that?
If it has to be theme specific, have you considered that the post type is like an attachment and the CSS is actually stored in a file? This way the storage is easier (CSS can be difficult to get into the database correctly), and the inclusion in the header is better (using the src attribute), and the browser can cache the file and it can be served zipped.

#21 @celloexpressions
12 months ago

@joyously as the ticket description explains, this feature is targeted at inexperienced users who are looking to customize their site beyond any options that the current theme provides, primarily with smaller tweaks. In nearly all cases, the changes they'll want to make are dependent on markup and styling provided by the theme, so the CSS should be scoped to the current theme. There are many plugins that offer custom CSS options, many of which will allow for plugin-related styling that persists across themes. For the core feature, we need to keep the experience as simple as possible.

#22 @johnregan3
12 months ago

  • Keywords dev-feedback added

@celloexpressions @westonruter @joyously
Based on my personal experience with this type of feature, I do agree with @joyously that many users would like to use this feature for theme-independent styles, as most would cover the style of their theme within the theme itself.

Perhaps we should add a subpanel after clicking on "Custom CSS" that allows the user to choose between Theme CSS and General CSS (theme-independent), which would then take them to separate CSS editors.

Your thoughts?

This ticket was mentioned in Slack in #core-customize by celloexpressions. View the logs.


12 months ago

#24 @johnregan3
12 months ago

CSSTidy hasn't been updated since 2007 (http://csstidy.sourceforge.net/changelog.php). Naturally, this is a problem since it does not support CSS3.

There are a couple of forks out there, but it would take some time to review their work if we were to go with any of them. Plus, we'd want to contact the author before using them. Not sure if this is really a viable option at this point.

This ticket was mentioned in Slack in #core-customize by johnregan3. View the logs.


12 months ago

#26 @celloexpressions
11 months ago

Is the Jetpack version of CSSTidy somewhat up to date? I remember seeing some changes related to CSSTidy allowed properties in a changelog recently.

This ticket was mentioned in Slack in #core-customize by celloexpressions. View the logs.


11 months ago

This ticket was mentioned in Slack in #core by celloexpressions. View the logs.


11 months ago

#29 @celloexpressions
11 months ago

The latest patch is being developed and reviewed inline here: https://github.com/xwp/wordpress-develop/pull/154. We need dev-feedback on the two proposed bundled libraries in particular: CSSTidy and CodeMirror.

#30 @ocean90
11 months ago

Something to look at: Tailor includes a Custom CSS module in the Customizer. Demo: https://youtu.be/tfMyLMuaXjI?t=2m45s

Direct links to the source:

It looks like it doesn't sanitize custom CSS though.

#31 @celloexpressions
11 months ago

There are numerous popular CSS plugins, many of which leverage the customizer: https://wordpress.org/plugins/search.php?q=css. At a glance many (most?) don't sanitize CSS. I should note here that probably the most popular is @johnregan3's, which has over 300,000 active installs (and his work to add customizer support transitioned into working on this for core).

The combined popularity of these plugins is a strong argument for a core need for this functionality, especially when considering that it is an improvement over and extension of the existing code editors in core. If we can move forward with bundling the two libraries we need (CSSTidy and CodeMirror), the core solution will offer a better combination of security and user experience than any plugin currently does (some use the customizer with instant postMessage previewing, some have code editors, some save CSS as posts, some sanitize, but I don't think any do all of those things).

Looks like Tailor also uses CodeMirror; seems like that's a good option here.

#32 @joyously
11 months ago

If you decide to make the CSS theme-specific, could there also be some sort of indicator that the CSS exists, perhaps on the theme list page? Especially for novices, but also for experts that support novices, it would be so useful to be able to see at a glance which themes are 'tainted'.

This ticket was mentioned in Slack in #core-customize by celloexpressions. View the logs.


11 months ago

#34 @johnregan3
11 months ago

For those looking for information about CSSTidy and CodeMirror, here are the links:

http://csstidy.sourceforge.net/
Jetpack is using a modified version of CSSTidy separate from what is found on the official CSSTidy download page. As discussed previously, the version on the site was last updated 2007, but Jetpack's version was updated at least in 2010 to support CSS3. (See here: https://github.com/Automattic/jetpack/blob/master/modules/custom-css/csstidy/class.csstidy.php)

https://codemirror.net/
CodeMirror packages can be customized to support only the features you need, so the download can be restricted to only CSS, if we so desire. Furthermore, that package can be expanded in the future to include other preprocessors if we eventually go that route.

This ticket was mentioned in Slack in #core by celloexpressions. View the logs.


11 months ago

#36 follow-ups: @azaozz
11 months ago

I am pretty firmly against introducing another way for adding "hacks" to WordPress.

The Theme Editor represents an important part of WordPress' mission to democratizing publishing

No, it doesn't. It has nothing to do with democratizing publishing. All it does is making it a bit easier for users to "shoot themselves in the foot".

I'm actually thinking we should be discussing shipping WordPress with define( 'DISALLOW_FILE_EDIT', true ); in wp-config. The explanation in the codex makes a lot of sense:

Occasionally you may wish to disable the plugin or theme editor to prevent overzealous users from being able to edit sensitive files and potentially crash the site. Disabling these also provides an additional layer of security if a hacker gains access to a well-privileged user account.

In my opinion adding "theme hacks" through the customizer is plugin material, and the plugin should be able to provide adequate support to users that break their sites.

Apart from the above there are several other things that are pretty bad:

  • Inadequate space for editing/writing. Try resizing your coding (text) editor to 275px width and edit something for 10-15 min. It's really bad.
  • "Deceiving" preview. CSS hacks affect the whole site but the user can see only one template in the preview. For example it is pretty easy to make a change that "looks good" on the front page but breaks the archive pages, etc.

In addition there is no good way to make the user entered CSS "secure". CSSTidy and similar tools can check/fix the syntax but cannot sanitize the CSS for security purposes. I'm not sure such tools exist. New versions of the browsers introduce support for new CSS features pretty much every month. Don't think it is feasible even trying to sanitize all of them. The only way would be to severely limit what is supported then parse the CSS and remove everything else.

Last edited 11 months ago by azaozz (previous) (diff)

#37 in reply to: ↑ 36 ; follow-ups: @celloexpressions
11 months ago

Replying to azaozz:

The Theme Editor represents an important part of WordPress' mission to democratizing publishing

No, it doesn't. It has nothing to do with democratizing publishing. All it does is making it a bit easier for users to "shoot themselves in the foot".

I'm actually thinking we should be discussing shipping WordPress with define( 'DISALLOW_FILE_EDIT', true ); in wp-config. The explanation in the codex makes a lot of sense:

I've pretty consistently heard from project leadership over the years that there is no chance that the theme/plugin editors will go away or be turned off in core, and serve an important purpose similar to what I've described here. Is this opinion shared by other lead developers or solely yours? Or am I recalling that incorrectly, and if so, why are these editors still on by default in core?

In the future, this type of feedback from a lead developer should come sooner than nine months into a project if at all possible. I would also hope that this project could eventually lead to a compromise where the more dangerous, less user-friendly way to start customizing a site with code can be moved to a plugin. The purpose of this project is to make it harder for users to shoot themselves in the foot when they need to make code-based customizations.

In my opinion adding "theme hacks" through the customizer is plugin material, and the plugin should be able to provide adequate support to users that break their sites.

There's a big terminology difference between "hack" and customization. Being CSS, the focus is on visual adjustments, or customizations, and I wouldn't describe those types of changes as hacks, but maybe that's just me. This is also not unlike the way child themes are designed to extend and customize parent themes.

As I mentioned above, there are easily enough plugin-based solutions (and even many in themes) to justify a core solution. I would also anticipate there being less of a support burden throughout the ecosystem with something like this, as support volunteers already using CSS as needed would no longer need to get the user set up with a plugin to add it, and those that previously suggested edits in the theme editor where the could have taken the site down may be able to suggest this feature instead.

Apart from the above there are several other things that are pretty bad:

  • Inadequate space for editing/writing. Try resizing your coding (text) editor to 275px width and edit something for 10-15 min. It's really bad.

Line lengths are generally pretty short for CSS specifically. The width is also variable based on device size (potentially even more so with my proposal on #32296). We shouldn't make feature decisions based on the current customizer UI, which could always change; we could also bump the textarea out to be wider if we feel that that's more important than maximizing the size of the preview in this instance.

  • "Deceiving" preview. CSS hacks affect the whole site but the user can see only one template in the preview. For example it is pretty easy to make a change that "looks good" on the front page but breaks the archive pages, etc.

Users can navigate to different pages on their site within the preview, and even preview different sized screens as they customize the CSS. Perhaps the help text associated with this feature should explicitly suggest doing that? By leveraging the customizer framework, we can provide a much better and less-likely-to-break-things environment for the user than other solutions.

In addition there is no good way to make the user entered CSS "secure". CSSTidy and similar tools can check/fix the syntax but cannot sanitize the CSS for security purposes. I'm not sure such tools exist. New versions of the browsers introduce support for new CSS features pretty much every month. Don't think it is feasible even trying to sanitize all of them. The only way would be to severely limit what is supported then parse the CSS and remove everything else.

I can't provide much input here, but surely this can't be worse in terms of security than being able to edit PHP files directly within the theme and plugin editors? We can decide what the appropriate capability is here, such as edit_files, if that helps.

#38 in reply to: ↑ 36 @joyously
11 months ago

Replying to azaozz:

I am pretty firmly against introducing another way for adding "hacks" to WordPress.

My sentiments exactly. I spent 2 years as a moderator of a popular theme forum, and most of those users had no clue what CSS is or what to type in this new editor. Having yet another place to look for CSS will make it that much harder for support.

Apart from the above there are several other things that are pretty bad:

  • Inadequate space for editing/writing. Try resizing your coding (text) editor to 275px width and edit something for 10-15 min. It's really bad.

The editor space needs to be adjustable. And at the point of editing, it's best to be able to see the HTML of a page, not the rendering. How else will you know what selectors to use?

  • "Deceiving" preview. CSS hacks affect the whole site but the user can see only one template in the preview. For example it is pretty easy to make a change that "looks good" on the front page but breaks the archive pages, etc.

And how do you preview/test the responsiveness of your CSS (desktop, mobile)?

In addition there is no good way to make the user entered CSS "secure".

I addressed this issue earlier, but I don't know if anyone "got" it. If the CSS lives in a file, then anything not CSS in there is a CSS error instead of treated as HTML.

If it has to be theme specific, have you considered that the post type is like an attachment and the CSS is actually stored in a file? This way the storage is easier (CSS can be difficult to get into the database correctly), and the inclusion in the header is better (using the src attribute), and the browser can cache the file and it can be served zipped.

#39 follow-up: @ThemeZee
11 months ago

I would like to add my perspective as a theme author here.

I agree that the Theme Editor is bad for users. I wish it would be removed. Users should not be able to edit PHP files, because they can easily break their sites.

But I'm a really huge fan of adding a CSS Editor to the Customizer. I support my themes via email, wordpress.org forums and wordpress.com forums. I often provide CSS snippets as long as it is only some small visual customizations the user wants. I think WordPress users get in contact with CSS all the time, because we as developers often provide them with CSS code. Just look at the forums.

Now a lot of themes include Custom CSS settings in their themes. There are also several very popular plugins for these. For me this only means that many users need this feature. A Core solution could improve the UI for users, because the CSS options are always at the same location. It will also handle sanitization and security much better than all the custom implementations in themes.

WordPress.com gives users the possibility to add CSS code in the Customizer: https://en.support.wordpress.com/custom-design/editing-css/
I think they should have some real user data that CSS options in the Customizer work well for users.

I do not agree that users should not make CSS customizations. They can not break anything here like with the Theme Editor. The WordPress Backend will always work fine, and if they do not like their customizations they can always remove the CSS code.

#40 in reply to: ↑ 37 @azaozz
11 months ago

Replying to celloexpressions:

I've pretty consistently heard from project leadership over the years that there is no chance that the theme/plugin editors will go away or be turned off

Right, I think it was quite clear: I would rather discuss turning the file editors off instead of adding another way to add theme hacks. Yes, the currently standing decision is to leave the file editors be. They are useful in cases where a quick fix to a template or plugin is needed in order to get a "live" site back on. They are not good for permanently adding hacks to themes or plugins.

The implementation here is to allow permanent changes to the theme's styles. These changes may break the site when updating the theme. I don't think we need to introduce another pain point on updating the theme.

The purpose of this project is to make it harder for users to shoot themselves in the foot when they need to make code-based customizations.
...
There's a big terminology difference between "hack" and customization. Being CSS, the focus is on visual adjustments, or customizations, and I wouldn't describe those types of changes as hacks, but maybe that's just me. This is also not unlike the way child themes are designed to extend and customize parent themes.

I don't agree. Don't think the term "code-based customizations" makes sense. Currently most of the popular WordPress themes and plugins are produced by several developers/companies, are quite "mature", and usually have pretty good support. From development point of view they are at the same level as core (if not better). Adding code hacks to them is pretty similar to hacking core files. Furthermore a lot of themes are being developed by using CSS preprocessors. Overriding the CSS by hand there is even harder and more error-prone.

  • Inadequate space for editing/writing. Try resizing your coding (text) editor to 275px width and edit something for 10-15 min. It's really bad.

Line lengths are generally pretty short for CSS specifically. The width is also variable based on device size (potentially even more so with my proposal on #32296). We shouldn't make feature decisions based on the current customizer UI, which could always change; we could also bump the textarea out to be wider if we feel that that's more important than maximizing the size of the preview in this instance.

Right. Fixing and improving the customizer UI and UX is much more important than adding a feature that will benefit only a small amount of users. On top of that this feature is already available in plugins so the users that need it already have it.

Even if this finds its way in core, I don't think it needs a preview. As far as I see there are two general user cases:

  1. The users try to change/override some CSS in the theme to perhaps change some colors or hide a component.
  2. The users receive a CSS snipped specific to their theme (by the theme author or from support) and want to add it to the site. See comment 39 above.

In the first case the users will actually need to edit the CSS. However doing that without seeing/knowing the current CSS structure and selectors is pretty much impossible. Anybody that is even a little familiar with CSS would know to open the browser tools and try the changes there. The browser tools are also a lot more comfortable when "hacking" any CSS. You can see all styles and selectors, there is autocomplete, error highlighting, instant preview, etc. We will never be able to match that, and don't really need to. There is no point in adding CSS Editor to WordPress.

In this case the users will "compose" their hacks in the browser tools and would only need a place to add them to their sites. In the second case the users will also only need a place to add the snipped (as they don't know how to edit CSS).

In both cases all of the templates would have to be checked for bad CSS interactions. Having a preview increases the chance for the user to believe that everything is okay, i.e. the preview can be "deceitful". I'd rather avoid that.

I also think that there are themes that would want to prevent the users from (easily) changing their CSS. An officially supported child theme would make much more sense in these cases.

...surely this can't be worse in terms of security than being able to edit PHP files directly within the theme and plugin editors? We can decide what the appropriate capability is here, such as edit_files, if that helps.

Right. The problems here are not bad syntax or foreign content (HTML, JS, etc.), the problem is that only users with unfiltered_html or edit_files should have access. There is such thing as "malicious CSS", you can easily deface a site with just couple of lines :)

In that terms changing the theme's CSS should also obey the DISALLOW_FILE_EDIT constant.

Last edited 11 months ago by azaozz (previous) (diff)

#41 in reply to: ↑ 39 ; follow-up: @azaozz
11 months ago

Replying to ThemeZee:

But I'm a really huge fan of adding a CSS Editor to the Customizer.

This is not a "CSS Editor". I don't even thing such editors exist. The closest to an editor is the "console" in the browser. It shows the HTML on one side and the CSS on the other. It also shows the current styles and selectors, has autocomplete, error highlighting, instant preview, and so on. I don't think the customizer can come even close.

I often provide CSS snippets as long as it is only some small visual customizations the user wants.

This sounds as a good way to test something or provide a temporary fix. But will be pretty bad user experience if you don't take all these snippets into account when you release updates for your themes. I don't see any problems in adding such snippets in the current theme editor.

I do not agree that users should not make CSS customizations. They can not break anything here like with the Theme Editor. The WordPress Backend will always work fine, and if they do not like their customizations they can always remove the CSS code.

Editing the existing style.css in the current theme editor will not take the site down either. Yes, having "undo" when adding CSS hacks would be helpful, but also sends the message that CSS hacks are okay. I don't agree with that. If the users want to do something, we should encourage them to do it "the right way". In this case that is a child theme.

Last edited 11 months ago by azaozz (previous) (diff)

#42 follow-up: @poena
11 months ago

I really doubt that user finds creating child themes easier than copy paste text into an area of the customizer. This whole idea would have been a non issue if that was true.

#43 in reply to: ↑ 42 ; follow-ups: @BinaryMoon
11 months ago

Replying to poena:

I really doubt that user finds creating child themes easier than copy paste text into an area of the customizer. This whole idea would have been a non issue if that was true.

Totally agreed

Replying to azzoaz:

Even if this finds its way in core, I don't think it needs a preview.

I don't think you're the target audience. The use cases you mentioned are quite limited. For example what about users who want to customize the output of plugins? What about users who are using child themes already (because they purchased Genesis with a child theme - or some other parent child combo)? I think this is about more than just themes.

that will benefit only a small amount of users

How do you know how many it will benefit? I think it would be quite a large number of people. I searched the plugin directory and there's currently over 500k active sites using custom css plugins - plus wordpress.com, and jetpack which we can't count. That's a decent amount of people imo. Plus there's plugins such as my own custom login plugin (which has 10k active installs) that include custom css abilities.

The implementation here is to allow permanent changes to the theme's styles.

Perhaps I misunderstood what this change is doing but I thought it was non destructive. This change does not edit the theme stylesheet. It saves the data in the database (through a theme mod) and then outputs it on page load. This means it's easy to update themes, and to remove the custom styles if something goes wrong. It's a lot less destructive than the theme editor (which I would be happy to see go away).

During my 9 years selling premium themes I've helped hundreds of people with custom css tweaks and many had made attempts before contacting me. A core solution would be fantastic.

#44 in reply to: ↑ 41 @ThemeZee
11 months ago

Replying to azaozz:

This is not a "CSS Editor". I don't even thing such editors exist. The closest to an editor is the "console" in the browser. It shows the HTML on one side and the CSS on the other. It also shows the current styles and selectors, has autocomplete, error highlighting, instant preview, and so on. I don't think the customizer can come even close.

Bad choice of words, sorry. As I understood this ticket it is not about creating a complete Editor which shows current styles and selectors and allows to edit them directly, but a simple Textarea field where users can paste CSS snippets. Nothing more. I just used the term CSS Editor because of the existing Theme Editor term.

@BinaryMoon Couldn't have said it better, I agree with everything.

#45 in reply to: ↑ 43 @rabmalin
11 months ago

Replying to BinaryMoon:

Replying to poena:

I really doubt that user finds creating child themes easier than copy paste text into an area of the customizer. This whole idea would have been a non issue if that was true.

Totally agreed

Replying to azzoaz:

Even if this finds its way in core, I don't think it needs a preview.

I don't think you're the target audience. The use cases you mentioned are quite limited. For example what about users who want to customize the output of plugins? What about users who are using child themes already (because they purchased Genesis with a child theme - or some other parent child combo)? I think this is about more than just themes.

that will benefit only a small amount of users

How do you know how many it will benefit? I think it would be quite a large number of people. I searched the plugin directory and there's currently over 500k active sites using custom css plugins - plus wordpress.com, and jetpack which we can't count. That's a decent amount of people imo. Plus there's plugins such as my own custom login plugin (which has 10k active installs) that include custom css abilities.

The implementation here is to allow permanent changes to the theme's styles.

Perhaps I misunderstood what this change is doing but I thought it was non destructive. This change does not edit the theme stylesheet. It saves the data in the database (through a theme mod) and then outputs it on page load. This means it's easy to update themes, and to remove the custom styles if something goes wrong. It's a lot less destructive than the theme editor (which I would be happy to see go away).

During my 9 years selling premium themes I've helped hundreds of people with custom css tweaks and many had made attempts before contacting me. A core solution would be fantastic.

Agree fully. I am really looking for Custom CSS box in core so that I dont have to ask user to install plugin to just paste few lines of CSS.

This ticket was mentioned in Slack in #core-customize by celloexpressions. View the logs.


11 months ago

#47 in reply to: ↑ 37 @Gary Barrett
11 months ago

Replying to celloexpressions:

I would also anticipate there being less of a support burden throughout the ecosystem with something like this, as support volunteers already using CSS as needed would no longer need to get the user set up with a plugin to add it, and those that previously suggested edits in the theme editor where the could have taken the site down may be able to suggest this feature instead.

As someone who has provided support to thousands of users over the past seven years, this gets a big +1 from me.

#48 in reply to: ↑ 43 @westonruter
11 months ago

Replying to BinaryMoon:

The implementation here is to allow permanent changes to the theme's styles.

Perhaps I misunderstood what this change is doing but I thought it was non destructive. This change does not edit the theme stylesheet. It saves the data in the database (through a theme mod) and then outputs it on page load. This means it's easy to update themes, and to remove the custom styles if something goes wrong. It's a lot less destructive than the theme editor (which I would be happy to see go away).

That is correct. The proposal is to store this custom post CSS in the database (via a custom post type), just as Jetpack is doing. No theme files would be modified, so this feature is not dependent on DISALLOW_FILE_EDIT being off.

This ticket was mentioned in Slack in #core by celloexpressions. View the logs.


11 months ago

#50 @celloexpressions
11 months ago

Summarizing the discussion in today's dev chat, we're going to proceed without CSSTidy or CodeMirror for 4.7 (pending the actual feature proposal and approval). CSSTidy doesn't actually provide much security benefit, and generally doesn't have enough positives to offset its size. CodeMirror (for syntax highlighting) is nice-to-have and can be added later; it's one more piece that we don't have time to consider at the moment.

For security, we will introduce a new meta capability, unfiltered_css, that is mapped to unfiltered_html by default. We should release a .org plugin that re-maps this to something that multisite site admin have, so that it can be easily opted into on multisite. See #28605 for the implementation of a meta cap. Where we can, it would be nice to expand the validation that is in place to cover more common mistakes.

We can also make some additional improvements to the UX, which @folletto has volunteered to assist with. In addition to validation, and keeping in mind that we won't have a code editor for now, we can improve the descriptive help text and make other minor adjustments.

@johnregan3 can you coordinate with @folletto for the design adjustments, and make the code changes as discussed, in the next few days? Once we have a completed patch, the next step is the make/core post, which is scheduled to go out next week for final approval.

@folletto
11 months ago

Customizer CSS design i2

#51 @folletto
11 months ago

I attached i2, a fairly advanced proposal for the CSS panel, however, it's also designed to be modular, so the end vision could be built over time.

Assuming the screenshot posted above as the current i1 reference, here are the notes about i2:

  1. Full height — it's super important that any scrolling happening in the sidebar is strictly the scrolling of the editor area. This is one of the main frustrations of having fixed height boxes and having the sidebar with an additional scrollbar.
  2. Code Highlight — Ideally the editor is visual, in the sense that highlights the right tokens, and shows row number. The use of an highlighted such as CodeMirror makes simple CSS way easier to understand for beginners, since the color acts as an implicit validation. We might tweak CodeMirror to be even more geared to this "learning" and avoiding errors approach.
  3. Line number — it is very useful in support, in this way we'll be able to effectively support not just individual developers helping out clients, but also people learning in groups ("See there on line 5?") and even remote technical support.
  4. "Site wide" and "This page" — the tabs at the top (design borrowed from the Plugins info UI in wp-admin since there's no equivalent in Customizer) is a split that can be incredibly helpful for both beginners and advanced users. Having a CSS that gets applied to all the site, and one that is applied only on the specific page the user is previewing, makes this simple tool less error-prone and keeps the CSS down in complexity for everyone.
  5. "History" — it is a very powerful tool, and given the flexibility of CSS can be very useful, especially for multi-user sites where changes can be applied by different people. Reverting and previewing there can be a life saver, and something that will build more trust in the tool.
  6. "Pop out" — this button makes editing more flexible. Reusing the hooks modern browsers have to pop out a window and detect when it gets closed, we can provide a full page preview and at the same time a floating panel that applies CSS, live refreshing.
  7. "Inspect" — the inspector is something every user refers to when they have to pinpoint a piece on the page they want to change, this is true for beginners and pro users as well. Would be thus amazing if with only one click the selector got added to the CSS list, ready to be customized. This would avoid all the complexity of learning the inspector, and would make the whole operation just two clicks apart.
  8. SCSS — would be also amazing if this panel processed SCSS instead of CSS. It's a transparent feature since it's a superset of CSS, so it's very effective to provide features to both beginners and advanced users. Given the limited space, this could be very powerful, and with appropriate filters, themes would also be able to provide easy to user variables that match their internal working dynamically, and even the other way around in the future. But that's really long term thinking.
  9. "Additional CSS" — this is a more accurate label. "Custom" doesn't add any information to the user. They have already clicked on "customize" and they are already "customizing". "Additional" instead gives the correct meaning and scope of this tool: adding more CSS to the page. Also "additional" has a slight implication of extra, so something that one usually won't do, which is another slight semantic nudge.
  10. Help — the help has been reduced to just the top icon. If someone doesn't know how to use this, a few lines of text don't really add anything, and after reading these once, they become just visual noise. Plus, it's very likely that someone getting there will ask help beforehand. Both beginners and more advanced users will instead benefit for the full page used properly to edit it, as space is critical, and it's very easy to frustrate people. If we feel strongly that an introduction is needed beyond the help button at the top, we can explore alternatives that still will get the best of both scenarios, but I'd like to start exploring this approach before we start exploring.

Now, this is a lot, I understand.

Thus, the design as mentioned is modular. Each of the advanced features can be removed with zero or minimal UI change, in a very intuitive way:

  • "History" — it's just a sub-panel activated by a button in the bottom bar. Removing the button can be done, and the bar stays with no problems. Zero other UI changes.
  • "Inspect" — similarly to history, this can be absent until built in a future version. Zero other UI changes. If both "History" and the inspector icons are missing, the entire bar disappears, so the editor goes edge to edge.
  • "Pop out" — the button can just be removed to build the feature at a later time. Zero other UI changes.
  • Code Highlight — if we can't have CodeMirror or any other highlighted and row number, at the beginning this can be just a normal monospaced (courier) text area.
  • Site wide" and "This page" — they can be removed to leave at the beginning just the site wide CSS. Zero other UI changes. If however the "Pop out" button is missing too, the entire row collapses and the editor area goes again edge to edge.

Without all the above, the page gets fairly simple, but it's still useful, and most importantly, will still allow all the pieces to be added one by one in future releases.

I hope this helps. :)

This ticket was mentioned in Slack in #core-customize by celloexpressions. View the logs.


11 months ago

#53 @celloexpressions
11 months ago

  • Keywords dev-feedback removed

Thanks for this @folletto!

I think most of these suggestions will be best as future enhancements, which can continue to improve the base experience piece by piece. To help get there, we could keep the code editor as a separate customizer control for now rather than going back to the textarea control, and possibly work on the height issue in 4.7.

I'd rather not do a custom section for this, so what about adding a description_hidden attribute to WP_Customize_Section that puts the description behind the icon like panel descriptions do? That would be useful for any sections that have larger descriptions. I'm going to leave the final call in terms of what should happen in 4.7 vs. future up to @johnregan3 since he's actually implementing it.

In the meantime, we also need to refine the help text and the external links. Are there any better resources on .org than the codex article on CSS? Should we create a handbook page that can be fleshed out over time?

#54 @johnregan3
11 months ago

My latest update can be found in this comment in GitHub: https://github.com/xwp/wordpress-develop/pull/154#issuecomment-251586810

Lots of progress today, still a bit more to do.

#55 @folletto
11 months ago

Can you add screenshots of the in-progress work? :)

@johnregan3
11 months ago

35395 - 5 October 2016 screenshot

#56 @johnregan3
11 months ago

@folletto Please see above. It's quite plain, really -- just a textarea that updates the CSS on postMessage.

I looked into utilizing the "?" icon, as used in the Nav Menu panel, but it would take quite a bit of work at this point to make this Panel functionality work on a Setting.

I did like your suggestion to use "Additional CSS," and plan to implement it on the Control title, in addition to the Section title.

I'm going to remove the underscores from the "new window" icons.

Since we don't have CodeMirror, syntax highlighting is not an option, which bums me out. :D

By the way, thanks so much for your work. It's really inspiring, and I hope to see this feature look like this someday!

Last edited 11 months ago by johnregan3 (previous) (diff)

#57 @johnregan3
11 months ago

@celloexpressions I'd like to look at removing the description text altogether (or at least cut it down significantly). I agree with @folletto that it is a lot of visual noise for a person who uses this feature repeatedly, as most certainly will. Also the point about precious space here makes a lot of sense. I don't think a majority of users will need an explanation of CSS in the actual control, but I do understand your intent here to help make visual changes easier for less experienced users.

Also, I've changed the validation notifications so they only appear when trying to save the CSS. The postMessage notifications (selective refresh) got pretty frustrating for me as the errors would appear while I was typing. As you know, these push the textarea down on the page, and my eye had to constantly move around as the text validated.

So, when the CSS isn't valid, the notifications appear once the user clicks "Save & Publish." Additionally, as you probably know, the errant value isn't saved until corrected.

I'm curious about your thoughts on these. Cheers!

Last edited 11 months ago by johnregan3 (previous) (diff)

#58 @johnregan3
11 months ago

  • Keywords dev-feedback added

@johnregan3
11 months ago

Demonstration of firing notifications on save

@johnregan3
11 months ago

Today's Demo. Note the new ability to use the help icon on Section titles, as well as the monospaced font to help indicate this is a code editor.

@folletto
11 months ago

customizer CSS i2, MVP milestone

#59 @folletto
11 months ago

That is great @johnregan3!

Sorry for being late, but I added above the mockups for the MVP version you're building. It's mostly just to make sure we're aligned, it's basically what you're building already. :)

@johnregan3
11 months ago

@folletto @cellodesigns - Here are the line numbers! You'll note the numbered column is a bit wider than in the comps. This is so it can be up to 3 characters wide (like "999").

#60 @johnregan3
11 months ago

@folletto I'll remove that "Additional CSS" title from above the textarea next.

#61 @celloexpressions
11 months ago

  • Keywords dev-feedback removed

I reviewed the patch on GitHub and left comments inline. Needs a few adjustments but it's pretty close to ready, as is the feature proposal post.

#62 @westonruter
10 months ago

I also left a several comments as well. A few highlights:

  • I think we should just re-use the core textarea control and skip trying to add line numbers. A line number gutter reduces the overall width in precious horizontal real estate. We can let an eventual CodeMirror or some other real editor library provide that UI instead.
  • The validate_balanced_characters method is going to need to be more robust to account for the characters appearing in string literals (comment).
  • Switch to only create the custom_css posts when there is actually data being saved. No need to create these posts if there is no custom CSS
  • Move the registration of the custom post type to create_initial_post_types() instead of from the WP_Custom_CSS class. Actually, I'm not sure about the best place to add CPT registration and also the filters that customize its behavior. In the past I think the norm for CPTs has been to add new global functions and add the filters in default-filters.php. But is a practice we should continue?

See full review: https://github.com/xwp/wordpress-develop/pull/154#pullrequestreview-3430614

This ticket was mentioned in Slack in #core-customize by celloexpressions. View the logs.


10 months ago

#64 @folletto
10 months ago

I think we should just re-use the core textarea control and skip trying to add line numbers. A line number gutter reduces the overall width in precious horizontal real estate. We can let an eventual CodeMirror or some other real editor library provide that UI instead.

I agree would be better to let that be handled directly in CodeMirror (or else), but if the feature is already in for a standard textarea, I think it's still beneficial. As noted above (it's a bit hidden, sorry) it helps keeping sense of longer CSS fixes. That said, I agree we should keep in mind to swap it with a proper CodeMirror (or else) one once we merge syntax highlighting in. :)

#65 @mikeschroder
10 months ago

I tested this feature using https://patch-diff.githubusercontent.com/raw/xwp/wordpress-develop/pull/154.diff

In Chrome (Mac), I found it to work as expected, and enjoyed the experience.

When I tested in Firefox (Mac), I noticed that content I had added in Chrome (Mac) showed up as a single line, and I couldn't get it to add carriage-returns, which made it difficult to edit.

Last edited 10 months ago by mikeschroder (previous) (diff)

This ticket was mentioned in Slack in #core by jeffpaul. View the logs.


10 months ago

This ticket was mentioned in Slack in #core-customize by celloexpressions. View the logs.


10 months ago

@johnregan3
10 months ago

Latest implementation. Note that we've opted to not create a new Code Editor control, so we're using a full-width textarea. This gif also demonstrates the basic validation we've added as well.

#68 @johnregan3
10 months ago

@mikeschroder

Great catch! I believe that we removed the Code Editor control after you last tested this. I just tested the latest patch with Firefox 49.01 on Mac OS El Capitan, and things look correct to me.

Can you please confirm that you no longer see this bug?

Thanks!

#69 @westonruter
10 months ago

  • Resolution set to fixed
  • Status changed from assigned to closed

In 38829:

Customize: Introduce custom CSS for extending theme styles.

  • Custom CSS is associated with a given theme and is displayed in an inline style element at the wp_head hook after the wp_print_styles is called so that it overrides any enqueued stylesheets.
  • A wp_get_custom_css() function is used for accessing the CSS associated with the current theme (or another theme) and a wp_get_custom_css filter for manipulating it.
  • CSS is managed in customizer via a new "Additional CSS" section with a single textarea control.
  • WP_Customize_Section::$description_hidden is introduced for hiding extended descriptions in customizer sections behind a help toggle as done with panels.
  • CSS is stored in a custom_css post type with the theme (stylesheet) slug as the post_name.
  • WP_Customize_Custom_CSS_Setting is introduced to handle validation of CSS, previewing, and persisting the CSS to the custom_css post type.
  • The custom_css setting is tied to a new unfiltered_css capability which maps to unfiltered_html by default.
  • Escaping the message in the notification template is removed to allow markup (code tags) to be rendered.

See https://make.wordpress.org/core/2016/10/11/feature-proposal-better-theme-customizations-via-custom-css-with-live-previews/

Props johnregan3, celloexpressions, folletto, westonruter.
Fixes #35395.

#70 @joyously
10 months ago

I might be a little late, but shouldn't the naming be consistent? The Customizer textarea is labeled "Additional CSS", but everything in the code is named after "Custom CSS".

#71 @pingram3541
10 months ago

Whew that was a lot to skim through but I'm liking where all this is going and the screens are absolutely beautiful! I have some input and I apologize if any of this is repetitious, again, I skimmed through A LOT of this.

This might eventually replace my own custom live css plugin that @westonruter helped me with a while back but I'm concerned like @azaozz whether this needs to be in core and something that is always present vs a plugin that can be used and then discarded later (it's a developer tool in my opinion). I really never would ask or want my end users to use this but I also wouldn't want to hide it from being an accessible tool in the wp plugins repo.

My thoughts, search it up in the repo, install it, use it, disable it and then possibly uninstall it after use.

My idea is very close to what is suggested here but my preference is not to use this as a permanent CSS solution that loops through the db on every visit but rather a tool to use for development, even post-production too.

We all know DB calls are much slower than our file system and we want to be able to properly enqueue our styles as well. This will help with post processing filters of the css such as minification, uglification (is that a word?) etc. and allow for overrides, dequeuing, changing priorities etc.

I love the idea that I can use a tool to edit live css but then also disable that tool when it is not needed and without losing all my work.

My concept is very similar, use an existing textarea control to apply the CodeMirror experience with line numbers, syntax highlighting etc.

I then set that control to use a custom callback and the rest falls within the js api passing post_meta as needed.

It stores the custom css in the db as follows:

  • master css, shop css (ie. woocommcerce) and archive css (per post_type) is stored in wp_options unique to the theme (or child-theme) so that switching themes applies the proper and unique css to appropriate pages
    • a. such as mycss_master_mythemename, mycss_shop_mythemename...
  • post/page/single css is stored in post_meta also unique to the theme/child-theme
    • a. such as mycss_mythemename_postid

This allows for full freedom for custom css code site wide, across a common group of posts/pages or individually and prioritized accordingly.

The live preview uses inline style elements (with unique ids) for the real time "live" previewing when code in the editor is changed but on the front end I'm using wp_enqueue_styles with a doctype wrapper to properly use wp standard practices.

Additionally, I added another customizer option to my plugin which disables the Front Loading (front end enqueuing of css stored in the db) but not when in the customizer.

My front end development process as a result:

  1. enable the plugin
  2. build to my hearts content all styling that is theme specific and see it both on the front-end and in the live customizer
  3. when I'm finished I manually copy all css to processed (minified) files into my theme folder (add appropriate wp_enqueue_styles to functions.php - future automation of this is an idea I have)
  4. disable the "Front Loading" option and verify static files are working on the front end
  5. finally disable the plugin and uninstall if I want

So what I've done here is use a plugin as a dev tool to build out all my css for my theme of which also loads on the front end but must stay enabled to be visible and uses css in the db. Then I optimize and load proper external stylesheets as it should be done and the css stored in the db is simply my backup copy and referenced only when I activate my css plugin again and edit in the customizer. Each time I do this and after verifying the results, I copy the updated css to my static files and disable the plugin again. This is a simple approach to not baking in a dependency on my plugin.

I think a similar approach to page content builders is the next step in improving live front-end development beyond just css.

Last edited 10 months ago by pingram3541 (previous) (diff)

#72 @pingram3541
10 months ago

Another thought that just occurred to me is better built in enqueueing of theme styles and scripts based on file structure, similar to the existing wp model for pages, posts partials/templates where the file structure and naming conventions define how wp loads css and js files.

How cool would it be for me to drop in a css file /mytheme/css/page_home_20.css and WP to automatically load that file only on the page with a slug of "home" with a priority of 20. Obviously I haven't thought much deeper on this and there may be a good reason for not doing this but in the case of saving files from the customizer as it pertains to css, this could be the good ol logic needed to remove needing to hook into the db for css to load on the front end. Think of the awesomeness we could have with the live editor in that we can employ a custom view for diffs not only against the recently proposed "changesets", i.e. customizer textarea history but also with actual files residing in the theme folder simply based on naming structure.

Heck at base value, I'd love the idea of being able to simply create and properly name a css file in my theme and never worry about touching functions.php for this!

Last edited 10 months ago by pingram3541 (previous) (diff)

#73 @sebastian.pisula
10 months ago

Why CPT? We can use theme_mods to save css

#74 follow-up: @westonruter
10 months ago

@sebastian.pisula a couple reasons why a custom post type. Theme mods are stored in options and they are autoloaded. If a large amount of CSS gets added, then this will increase the size of the alloptions cache. For sites that use Memcached object cache, the size of the alloptions cache and (especially on WordPress.com) the sum of all options must not approach 1MB or else the alloptions cache will cease to cache at all, and the site will crash if it is getting any traffic.

A more positive reason for using a custom post type is that it allows us to make use of post revisions to do versioning of the CSS. Jetpack also used a custom post type for storing CSS.

#75 in reply to: ↑ 74 @sebastian.pisula
10 months ago

If user will want revisions then someone make a plugin. I think that default functionality should be minimalist.

Better use as option with autoload off. We can have revisions. Add new option, 'custom_css_revisons' with md5 hash value. Custom styles will be in 'custom_css' option. And revisions in 'custom_css_[HASH]'

this is better than CPT.

custom_css -> hash latest version (autoload = yes)
custom_css_revisons -> array of revisions (hash) (autoload = yes)
custom_css_[HASH] -> custom css (autoload = off)

for example:

get_option('custom_css_'.get_option('custom_css'));

Replying to westonruter:

@sebastian.pisula a couple reasons why a custom post type. Theme mods are stored in options and they are autoloaded. If a large amount of CSS gets added, then this will increase the size of the alloptions cache. For sites that use Memcached object cache, the size of the alloptions cache and (especially on WordPress.com) the sum of all options must not approach 1MB or else the alloptions cache will cease to cache at all, and the site will crash if it is getting any traffic.

A more positive reason for using a custom post type is that it allows us to make use of post revisions to do versioning of the CSS. Jetpack also used a custom post type for storing CSS.

#76 @westonruter
10 months ago

Revisions support is turned off by default. A plugin currently is needed to add the revisions support to the custom_css post type. Storing code content in options (or theme_mods) is not scalable. We decided to use a custom post/object/content type for the purpose of scalably storing CSS. As I noted, in some environments (at least WordPress.com), autoload=no is ignored.

#77 @westonruter
10 months ago

In 39009:

Customize: Fix message grammar for custom_css validity error when imbalanced characters possibly due to content CSS property.

Props Presskopp.
See #35395.
Fixes #38564.

#78 @johnbillion
10 months ago

The capability mapping for unfiltered_css introduced in [38829] is incorrect and allows administrators and editors on multisite to post unfiltered CSS, which they should not be able to do if the mapping corresponds to the unfiltered_html capability.

#79 @johnbillion
10 months ago

  • Resolution fixed deleted
  • Status changed from closed to reopened

#80 @johnbillion
10 months ago

  • Resolution set to fixed
  • Status changed from reopened to closed

In 39016:

Customize: Correct the capability mapping and associated tests for the unfiltered_css capability.

Fixes #35395

#81 @johnbillion
10 months ago

In 39017:

Customize: Correct the CRUD tests for custom CSS on multisite.

See #35395

#82 @johnbillion
10 months ago

In 39020:

Customize: Avoid using assertNotFalse() in tests because it's not available in PHPUnit 3.6.

See #35395

#83 @lukecavanagh
10 months ago

Will there be an option to enable CSS to be global, besides being theme specific CSS. So global CSS might be tweaks made for active plugins, rather than theme specific CSS changes.

#84 follow-up: @folletto
10 months ago

Which reminds me...

@johnregan3 do we need to create a separate ticket to progress the other pieces of the designs post-4.7?

#85 in reply to: ↑ 84 @helen
10 months ago

Replying to folletto:

Which reminds me...

@johnregan3 do we need to create a separate ticket to progress the other pieces of the designs post-4.7?

Please create tickets for tracking things you are already aware of, yes :)

#86 @westonruter
10 months ago

In 39149:

Customize: Allow tab characters in custom CSS input.

Pressing Esc followed by Tab allows for tabbing to the next element.

Props afercia, coffee2code, westonruter.
See #35395.
Fixes #38667.

#87 @westonruter
10 months ago

In 39151:

Customize: Move Custom CSS control placeholder help text to setting default value.

The WP_Customize_Custom_CSS_Setting::value() method now returns the default if wp_get_custom_css() returns empty.

Props westonruter, afercia, helen.
See #35395.
Fixes #38685.

#88 @westonruter
9 months ago

In 39175:

Customize: Rename unfiltered_css meta capability to edit_css; add revisions support to custom_css post type.

Props lukecavanagh, georgestephanis, westonruter.
See #38672, #35395.

#89 @westonruter
9 months ago

In 39178:

Customize: Rename remaining instances unfiltered_css meta capability to edit_css in unit tests.

Amends [39175].
See #38672, #35395.

#90 @westonruter
9 months ago

In 39185:

Customize: Split out custom_css query logic from wp_get_custom_css() into a re-usable wp_get_custom_css_post() function to also be used when updating.

Props georgestephanis, westonruter.
See #38672, #35395.

#91 @westonruter
9 months ago

In 39229:

Customize: Maximize height of Custom CSS textarea without causing doubled scrollbars.

Textarea will fill vertical height of Custom CSS section for browsers that support calc() and when plugins don't add other controls to the section. Also run CSS autoprefixer.

Props michaelarestad, westonruter.
See #35395.
Fixes #38755.

#92 @westonruter
9 months ago

In 39268:

Customize: Allow URL for Codex link in Additional CSS section to be translated.

Props odysseygate, ocean90, westonruter.
See #35395.
Fixes #38823.

#93 @westonruter
9 months ago

In 39350:

Customize: Refactor logic for updating custom_css posts by introducing wp_update_custom_css_post() function and renaming update filter.

  • Moves logic from WP_Customize_Custom_CSS_Setting::update() into a re-usable wp_update_custom_css_post() function, useful for future REST API endpoint, WP-CLI command, or plugin migrations.
  • Renames customize_update_custom_css_post_content_args filter to update_custom_css_data and improves the naming of the parameters. Instead of passing post_content and post_content_filtered the filtered array now contains css and preprocessed respectively.
  • The second context param for the update_custom_css_data filter is now an array of the original args passed to wp_update_custom_css_post() and there is now no more $setting arg since it isn't necessarily being called in the customizer context.

Props westonruter, georgestephanis.
See #35395.
Fixes #38672.

#94 @westonruter
9 months ago

In 39477:

Customize: Ensure a custom_css post insertion gets an initial post revision.

Props georgestephanis, westonruter.
See #30854, #38672, #35395.
Fixes #39032.

#95 @westonruter
9 months ago

In 39499:

Customize: Ensure textarea for Custom CSS displays as code (in LTR) when an RTL language is active.

See #35395.
Fixes #39085.

#96 @westonruter
8 months ago

In 39559:

Customize: Prevent single quotes (apostrophes) in custom_css values from unexpectedly causing false positives for unbalanced character validation errors.

See #39218, #35395.
Fixes #39198.

#97 @dd32
8 months ago

In 39567:

Customize: Prevent single quotes (apostrophes) in custom_css values from unexpectedly causing false positives for unbalanced character validation errors.

Props westonruter.
See #39218, #35395.
Merges [39559] to the 4.7 branch.
Fixes #39198.

#98 @westonruter
8 months ago

In 39616:

Customize: Bump wp_custom_css_cb from running at wp_head priority 11 to 101 to ensure Custom CSS overrides other CSS.

Aligns wp_head action priority with Jetpack's Custom CSS.

Amends [38829].
See #35395, #38672.
Fixes #39270.

#99 @dd32
8 months ago

In 39651:

Customize: Bump wp_custom_css_cb from running at wp_head priority 11 to 101 to ensure Custom CSS overrides other CSS.

Aligns wp_head action priority with Jetpack's Custom CSS.

Amends [38829].
See #35395, #38672.
Merges [39616] to the 4.7 branch.
Fixes #39270.

#100 @westonruter
8 months ago

In 39688:

Customize: Ensure theme_mod-cache of custom_css lookup of -1 short-circuits a WP_Query from being made.

Props dlh.
See #35395.
Fixes #39259.

#101 @dd32
8 months ago

In 39694:

Customize: Ensure theme_mod-cache of custom_css lookup of -1 short-circuits a WP_Query from being made.

Props dlh, westonruter.
See #35395.
Merges [39688] to the 4.7 branch.
Fixes #39259.

#102 @westonruter
7 months ago

I've re-opened #12423 to introduce CodeMirror (or another code editor component).

Note: See TracTickets for help on using tickets.