Skip to content

Instantly share code, notes, and snippets.

@emfluenceindia
Created June 6, 2025 13:39
Show Gist options
  • Save emfluenceindia/64ae2e63ce661915edf4478c977d18f4 to your computer and use it in GitHub Desktop.
Save emfluenceindia/64ae2e63ce661915edf4478c977d18f4 to your computer and use it in GitHub Desktop.
A simple plugin to add a section in WordPress dashboard under Appearance for users to add their custom CSS.
<?php
/**
* Plugin Name: Custom CSS Textarea
* Description: Adds a custom textarea in the WordPress admin where users can add site-wide CSS.
* Version: 1.0.0
* Author: Subrata Sarkar
* Author URI: https://profiles.wordpress.org/subrataemfluence/
* License: GPL-2.0-or-later
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
* Text Domain: custom-css-textarea
*/
// Exit if accessed directly to prevent direct file access.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Class Custom_CSS_Textarea_Plugin
*
* Manages the custom CSS textarea plugin functionality.
*/
class Custom_CSS_Textarea_Plugin {
/**
* Constructor.
* Initializes the plugin by hooking into WordPress actions.
*/
public function __construct() {
add_action( 'admin_menu', array( $this, 'add_plugin_admin_page' ) );
add_action( 'admin_init', array( $this, 'register_plugin_settings' ) );
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_custom_css' ) );
}
/**
* Adds the plugin's admin page to the WordPress admin menu.
* It will appear under the "Appearance" menu.
*/
public function add_plugin_admin_page() {
add_theme_page(
__( 'Custom CSS', 'custom-css-textarea' ), // Page title
__( 'Custom CSS', 'custom-css-textarea' ), // Menu title
'manage_options', // Capability required to access
'custom-css-textarea', // Menu slug
array( $this, 'display_plugin_admin_page' ) // Callback function to render the page
);
}
/**
* Registers the plugin's settings using the WordPress Settings API.
* This handles saving and retrieving the custom CSS from the database.
*/
public function register_plugin_settings() {
// Register a setting group. This group name is used in settings_fields().
register_setting(
'custom_css_textarea_options_group', // Option group name
'custom_css_textarea_content', // Option name (the key for the CSS content in the database)
array( $this, 'sanitize_custom_css' ) // Sanitization callback
);
// Add a settings section to the page.
add_settings_section(
'custom_css_textarea_main_section', // Section ID
__( 'Add Your Custom CSS Below', 'custom-css-textarea' ), // Section title
array( $this, 'custom_css_textarea_section_callback' ), // Callback for section content
'custom-css-textarea' // Page slug where this section appears
);
// Add a settings field (the textarea itself).
add_settings_field(
'custom_css_textarea_field', // Field ID
__( 'Custom CSS', 'custom-css-textarea' ), // Field title (label)
array( $this, 'custom_css_textarea_field_callback' ), // Callback to render the field
'custom-css-textarea', // Page slug where this field appears
'custom_css_textarea_main_section' // Section ID this field belongs to
);
}
/**
* Callback function for the settings section.
* Displays a brief description for the section.
*/
public function custom_css_textarea_section_callback() {
echo '<p>' . esc_html__( 'Enter your custom CSS rules here. These styles will be applied to your website\'s frontend.', 'custom-css-textarea' ) . '</p>';
}
/**
* Callback function to render the custom CSS textarea field.
* Retrieves the saved CSS content from the database.
*/
public function custom_css_textarea_field_callback() {
// Get the saved CSS content. The second argument is the default value if the option doesn't exist.
$css_content = get_option( 'custom_css_textarea_content', '' );
?>
<textarea
name="custom_css_textarea_content"
id="custom_css_textarea_content"
rows="20"
cols="100"
class="large-text code"
placeholder="<?php esc_attr_e( '/* Add your custom CSS here */', 'custom-css-textarea' ); ?>"
><?php echo esc_textarea( $css_content ); ?></textarea>
<p class="description">
<?php esc_html_e( 'These styles will override your theme\'s default styles. Be careful not to break your site!', 'custom-css-textarea' ); ?>
</p>
<?php
}
/**
* Sanitizes the custom CSS content before saving it to the database.
*
* @param string $input The raw CSS input from the textarea.
* @return string Sanitized CSS content.
*/
public function sanitize_custom_css( $input ) {
// Use wp_strip_all_tags to remove any potentially malicious HTML tags.
// For CSS, we mostly want to prevent script injection.
// It's generally safe to allow most CSS characters.
// A more robust solution might parse CSS, but for basic use, this is a good start.
return wp_strip_all_tags( $input );
}
/**
* Displays the main admin page for the plugin.
* This page contains the form for the custom CSS textarea.
*/
public function display_plugin_admin_page() {
// Check user capabilities.
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
?>
<div class="wrap">
<h1><?php echo esc_html( get_admin_page_title() ); ?></h1>
<form action="options.php" method="post">
<?php
// Output security fields and the settings section.
settings_fields( 'custom_css_textarea_options_group' ); // Must match the group name in register_setting()
do_settings_sections( 'custom-css-textarea' ); // Must match the page slug in add_settings_section()
submit_button( __( 'Save Custom CSS', 'custom-css-textarea' ) );
?>
</form>
</div>
<?php
}
/**
* Enqueues the custom CSS on the website's frontend.
* The CSS is outputted directly into the <head> section of the page.
*/
public function enqueue_custom_css() {
$custom_css = get_option( 'custom_css_textarea_content', '' ); // Get the saved CSS
// Only enqueue if there's actual CSS content.
if ( ! empty( $custom_css ) ) {
wp_add_inline_style( 'wp-block-library', $custom_css ); // 'wp-block-library' is a common handle to hook into
// You could also register your own handle if you prefer:
// wp_register_style( 'custom-css-textarea-style', false );
// wp_enqueue_style( 'custom-css-textarea-style' );
// wp_add_inline_style( 'custom-css-textarea-style', $custom_css );
}
}
}
// Instantiate the plugin class to run it.
new Custom_CSS_Textarea_Plugin();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment