typography-options.php

I’ll build this as a full WordPress Customizer typography options file for your RX theme, with Google font selection, body/headings/menu/buttons/forms/post typography, responsive font sizes, line height, letter spacing, text transform, font style, and live CSS output.

Below is an advanced inc/options/typography-options.php file for your RX Theme. It adds many typography controls through the WordPress Customizer and outputs dynamic CSS automatically.

Create this file:

rx-theme/
└── inc/
    └── options/
        └── typography-options.php

Then paste this full code:

<?php
/**
 * RX Theme Typography Options
 *
 * File: inc/options/typography-options.php
 *
 * Adds advanced typography controls to WordPress Customizer:
 * - Global body typography
 * - Headings H1-H6 typography
 * - Site title and tagline typography
 * - Menu typography
 * - Button typography
 * - Form typography
 * - Blog/post/content typography
 * - Widget typography
 * - Footer typography
 * - Responsive font sizes
 * - Google Fonts support
 * - Dynamic frontend CSS
 *
 * @package RX_Theme
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Register Typography Options.
 */
function rx_theme_typography_options( $wp_customize ) {

	/**
	 * Panel: Typography
	 */
	$wp_customize->add_panel(
		'rx_typography_panel',
		array(
			'title'       => esc_html__( 'RX Typography', 'rx-theme' ),
			'description' => esc_html__( 'Advanced typography settings for RX Theme.', 'rx-theme' ),
			'priority'    => 25,
		)
	);

	/**
	 * Font choices.
	 */
	$rx_font_choices = array(
		'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif' => esc_html__( 'System UI', 'rx-theme' ),
		'Arial, Helvetica, sans-serif'                                        => esc_html__( 'Arial', 'rx-theme' ),
		'Helvetica, Arial, sans-serif'                                        => esc_html__( 'Helvetica', 'rx-theme' ),
		'Georgia, serif'                                                      => esc_html__( 'Georgia', 'rx-theme' ),
		'"Times New Roman", Times, serif'                                     => esc_html__( 'Times New Roman', 'rx-theme' ),
		'"Trebuchet MS", Helvetica, sans-serif'                               => esc_html__( 'Trebuchet MS', 'rx-theme' ),
		'Verdana, Geneva, sans-serif'                                         => esc_html__( 'Verdana', 'rx-theme' ),
		'"Courier New", Courier, monospace'                                   => esc_html__( 'Courier New', 'rx-theme' ),
		'"Roboto", sans-serif'                                                => esc_html__( 'Roboto', 'rx-theme' ),
		'"Open Sans", sans-serif'                                             => esc_html__( 'Open Sans', 'rx-theme' ),
		'"Lato", sans-serif'                                                  => esc_html__( 'Lato', 'rx-theme' ),
		'"Poppins", sans-serif'                                               => esc_html__( 'Poppins', 'rx-theme' ),
		'"Montserrat", sans-serif'                                            => esc_html__( 'Montserrat', 'rx-theme' ),
		'"Inter", sans-serif'                                                 => esc_html__( 'Inter', 'rx-theme' ),
		'"Nunito", sans-serif'                                                => esc_html__( 'Nunito', 'rx-theme' ),
		'"Merriweather", serif'                                               => esc_html__( 'Merriweather', 'rx-theme' ),
		'"Playfair Display", serif'                                           => esc_html__( 'Playfair Display', 'rx-theme' ),
		'"Source Sans 3", sans-serif'                                         => esc_html__( 'Source Sans 3', 'rx-theme' ),
		'"Noto Sans", sans-serif'                                             => esc_html__( 'Noto Sans', 'rx-theme' ),
		'"Noto Serif", serif'                                                 => esc_html__( 'Noto Serif', 'rx-theme' ),
	);

	$rx_font_weights = array(
		'100' => esc_html__( 'Thin 100', 'rx-theme' ),
		'200' => esc_html__( 'Extra Light 200', 'rx-theme' ),
		'300' => esc_html__( 'Light 300', 'rx-theme' ),
		'400' => esc_html__( 'Regular 400', 'rx-theme' ),
		'500' => esc_html__( 'Medium 500', 'rx-theme' ),
		'600' => esc_html__( 'Semi Bold 600', 'rx-theme' ),
		'700' => esc_html__( 'Bold 700', 'rx-theme' ),
		'800' => esc_html__( 'Extra Bold 800', 'rx-theme' ),
		'900' => esc_html__( 'Black 900', 'rx-theme' ),
	);

	$rx_text_transforms = array(
		'none'       => esc_html__( 'None', 'rx-theme' ),
		'capitalize' => esc_html__( 'Capitalize', 'rx-theme' ),
		'uppercase'  => esc_html__( 'Uppercase', 'rx-theme' ),
		'lowercase'  => esc_html__( 'Lowercase', 'rx-theme' ),
	);

	$rx_font_styles = array(
		'normal'  => esc_html__( 'Normal', 'rx-theme' ),
		'italic'  => esc_html__( 'Italic', 'rx-theme' ),
		'oblique' => esc_html__( 'Oblique', 'rx-theme' ),
	);

	/**
	 * Helper: Add typography section.
	 */
	$sections = array(
		'global' => array(
			'title'       => esc_html__( 'Global Body Typography', 'rx-theme' ),
			'description' => esc_html__( 'Typography for body text and general content.', 'rx-theme' ),
			'priority'    => 10,
		),
		'site_identity_text' => array(
			'title'       => esc_html__( 'Site Title & Tagline Typography', 'rx-theme' ),
			'description' => esc_html__( 'Typography for website title and tagline.', 'rx-theme' ),
			'priority'    => 20,
		),
		'headings' => array(
			'title'       => esc_html__( 'Headings Typography', 'rx-theme' ),
			'description' => esc_html__( 'Typography for H1 to H6 headings.', 'rx-theme' ),
			'priority'    => 30,
		),
		'menu' => array(
			'title'       => esc_html__( 'Menu Typography', 'rx-theme' ),
			'description' => esc_html__( 'Typography for navigation menus.', 'rx-theme' ),
			'priority'    => 40,
		),
		'content' => array(
			'title'       => esc_html__( 'Post & Page Content Typography', 'rx-theme' ),
			'description' => esc_html__( 'Typography for post title, excerpt, meta, and content.', 'rx-theme' ),
			'priority'    => 50,
		),
		'buttons' => array(
			'title'       => esc_html__( 'Button Typography', 'rx-theme' ),
			'description' => esc_html__( 'Typography for buttons and links styled as buttons.', 'rx-theme' ),
			'priority'    => 60,
		),
		'forms' => array(
			'title'       => esc_html__( 'Form Typography', 'rx-theme' ),
			'description' => esc_html__( 'Typography for form inputs, textarea, labels, and select boxes.', 'rx-theme' ),
			'priority'    => 70,
		),
		'widgets' => array(
			'title'       => esc_html__( 'Widget Typography', 'rx-theme' ),
			'description' => esc_html__( 'Typography for sidebar and footer widgets.', 'rx-theme' ),
			'priority'    => 80,
		),
		'footer' => array(
			'title'       => esc_html__( 'Footer Typography', 'rx-theme' ),
			'description' => esc_html__( 'Typography for footer text and footer links.', 'rx-theme' ),
			'priority'    => 90,
		),
		'responsive' => array(
			'title'       => esc_html__( 'Responsive Typography', 'rx-theme' ),
			'description' => esc_html__( 'Typography size controls for tablet and mobile devices.', 'rx-theme' ),
			'priority'    => 100,
		),
	);

	foreach ( $sections as $section_id => $section ) {
		$wp_customize->add_section(
			'rx_typography_' . $section_id,
			array(
				'title'       => $section['title'],
				'description' => $section['description'],
				'panel'       => 'rx_typography_panel',
				'priority'    => $section['priority'],
			)
		);
	}

	/**
	 * Helper function to add full typography controls.
	 */
	$add_typography_controls = function( $prefix, $section, $label, $defaults = array() ) use ( $wp_customize, $rx_font_choices, $rx_font_weights, $rx_text_transforms, $rx_font_styles ) {

		$defaults = wp_parse_args(
			$defaults,
			array(
				'font_family'    => 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
				'font_size'      => 16,
				'font_weight'    => '400',
				'line_height'    => 1.7,
				'letter_spacing' => 0,
				'text_transform' => 'none',
				'font_style'     => 'normal',
			)
		);

		$wp_customize->add_setting(
			$prefix . '_font_family',
			array(
				'default'           => $defaults['font_family'],
				'sanitize_callback' => 'rx_theme_sanitize_font_family',
				'transport'         => 'refresh',
			)
		);

		$wp_customize->add_control(
			$prefix . '_font_family',
			array(
				'label'    => sprintf( esc_html__( '%s Font Family', 'rx-theme' ), $label ),
				'section'  => $section,
				'type'     => 'select',
				'choices'  => $rx_font_choices,
				'priority' => 10,
			)
		);

		$wp_customize->add_setting(
			$prefix . '_font_size',
			array(
				'default'           => $defaults['font_size'],
				'sanitize_callback' => 'absint',
				'transport'         => 'refresh',
			)
		);

		$wp_customize->add_control(
			$prefix . '_font_size',
			array(
				'label'       => sprintf( esc_html__( '%s Font Size PX', 'rx-theme' ), $label ),
				'section'     => $section,
				'type'        => 'number',
				'input_attrs' => array(
					'min'  => 8,
					'max'  => 120,
					'step' => 1,
				),
				'priority'    => 20,
			)
		);

		$wp_customize->add_setting(
			$prefix . '_font_weight',
			array(
				'default'           => $defaults['font_weight'],
				'sanitize_callback' => 'rx_theme_sanitize_font_weight',
				'transport'         => 'refresh',
			)
		);

		$wp_customize->add_control(
			$prefix . '_font_weight',
			array(
				'label'    => sprintf( esc_html__( '%s Font Weight', 'rx-theme' ), $label ),
				'section'  => $section,
				'type'     => 'select',
				'choices'  => $rx_font_weights,
				'priority' => 30,
			)
		);

		$wp_customize->add_setting(
			$prefix . '_line_height',
			array(
				'default'           => $defaults['line_height'],
				'sanitize_callback' => 'rx_theme_sanitize_decimal',
				'transport'         => 'refresh',
			)
		);

		$wp_customize->add_control(
			$prefix . '_line_height',
			array(
				'label'       => sprintf( esc_html__( '%s Line Height', 'rx-theme' ), $label ),
				'section'     => $section,
				'type'        => 'number',
				'input_attrs' => array(
					'min'  => 0.8,
					'max'  => 4,
					'step' => 0.1,
				),
				'priority'    => 40,
			)
		);

		$wp_customize->add_setting(
			$prefix . '_letter_spacing',
			array(
				'default'           => $defaults['letter_spacing'],
				'sanitize_callback' => 'rx_theme_sanitize_decimal',
				'transport'         => 'refresh',
			)
		);

		$wp_customize->add_control(
			$prefix . '_letter_spacing',
			array(
				'label'       => sprintf( esc_html__( '%s Letter Spacing PX', 'rx-theme' ), $label ),
				'section'     => $section,
				'type'        => 'number',
				'input_attrs' => array(
					'min'  => -5,
					'max'  => 20,
					'step' => 0.1,
				),
				'priority'    => 50,
			)
		);

		$wp_customize->add_setting(
			$prefix . '_text_transform',
			array(
				'default'           => $defaults['text_transform'],
				'sanitize_callback' => 'rx_theme_sanitize_text_transform',
				'transport'         => 'refresh',
			)
		);

		$wp_customize->add_control(
			$prefix . '_text_transform',
			array(
				'label'    => sprintf( esc_html__( '%s Text Transform', 'rx-theme' ), $label ),
				'section'  => $section,
				'type'     => 'select',
				'choices'  => $rx_text_transforms,
				'priority' => 60,
			)
		);

		$wp_customize->add_setting(
			$prefix . '_font_style',
			array(
				'default'           => $defaults['font_style'],
				'sanitize_callback' => 'rx_theme_sanitize_font_style',
				'transport'         => 'refresh',
			)
		);

		$wp_customize->add_control(
			$prefix . '_font_style',
			array(
				'label'    => sprintf( esc_html__( '%s Font Style', 'rx-theme' ), $label ),
				'section'  => $section,
				'type'     => 'select',
				'choices'  => $rx_font_styles,
				'priority' => 70,
			)
		);
	};

	/**
	 * Global body typography.
	 */
	$add_typography_controls(
		'rx_body_typography',
		'rx_typography_global',
		esc_html__( 'Body', 'rx-theme' ),
		array(
			'font_size'   => 16,
			'font_weight' => '400',
			'line_height' => 1.7,
		)
	);

	/**
	 * Site title and tagline.
	 */
	$add_typography_controls(
		'rx_site_title_typography',
		'rx_typography_site_identity_text',
		esc_html__( 'Site Title', 'rx-theme' ),
		array(
			'font_size'      => 32,
			'font_weight'    => '700',
			'line_height'    => 1.2,
			'letter_spacing' => 0,
		)
	);

	$add_typography_controls(
		'rx_site_tagline_typography',
		'rx_typography_site_identity_text',
		esc_html__( 'Tagline', 'rx-theme' ),
		array(
			'font_size'   => 14,
			'font_weight' => '400',
			'line_height' => 1.5,
		)
	);

	/**
	 * Headings.
	 */
	$heading_defaults = array(
		'h1' => array( 42, '700', 1.2 ),
		'h2' => array( 36, '700', 1.25 ),
		'h3' => array( 30, '600', 1.3 ),
		'h4' => array( 24, '600', 1.35 ),
		'h5' => array( 20, '600', 1.4 ),
		'h6' => array( 16, '600', 1.45 ),
	);

	foreach ( $heading_defaults as $tag => $data ) {
		$add_typography_controls(
			'rx_' . $tag . '_typography',
			'rx_typography_headings',
			strtoupper( $tag ),
			array(
				'font_size'   => $data[0],
				'font_weight' => $data[1],
				'line_height' => $data[2],
			)
		);
	}

	/**
	 * Menu typography.
	 */
	$add_typography_controls(
		'rx_menu_typography',
		'rx_typography_menu',
		esc_html__( 'Main Menu', 'rx-theme' ),
		array(
			'font_size'      => 15,
			'font_weight'    => '600',
			'line_height'    => 1.4,
			'letter_spacing' => 0.2,
			'text_transform' => 'none',
		)
	);

	$add_typography_controls(
		'rx_submenu_typography',
		'rx_typography_menu',
		esc_html__( 'Sub Menu', 'rx-theme' ),
		array(
			'font_size'   => 14,
			'font_weight' => '400',
			'line_height' => 1.4,
		)
	);

	/**
	 * Content typography.
	 */
	$add_typography_controls(
		'rx_post_title_typography',
		'rx_typography_content',
		esc_html__( 'Post Title', 'rx-theme' ),
		array(
			'font_size'   => 38,
			'font_weight' => '700',
			'line_height' => 1.25,
		)
	);

	$add_typography_controls(
		'rx_archive_title_typography',
		'rx_typography_content',
		esc_html__( 'Archive Title', 'rx-theme' ),
		array(
			'font_size'   => 34,
			'font_weight' => '700',
			'line_height' => 1.25,
		)
	);

	$add_typography_controls(
		'rx_post_meta_typography',
		'rx_typography_content',
		esc_html__( 'Post Meta', 'rx-theme' ),
		array(
			'font_size'      => 14,
			'font_weight'    => '400',
			'line_height'    => 1.5,
			'letter_spacing' => 0.1,
		)
	);

	$add_typography_controls(
		'rx_excerpt_typography',
		'rx_typography_content',
		esc_html__( 'Post Excerpt', 'rx-theme' ),
		array(
			'font_size'   => 16,
			'font_weight' => '400',
			'line_height' => 1.7,
		)
	);

	/**
	 * Buttons.
	 */
	$add_typography_controls(
		'rx_button_typography',
		'rx_typography_buttons',
		esc_html__( 'Buttons', 'rx-theme' ),
		array(
			'font_size'      => 15,
			'font_weight'    => '600',
			'line_height'    => 1.3,
			'letter_spacing' => 0.3,
			'text_transform' => 'none',
		)
	);

	/**
	 * Forms.
	 */
	$add_typography_controls(
		'rx_form_label_typography',
		'rx_typography_forms',
		esc_html__( 'Form Label', 'rx-theme' ),
		array(
			'font_size'   => 14,
			'font_weight' => '600',
			'line_height' => 1.4,
		)
	);

	$add_typography_controls(
		'rx_form_input_typography',
		'rx_typography_forms',
		esc_html__( 'Form Input', 'rx-theme' ),
		array(
			'font_size'   => 15,
			'font_weight' => '400',
			'line_height' => 1.5,
		)
	);

	/**
	 * Widget typography.
	 */
	$add_typography_controls(
		'rx_widget_title_typography',
		'rx_typography_widgets',
		esc_html__( 'Widget Title', 'rx-theme' ),
		array(
			'font_size'      => 20,
			'font_weight'    => '700',
			'line_height'    => 1.3,
			'letter_spacing' => 0,
		)
	);

	$add_typography_controls(
		'rx_widget_text_typography',
		'rx_typography_widgets',
		esc_html__( 'Widget Text', 'rx-theme' ),
		array(
			'font_size'   => 15,
			'font_weight' => '400',
			'line_height' => 1.6,
		)
	);

	/**
	 * Footer typography.
	 */
	$add_typography_controls(
		'rx_footer_text_typography',
		'rx_typography_footer',
		esc_html__( 'Footer Text', 'rx-theme' ),
		array(
			'font_size'   => 14,
			'font_weight' => '400',
			'line_height' => 1.6,
		)
	);

	$add_typography_controls(
		'rx_footer_link_typography',
		'rx_typography_footer',
		esc_html__( 'Footer Links', 'rx-theme' ),
		array(
			'font_size'   => 14,
			'font_weight' => '500',
			'line_height' => 1.6,
		)
	);

	/**
	 * Responsive typography.
	 */
	$responsive_controls = array(
		'rx_tablet_body_font_size'  => array(
			'label'   => esc_html__( 'Tablet Body Font Size PX', 'rx-theme' ),
			'default' => 15,
		),
		'rx_mobile_body_font_size'  => array(
			'label'   => esc_html__( 'Mobile Body Font Size PX', 'rx-theme' ),
			'default' => 15,
		),
		'rx_tablet_h1_font_size'    => array(
			'label'   => esc_html__( 'Tablet H1 Font Size PX', 'rx-theme' ),
			'default' => 36,
		),
		'rx_mobile_h1_font_size'    => array(
			'label'   => esc_html__( 'Mobile H1 Font Size PX', 'rx-theme' ),
			'default' => 30,
		),
		'rx_tablet_h2_font_size'    => array(
			'label'   => esc_html__( 'Tablet H2 Font Size PX', 'rx-theme' ),
			'default' => 30,
		),
		'rx_mobile_h2_font_size'    => array(
			'label'   => esc_html__( 'Mobile H2 Font Size PX', 'rx-theme' ),
			'default' => 26,
		),
		'rx_tablet_menu_font_size'  => array(
			'label'   => esc_html__( 'Tablet Menu Font Size PX', 'rx-theme' ),
			'default' => 15,
		),
		'rx_mobile_menu_font_size'  => array(
			'label'   => esc_html__( 'Mobile Menu Font Size PX', 'rx-theme' ),
			'default' => 14,
		),
		'rx_tablet_post_title_size' => array(
			'label'   => esc_html__( 'Tablet Post Title Font Size PX', 'rx-theme' ),
			'default' => 32,
		),
		'rx_mobile_post_title_size' => array(
			'label'   => esc_html__( 'Mobile Post Title Font Size PX', 'rx-theme' ),
			'default' => 28,
		),
	);

	$priority = 10;

	foreach ( $responsive_controls as $setting_id => $control ) {
		$wp_customize->add_setting(
			$setting_id,
			array(
				'default'           => $control['default'],
				'sanitize_callback' => 'absint',
				'transport'         => 'refresh',
			)
		);

		$wp_customize->add_control(
			$setting_id,
			array(
				'label'       => $control['label'],
				'section'     => 'rx_typography_responsive',
				'type'        => 'number',
				'input_attrs' => array(
					'min'  => 8,
					'max'  => 90,
					'step' => 1,
				),
				'priority'    => $priority,
			)
		);

		$priority += 10;
	}
}
add_action( 'customize_register', 'rx_theme_typography_options' );

