Fluid Typography Calculator

Clamp Calculator

Use this Clamp() Calculation Generator by modifying the Widths, and Select the Font Size Units. Can be used for other areas such as Margins, and more (just modify/add Classes where required). 

Fluid Typography Calculator

Tag
Min Width (px)
Min Font Size (px)
Max Width (px)
Max Font Size (px)
hero-h1
h1
h2
h3
h4
h5
h6
body
p
p-accent

Using the fluid typography calculator is simple:

 

  1. Root HTML Font Size (px): This is usually 16px by default, but you can adjust it if needed.
  2. Fill in your tag (e.g., h1, p, body) and input values for the following fields:
    • Min Width (px): The smallest screen size where the font should start scaling.
    • Min Font Size (px): The minimum size the font should scale down to on smaller screens.
    • Max Width (px): The largest screen size where the font should stop scaling.
    • Max Font Size (px): The largest size the font should scale up to on larger screens.
  3. After entering your values, click Generate, and the calculator will output the CSS code you can use in your project.

Fluid typography ensures your text scales seamlessly across different screen sizes, enhancing readability and user experience. By using relative units like REM and VW, fluid typography adapts to both small and large screens, creating a more responsive design. This eliminates the need for multiple media queries, making your design more efficient while maintaining consistent proportions. In short, it provides flexibility and saves time, giving your website a more polished, adaptable feel.

To use Font Clamp in Elementor, follow these simple steps:

  1. Open the Elementor editor and select the element you want to apply fluid typography to (e.g., Heading, Text, etc.).
  2. In the Typography section, click on the Custom (pencil) option for font size.
  3. Input the generated clamp() [ clamp(1.5rem, 0.97439rem + 2.21311vw, 3.1875rem) ] CSS code from the calculator directly into the Custom CSS section for the selected element.
  4. Save and preview your site to see the responsive typography in action. This method allows your text to scale smoothly between defined minimum and maximum sizes, ensuring a balanced design on all screen sizes.

For best results, apply the clamp to every global font in your Site Settings tab.

				
					// Function to add the calculator to the admin menu
function ft_calculator_admin_menu()
{
    add_menu_page(
        "Fluid Typography Calculator", // Page title
        "Typography Calculator", // Menu title
        "manage_options", // Capability
        "fluid-typography-calculator", // Menu slug
        "ft_calculator_page" // Function that displays the page content
    );
}

add_action("admin_menu", "ft_calculator_admin_menu");