/**
 * Sanitization: Font Family.
 */
function rx_theme_sanitize_font_family( $input ) {
	$allowed = array(
		'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
		'Arial, Helvetica, sans-serif',
		'Helvetica, Arial, sans-serif',
		'Georgia, serif',
		'"Times New Roman", Times, serif',
		'"Trebuchet MS", Helvetica, sans-serif',
		'Verdana, Geneva, sans-serif',
		'"Courier New", Courier, monospace',
		'"Roboto", sans-serif',
		'"Open Sans", sans-serif',
		'"Lato", sans-serif',
		'"Poppins", sans-serif',
		'"Montserrat", sans-serif',
		'"Inter", sans-serif',
		'"Nunito", sans-serif',
		'"Merriweather", serif',
		'"Playfair Display", serif',
		'"Source Sans 3", sans-serif',
		'"Noto Sans", sans-serif',
		'"Noto Serif", serif',
	);

	return in_array( $input, $allowed, true ) ? $input : 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif';
}

/**
 * Sanitization: Font Weight.
 */
function rx_theme_sanitize_font_weight( $input ) {
	$allowed = array( '100', '200', '300', '400', '500', '600', '700', '800', '900' );
	return in_array( (string) $input, $allowed, true ) ? (string) $input : '400';
}

/**
 * Sanitization: Decimal.
 */