// Function that generates the calculator page
function ft_calculator_page() {
    // Initialize the $useRem variable at the start of the function
    $useRem = false;

    echo '<div class="wrap"><h2>Fluid Typography Calculator</h2>';

    // Basic styles for the form and output
    echo '<style>
            .ft-form input[type="number"] {
                width: 100px;
                padding: 2px;
                margin: 2px 0;
                box-sizing: border-box;
                border: 1px solid #ccc;
                border-radius: 4px;
            }
            .ft-form label {
                font-weight: bold;
            }
            .ft-form div {
                margin-bottom: 10px;
            }
			.ft-form textarea {
				width: 100%;  // Adjust this to your preference
				height: 150px; // Or any height that suits your layout
				padding: 8px;
				border: 1px solid #ccc;
				border-radius: 22px;
				margin-top: 10px;
			}

			#cssOutput, #cssVariablesOutput {
				width: 100%; // Makes the textarea take up the full width of its container
				max-width: 100%; // You can adjust this as needed
				min-width: 300px; // Ensures a minimum width
				padding: 8px;
				border: 1px solid #ccc;
				border-radius: 4px; // You can adjust this as needed
				margin-top: 10px;
			}

            .ft-form button {
                background-color: #4CAF50;
                color: white;
                padding: 10px 15px;
                border: none;
                border-radius: 4px;
                cursor: pointer;
            }
            .ft-form button:hover {
                background-color: #45a049;
            }
            .grid-container {
                display: grid;
                grid-template-columns: repeat(5, 1fr);
                gap: 10px;
            }
          </style>';

    // Initialize variables
    $rootFontSize = isset($_POST["rootFontSize"]) ? $_POST["rootFontSize"] : 16;
    $defaultValues = [
        "hero-h1" => [
            "MinWidth" => 380,
            "MinFontSize" => 32,
            "MaxWidth" => 1600,
            "MaxFontSize" => 80,
        ],
        "h1" => [
            "MinWidth" => 380,
            "MinFontSize" => 29,
            "MaxWidth" => 1600,
            "MaxFontSize" => 68,
        ],
        "h2" => [
            "MinWidth" => 380,
            "MinFontSize" => 24,
            "MaxWidth" => 1600,
            "MaxFontSize" => 51,
        ],
        "h3" => [
            "MinWidth" => 380,
            "MinFontSize" => 20,
            "MaxWidth" => 1600,
            "MaxFontSize" => 38,
        ],
        "h4" => [
            "MinWidth" => 380,
            "MinFontSize" => 17,
            "MaxWidth" => 1600,
            "MaxFontSize" => 29,
        ],
        "h5" => [
            "MinWidth" => 380,
            "MinFontSize" => 14,
            "MaxWidth" => 1600,
            "MaxFontSize" => 22,
        ],
        "h6" => [
            "MinWidth" => 380,
            "MinFontSize" => 12,
            "MaxWidth" => 1600,
            "MaxFontSize" => 16,
        ],
        "body" => [
            "MinWidth" => 380,
            "MinFontSize" => 16,
            "MaxWidth" => 1600,
            "MaxFontSize" => 24,
        ],
        "p" => [
            "MinWidth" => 380,
            "MinFontSize" => 14,
            "MaxWidth" => 1600,
            "MaxFontSize" => 28,
        ],
		"p-accent" => [
            "MinWidth" => 380,
            "MinFontSize" => 16,
            "MaxWidth" => 1600,
            "MaxFontSize" => 24,
        ],
    ];

    $cssOutput = ""; // Initialize traditional CSS output string
    $cssVariablesOutput = ""; // Initialize CSS variables output string

    // Check if form is submitted
    if ($_SERVER["REQUEST_METHOD"] == "POST") {
        $useRem = isset($_POST["unitToggle"]) && $_POST["unitToggle"] === 'on';
        // Security check using nonce
        if (!isset($_POST["ft_calculator_nonce_field"]) || !wp_verify_nonce($_POST["ft_calculator_nonce_field"], "ft_calculator_action")) {
            echo "<p>Security check failed. Please try again.</p>";
            return;
        }

        foreach (["hero-h1", "h1", "h2", "h3", "h4", "h5", "h6", "body", "p", "p-accent"] as $tag) {
            $minWidth = isset($_POST[$tag . "MinWidth"]) ? $_POST[$tag . "MinWidth"] : $defaultValues[$tag]["MinWidth"];
            $minFontSizePx = isset($_POST[$tag . "MinFontSize"]) ? $_POST[$tag . "MinFontSize"] : $defaultValues[$tag]["MinFontSize"];
            $maxWidth = isset($_POST[$tag . "MaxWidth"]) ? $_POST[$tag . "MaxWidth"] : $defaultValues[$tag]["MaxWidth"];
            $maxFontSizePx = isset($_POST[$tag . "MaxFontSize"]) ? $_POST[$tag . "MaxFontSize"] : $defaultValues[$tag]["MaxFontSize"];

            // Capture the original input values for the comments
            $originalMinFontSizePx = $minFontSizePx;
            $originalMaxFontSizePx = $maxFontSizePx;

            // Handle unit conversion
            if ($useRem) {
                // Convert REM to Pixels for internal calculation
                $minFontSizePx *= $rootFontSize;
                $maxFontSizePx *= $rootFontSize;
            }

            // Convert pixel values to REM for CSS generation
            $minFontSize = $minFontSizePx / $rootFontSize; // In rem
            $maxFontSize = $maxFontSizePx / $rootFontSize; // In rem

            // Convert widths from px to vw (assuming 1rem = rootFontSize px)
            $minWidthVW = $minWidth / $rootFontSize; // In vw
            $maxWidthVW = $maxWidth / $rootFontSize; // In vw

            // Calculate the CSS
            $vwUnit = (($maxFontSize - $minFontSize) / ($maxWidthVW - $minWidthVW)) * 100;
            $constant = $minFontSize - ($vwUnit * $minWidthVW) / 100;

            // Format to a maximum of 5 decimal places
            $vwUnitFormatted = number_format($vwUnit, 5, ".", "");
            $constantFormatted = number_format($constant, 5, ".", "");

			  // Add to traditional CSS output
              if ($tag === "hero-h1") {
                $cssOutput .=
                    ".hero-h1 h1 {font-size: clamp(" .
                    $minFontSize .
                    "rem, " .
                    $constantFormatted .
                    "rem + " .
                    $vwUnitFormatted .
                    "vw, " .
                    $maxFontSize .
                    "rem); /* " .
                    number_format($originalMinFontSizePx, 0) .
                    "px to " .
                    number_format($originalMaxFontSizePx, 0) .
                    "px */ /* .hero-h1 CSS class for homepage hero section */}\n";
            	} elseif ($tag === "p-accent") {
                $cssOutput .=
                    ".p-accent {font-size: clamp(" .
                    $minFontSize .
                    "rem, " .
                    $constantFormatted .
                    "rem + " .
                    $vwUnitFormatted .
                    "vw, " .
                    $maxFontSize .
                    "rem); /* " .
                    number_format($originalMinFontSizePx, 0) .
                    "px to " .
                    number_format($originalMaxFontSizePx, 0) .
                    "px */ /* .p-accent CSS class for Subheadings and accents */}\n";
           	   } else {
                $cssOutput .=
                    "{$tag} {font-size: clamp(" .
                    $minFontSize .
                    "rem, " .
                    $constantFormatted .
                    "rem + " .
                    $vwUnitFormatted .
                    "vw, " .
                    $maxFontSize .
                    "rem); /* " .
                    number_format($originalMinFontSizePx, 0) .
                    "px to " .
                    number_format($originalMaxFontSizePx, 0) .
                    "px */}\n";
            }

            // Add to CSS variables output
            $cssVariablesOutput .=
                "  --{$tag}-font-size: clamp(" .
                $minFontSize .
                "rem, " .
                $constantFormatted .
                "rem + " .
                $vwUnitFormatted .
                "vw, " .
                $maxFontSize .
                "rem); /* " .
                number_format($originalMinFontSizePx, 0) .
                "px to " .
                number_format($originalMaxFontSizePx, 0) .
                "px */\n";
        }

        // Wrap CSS variables in a :root selector
        $cssVariablesOutput = ":root {\n" . $cssVariablesOutput . "}\n";
    }

    // Display the form
    echo '<form class="ft-form" method="post">';
    wp_nonce_field("ft_calculator_action", "ft_calculator_nonce_field");

    echo '<div>
        <label for="rootFontSize">Root HTML Font Size (px):</label>
        <input type="number" id="rootFontSize" name="rootFontSize" required value="' . htmlspecialchars($rootFontSize) . '">
      </div>
      <div>
        <label for="unitToggle">Use REM Units for Font Size:</label>
        <input type="checkbox" id="unitToggle" name="unitToggle" ' . ($useRem ? 'checked' : '') . ' onchange="toggleUnits()">
      </div>';

    echo '<div class="grid-container">
        <div><strong>Tag</strong></div>
        <div><strong>Min Width (px)</strong></div>
        <div><strong>Min Font Size (' . ($useRem ? 'rem' : 'px') . ')</strong></div>
        <div><strong>Max Width (px)</strong></div>
        <div><strong>Max Font Size (' . ($useRem ? 'rem' : 'px') . ')</strong></div>';

    // Display input fields for each tag
    foreach ([ "hero-h1", "h1", "h2", "h3", "h4", "h5", "h6", "body", "p", "p-accent"] as $tag) {
        $minWidthValue = isset($_POST[$tag . "MinWidth"]) ? $_POST[$tag . "MinWidth"] : $defaultValues[$tag]["MinWidth"];
        $minFontSizeValue = isset($_POST[$tag . "MinFontSize"]) ? $_POST[$tag . "MinFontSize"] : $defaultValues[$tag]["MinFontSize"];
        $maxWidthValue = isset($_POST[$tag . "MaxWidth"]) ? $_POST[$tag . "MaxWidth"] : $defaultValues[$tag]["MaxWidth"];
        $maxFontSizeValue = isset($_POST[$tag . "MaxFontSize"]) ? $_POST[$tag . "MaxFontSize"] : $defaultValues[$tag]["MaxFontSize"];

        echo "<div><strong>{$tag}</strong></div>
          <div><input type='number' id='{$tag}MinWidth' name='{$tag}MinWidth' class='unit-input' required value='{$minWidthValue}'></div>
          <div><input type='number' id='{$tag}MinFontSize' name='{$tag}MinFontSize' class='unit-input' step='0.01' required value='{$minFontSizeValue}'></div>
          <div><input type='number' id='{$tag}MaxWidth' name='{$tag}MaxWidth' class='unit-input' required value='{$maxWidthValue}'></div>
          <div><input type='number' id='{$tag}MaxFontSize' name='{$tag}MaxFontSize' class='unit-input' step='0.01' required value='{$maxFontSizeValue}'></div>";
    }

    echo '</div><input type="submit" value="Generate CSS"></form>';

    // Display the traditional CSS output
    if (!empty($cssOutput)) {
        echo "<h2>Generated CSS:</h2>";
        echo '<textarea id="cssOutput" rows="15">' . htmlspecialchars($cssOutput) . "</textarea><br>";
        echo '<button onclick="copyToClipboard(\'cssOutput\')">Copy CSS</button>';
    }

    // Display the CSS variables output
    if (!empty($cssVariablesOutput)) {
        echo "<h2>Generated CSS Variables:</h2>";
        echo '<textarea id="cssVariablesOutput" rows="15">' . htmlspecialchars($cssVariablesOutput) . "</textarea><br>";
        echo '<button onclick="copyToClipboard(\'cssVariablesOutput\')">Copy CSS Variables</button>';
    }

    // JavaScript for copy to clipboard functionality and unit conversion
    echo '<script>
            function copyToClipboard(elementId) {
                var copyText = document.getElementById(elementId);
                copyText.select();
                document.execCommand("copy");
            }

            function toggleUnits() {
                var useRem = document.getElementById("unitToggle").checked;
                var rootFontSize = parseFloat(document.getElementById("rootFontSize").value);
                var fontSizeElements = document.querySelectorAll(".unit-input"); // Class for font size inputs

                fontSizeElements.forEach(function(element) {
                    if (element.id.endsWith("MinFontSize") || element.id.endsWith("MaxFontSize")) {
                        var value = parseFloat(element.value);
                        if (!isNaN(value)) {
                            if (useRem) {
                                element.value = (value / rootFontSize).toFixed(2); // Convert to REM
                            } else {
                                element.value = (value * rootFontSize).toFixed(0); // Convert to Pixels
                            }
                        }
                    }
                });
            }
          </script>';

    echo "</div>";
}

// Define the function for the fluid typography calculator
function fluid_typography_calculator() {
    // Call the existing function to display the fluid typography calculator
    ft_calculator_page();
}

// Add the shortcode
add_shortcode('Fluid_calc', 'fluid_typography_calculator');

				
			

Step 1: Install the plugin “Code Snippet” or whatever you prefer.

Step 2: Add a new PHP Snippet

Step 3: copy the code from above.

Step 4: Click Save!

Step 5: Add the shortcode * [ In Brackets  ] *  Fluid_calc Or fluid_typography_calculator to the page you want to use it on. 

Step 6: Publish changes and enjoy!