function rx_theme_sanitize_decimal( $input ) {
	return is_numeric( $input ) ? floatval( $input ) : 0;
}

/**
 * Sanitization: Text Transform.
 */
function rx_theme_sanitize_text_transform( $input ) {
	$allowed = array( 'none', 'capitalize', 'uppercase', 'lowercase' );
	return in_array( $input, $allowed, true ) ? $input : 'none';
}

/**
 * Sanitization: Font Style.
 */
function rx_theme_sanitize_font_style( $input ) {
	$allowed = array( 'normal', 'italic', 'oblique' );
	return in_array( $input, $allowed, true ) ? $input : 'normal';
}

/**
 * Helper: Return typography CSS.
 */
function rx_theme_typography_css( $prefix, $selector ) {

	$font_family    = get_theme_mod( $prefix . '_font_family', 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif' );
	$font_size      = absint( get_theme_mod( $prefix . '_font_size', 16 ) );
	$font_weight    = rx_theme_sanitize_font_weight( get_theme_mod( $prefix . '_font_weight', '400' ) );
	$line_height    = rx_theme_sanitize_decimal( get_theme_mod( $prefix . '_line_height', 1.7 ) );
	$letter_spacing = rx_theme_sanitize_decimal( get_theme_mod( $prefix . '_letter_spacing', 0 ) );
	$text_transform = rx_theme_sanitize_text_transform( get_theme_mod( $prefix . '_text_transform', 'none' ) );
	$font_style     = rx_theme_sanitize_font_style( get_theme_mod( $prefix . '_font_style', 'normal' ) );

	$css  = $selector . "{";
	$css .= "font-family:" . esc_html( $font_family ) . ";";
	$css .= "font-size:" . esc_html( $font_size ) . "px;";
	$css .= "font-weight:" . esc_html( $font_weight ) . ";";
	$css .= "line-height:" . esc_html( $line_height ) . ";";
	$css .= "letter-spacing:" . esc_html( $letter_spacing ) . "px;";
	$css .= "text-transform:" . esc_html( $text_transform ) . ";";
	$css .= "font-style:" . esc_html( $font_style ) . ";";
	$css .= "}";

	return $css;
}

/**
 * Output Dynamic Typography CSS.
 */
function rx_theme_output_typography_css() {

	$css = '';

	$css .= rx_theme_typography_css(
		'rx_body_typography',
		'body, button, input, select, optgroup, textarea'
	);

	$css .= rx_theme_typography_css(
		'rx_site_title_typography',
		'.site-title, .site-title a, .rx-site-title, .rx-site-title a'
	);

	$css .= rx_theme_typography_css(
		'rx_site_tagline_typography',
		'.site-description, .rx-site-description, .rx-tagline'
	);

	$css .= rx_theme_typography_css(
		'rx_h1_typography',
		'h1, .h1, .entry-content h1, .wp-block-heading h1'
	);

	$css .= rx_theme_typography_css(
		'rx_h2_typography',
		'h2, .h2, .entry-content h2, .wp-block-heading h2'
	);

	$css .= rx_theme_typography_css(
		'rx_h3_typography',
		'h3, .h3, .entry-content h3, .wp-block-heading h3'
	);

	$css .= rx_theme_typography_css(
		'rx_h4_typography',
		'h4, .h4, .entry-content h4, .wp-block-heading h4'
	);

	$css .= rx_theme_typography_css(
		'rx_h5_typography',
		'h5, .h5, .entry-content h5, .wp-block-heading h5'
	);

	$css .= rx_theme_typography_css(
		'rx_h6_typography',
		'h6, .h6, .entry-content h6, .wp-block-heading h6'
	);

	$css .= rx_theme_typography_css(
		'rx_menu_typography',
		'.main-navigation a, .primary-menu a, .menu-primary-container a, nav ul li a'
	);

	$css .= rx_theme_typography_css(
		'rx_submenu_typography',
		'.main-navigation ul ul a, .primary-menu ul ul a, nav ul ul li a'
	);

	$css .= rx_theme_typography_css(
		'rx_post_title_typography',
		'.entry-title, .entry-title a, .single .entry-title, .page .entry-title, .rx-post-title'
	);

	$css .= rx_theme_typography_css(
		'rx_archive_title_typography',
		'.archive-title, .page-title, .rx-archive-title'
	);

	$css .= rx_theme_typography_css(
		'rx_post_meta_typography',
		'.entry-meta, .entry-meta a, .posted-on, .byline, .cat-links, .tags-links'
	);

	$css .= rx_theme_typography_css(
		'rx_excerpt_typography',
		'.entry-summary, .post-excerpt, .rx-excerpt'
	);

	$css .= rx_theme_typography_css(
		'rx_button_typography',
		'button, .button, .btn, input[type="button"], input[type="reset"], input[type="submit"], .wp-block-button__link, .rx-button'
	);

	$css .= rx_theme_typography_css(
		'rx_form_label_typography',
		'label, .comment-form label, .wpcf7 label'
	);

	$css .= rx_theme_typography_css(
		'rx_form_input_typography',
		'input, textarea, select, .wpcf7-form-control'
	);

	$css .= rx_theme_typography_css(
		'rx_widget_title_typography',
		'.widget-title, .widget .wp-block-heading, .sidebar .widget-title, .footer-widget .widget-title'
	);

	$css .= rx_theme_typography_css(
		'rx_widget_text_typography',
		'.widget, .widget p, .widget li, .widget a'
	);

	$css .= rx_theme_typography_css(
		'rx_footer_text_typography',
		'.site-footer, .site-footer p, .rx-footer, .rx-footer p'
	);

	$css .= rx_theme_typography_css(
		'rx_footer_link_typography',
		'.site-footer a, .rx-footer a'
	);

	/**
	 * Content special readability.
	 */
	$css .= '
		.entry-content,
		.page-content,
		.comment-content {
			text-rendering: optimizeLegibility;
			-webkit-font-smoothing: antialiased;
			-moz-osx-font-smoothing: grayscale;
		}

		.entry-content p,
		.page-content p {
			margin-bottom: 1.25em;
		}

		.entry-content ul,
		.entry-content ol,
		.page-content ul,
		.page-content ol {
			margin-bottom: 1.25em;
		}

		.entry-content blockquote,
		.wp-block-quote {
			font-size: 1.1em;
			line-height: 1.7;
			font-style: italic;
		}

		code,
		kbd,
		pre,
		samp {
			font-family: "Courier New", Courier, monospace;
		}
	';

	/**
	 * Responsive CSS.
	 */
	$tablet_body      = absint( get_theme_mod( 'rx_tablet_body_font_size', 15 ) );
	$mobile_body      = absint( get_theme_mod( 'rx_mobile_body_font_size', 15 ) );
	$tablet_h1        = absint( get_theme_mod( 'rx_tablet_h1_font_size', 36 ) );
	$mobile_h1        = absint( get_theme_mod( 'rx_mobile_h1_font_size', 30 ) );
	$tablet_h2        = absint( get_theme_mod( 'rx_tablet_h2_font_size', 30 ) );
	$mobile_h2        = absint( get_theme_mod( 'rx_mobile_h2_font_size', 26 ) );
	$tablet_menu      = absint( get_theme_mod( 'rx_tablet_menu_font_size', 15 ) );
	$mobile_menu      = absint( get_theme_mod( 'rx_mobile_menu_font_size', 14 ) );
	$tablet_post_title = absint( get_theme_mod( 'rx_tablet_post_title_size', 32 ) );
	$mobile_post_title = absint( get_theme_mod( 'rx_mobile_post_title_size', 28 ) );

	$css .= '
		@media (max-width: 1024px) {
			body {
				font-size: ' . esc_html( $tablet_body ) . 'px;
			}

			h1,
			.h1,
			.entry-content h1 {
				font-size: ' . esc_html( $tablet_h1 ) . 'px;
			}

			h2,
			.h2,
			.entry-content h2 {
				font-size: ' . esc_html( $tablet_h2 ) . 'px;
			}

			.main-navigation a,
			.primary-menu a,
			nav ul li a {
				font-size: ' . esc_html( $tablet_menu ) . 'px;
			}

			.entry-title,
			.single .entry-title,
			.page .entry-title {
				font-size: ' . esc_html( $tablet_post_title ) . 'px;
			}
		}

		@media (max-width: 767px) {
			body {
				font-size: ' . esc_html( $mobile_body ) . 'px;
			}

			h1,
			.h1,
			.entry-content h1 {
				font-size: ' . esc_html( $mobile_h1 ) . 'px;
			}

			h2,
			.h2,
			.entry-content h2 {
				font-size: ' . esc_html( $mobile_h2 ) . 'px;
			}

			.main-navigation a,
			.primary-menu a,
			nav ul li a {
				font-size: ' . esc_html( $mobile_menu ) . 'px;
			}

			.entry-title,
			.single .entry-title,
			.page .entry-title {
				font-size: ' . esc_html( $mobile_post_title ) . 'px;
			}
		}
	';

	if ( ! empty( $css ) ) {
		echo '<style id="rx-theme-typography-css">' . wp_strip_all_tags( $css ) . '</style>';
	}
}
add_action( 'wp_head', 'rx_theme_output_typography_css', 99 );

/**
 * Enqueue selected Google Fonts.
 */
function rx_theme_enqueue_typography_fonts() {

	$google_fonts = array(
		'"Roboto", sans-serif'          => 'Roboto:wght@100;200;300;400;500;600;700;800;900',
		'"Open Sans", sans-serif'       => 'Open+Sans:wght@300;400;500;600;700;800',
		'"Lato", sans-serif'            => 'Lato:wght@100;300;400;700;900',
		'"Poppins", sans-serif'         => 'Poppins:wght@100;200;300;400;500;600;700;800;900',
		'"Montserrat", sans-serif'      => 'Montserrat:wght@100;200;300;400;500;600;700;800;900',
		'"Inter", sans-serif'           => 'Inter:wght@100;200;300;400;500;600;700;800;900',
		'"Nunito", sans-serif'          => 'Nunito:wght@200;300;400;500;600;700;800;900',
		'"Merriweather", serif'         => 'Merriweather:wght@300;400;700;900',
		'"Playfair Display", serif'     => 'Playfair+Display:wght@400;500;600;700;800;900',
		'"Source Sans 3", sans-serif'   => 'Source+Sans+3:wght@200;300;400;500;600;700;800;900',
		'"Noto Sans", sans-serif'       => 'Noto+Sans:wght@100;200;300;400;500;600;700;800;900',
		'"Noto Serif", serif'           => 'Noto+Serif:wght@100;200;300;400;500;600;700;800;900',
	);

	$settings_to_check = array(
		'rx_body_typography_font_family',
		'rx_site_title_typography_font_family',
		'rx_site_tagline_typography_font_family',
		'rx_h1_typography_font_family',
		'rx_h2_typography_font_family',
		'rx_h3_typography_font_family',
		'rx_h4_typography_font_family',
		'rx_h5_typography_font_family',
		'rx_h6_typography_font_family',
		'rx_menu_typography_font_family',
		'rx_submenu_typography_font_family',
		'rx_post_title_typography_font_family',
		'rx_archive_title_typography_font_family',
		'rx_post_meta_typography_font_family',
		'rx_excerpt_typography_font_family',
		'rx_button_typography_font_family',
		'rx_form_label_typography_font_family',
		'rx_form_input_typography_font_family',
		'rx_widget_title_typography_font_family',
		'rx_widget_text_typography_font_family',
		'rx_footer_text_typography_font_family',
		'rx_footer_link_typography_font_family',
	);

	$families = array();

	foreach ( $settings_to_check as $setting ) {
		$selected_font = get_theme_mod( $setting );

		if ( isset( $google_fonts[ $selected_font ] ) ) {
			$families[] = $google_fonts[ $selected_font ];
		}
	}

	$families = array_unique( $families );

	if ( ! empty( $families ) ) {
		$fonts_url = add_query_arg(
			array(
				'family'  => implode( '&family=', $families ),
				'display' => 'swap',
			),
			'https://fonts.googleapis.com/css2'
		);

		wp_enqueue_style(
			'rx-theme-google-fonts',
			esc_url_raw( $fonts_url ),
			array(),
			null
		);
	}
}
add_action( 'wp_enqueue_scripts', 'rx_theme_enqueue_typography_fonts' );

Now include it in your theme functions.php:

/**
 * RX Theme Typography Options.
 */
require_once get_template_directory() . '/inc/options/typography-options.php';

After adding it, go to:

WordPress Dashboard → Appearance → Customize → RX Typography

You will see typography controls for body, headings, menu, posts, buttons, forms, widgets, footer, and responsive devices.

Leave a Reply

Your email address will not be published. Required fields are marked *