1/*
2 * This script creates an admin page with a fluid typography calculator.
3 * Add this snippet to your code snippets plugin of choice.
4 * It outputs both traditional CSS and CSS variables for typography.
5 * It includes basic styling and a copy to clipboard feature, along with nonce security for form submission.
6 * To use the variables in bricks add the output CSS to your stylesheet or Appearance>Customize
7 * Then, when editing add a variable such as var(--h1-font-size) in your font size style input.
8 */
9
10// Function to add the calculator to the admin menu
11function ft_calculator_admin_menu()
12{
13 add_menu_page(
14 "Fluid Typography Calculator", // Page title
15 "Typography Calculator", // Menu title
16 "manage_options", // Capability
17 "fluid-typography-calculator", // Menu slug
18 "ft_calculator_page" // Function that displays the page content
19 );
20}
21
22add_action("admin_menu", "ft_calculator_admin_menu");
23
24// Function that generates the calculator page
25function ft_calculator_page()
26{
27 echo '<div class="wrap"><h1>Fluid Typography Calculator</h1>';
28
29 // Basic styles for the form and output
30 echo '<style>
31 .ft-form input[type="number"] {
32 width: 100px;
33 padding: 8px;
34 margin: 4px 0;
35 box-sizing: border-box;
36 border: 1px solid #ccc;
37 border-radius: 4px;
38 }
39 .ft-form label {
40 font-weight: bold;
41 }
42 .ft-form div {
43 margin-bottom: 0px;
44 }
45 .ft-form textarea {
46 width: 100%;
47 padding: 8px;
48 border: 1px solid #ccc;
49 border-radius: 4px;
50 margin-top: 10px;
51 }
52 .ft-form button {
53 background-color: #4CAF50;
54 color: white;
55 padding: 10px 15px;
56 border: none;
57 border-radius: 4px;
58 cursor: pointer;
59 }
60 .ft-form button:hover {
61 background-color: #45a049;
62 }
63 .grid-container {
64 display: grid;
65 grid-template-columns: repeat(5, 1fr);
66 gap: 10px;
67 }
68 </style>';
69
70 // Initialize variables
71 $rootFontSize = isset($_POST["rootFontSize"]) ? $_POST["rootFontSize"] : 16;
72 $defaultValues = [
73 "h1" => [
74 "MinWidth" => 380,
75 "MinFontSize" => 29,
76 "MaxWidth" => 1600,
77 "MaxFontSize" => 68,
78 ],
79 "h2" => [
80 "MinWidth" => 380,
81 "MinFontSize" => 24,
82 "MaxWidth" => 1600,
83 "MaxFontSize" => 51,
84 ],
85 "h3" => [
86 "MinWidth" => 380,
87 "MinFontSize" => 20,
88 "MaxWidth" => 1600,
89 "MaxFontSize" => 38,
90 ],
91 "h4" => [
92 "MinWidth" => 380,
93 "MinFontSize" => 17,
94 "MaxWidth" => 1600,
95 "MaxFontSize" => 29,
96 ],
97 "h5" => [
98 "MinWidth" => 380,
99 "MinFontSize" => 14,
100 "MaxWidth" => 1600,
101 "MaxFontSize" => 22,
102 ],
103 "h6" => [
104 "MinWidth" => 380,
105 "MinFontSize" => 12,
106 "MaxWidth" => 1600,
107 "MaxFontSize" => 16,
108 ],
109 "body" => [
110 "MinWidth" => 380,
111 "MinFontSize" => 16,
112 "MaxWidth" => 1600,
113 "MaxFontSize" => 24,
114 ],
115 "p" => [
116 "MinWidth" => 380,
117 "MinFontSize" => 16,
118 "MaxWidth" => 1600,
119 "MaxFontSize" => 24,
120 ],
121 ];
122
123 $cssOutput = ""; // Initialize traditional CSS output string
124 $cssVariablesOutput = ""; // Initialize CSS variables output string
125
126 // Check if form is submitted
127 if ($_SERVER["REQUEST_METHOD"] == "POST") {
128 // Security check using nonce
129 if (
130 !isset($_POST["ft_calculator_nonce_field"]) ||
131 !wp_verify_nonce(
132 $_POST["ft_calculator_nonce_field"],
133 "ft_calculator_action"
134 )
135 ) {
136 echo "<p>Security check failed. Please try again.</p>";
137 return;
138 }
139
140 foreach (["h1", "h2", "h3", "h4", "h5", "h6", "body", "p"] as $tag) {
141 $minWidth = $_POST[$tag . "MinWidth"]; // In pixels
142 $minFontSizePx = $_POST[$tag . "MinFontSize"]; // In pixels
143 $maxWidth = $_POST[$tag . "MaxWidth"]; // In pixels
144 $maxFontSizePx = $_POST[$tag . "MaxFontSize"]; // In pixels
145
146 // Convert pixel values to REM
147 $minFontSize = $minFontSizePx / $rootFontSize; // In rem
148 $maxFontSize = $maxFontSizePx / $rootFontSize; // In rem
149
150 // Convert widths from px to vw (assuming 1rem = rootFontSize px)
151 $minWidthVW = $minWidth / $rootFontSize; // In vw
152 $maxWidthVW = $maxWidth / $rootFontSize; // In vw
153
154 // Calculate the CSS
155 $vwUnit =
156 (($maxFontSize - $minFontSize) / ($maxWidthVW - $minWidthVW)) *
157 100;
158 $constant = $minFontSize - ($vwUnit * $minWidthVW) / 100;
159
160 // Format to a maximum of 5 decimal places
161 $vwUnitFormatted = number_format($vwUnit, 5, ".", "");
162 $constantFormatted = number_format($constant, 5, ".", "");
163
164 // Add to traditional CSS output
165 $cssOutput .=
166 "{$tag} {font-size: clamp(" .
167 $minFontSize .
168 "rem, " .
169 $constantFormatted .
170 "rem + " .
171 $vwUnitFormatted .
172 "vw, " .
173 $maxFontSize .
174 "rem);}\n";
175
176 // Add to CSS variables output
177 $cssVariablesOutput .=
178 " --{$tag}-font-size: clamp(" .
179 $minFontSize .
180 "rem, " .
181 $constantFormatted .
182 "rem + " .
183 $vwUnitFormatted .
184 "vw, " .
185 $maxFontSize .
186 "rem);\n";
187 }
188
189 // Wrap CSS variables in a :root selector
190 $cssVariablesOutput = ":root {\n" . $cssVariablesOutput . "}\n";
191 }
192
193 // Display the form
194 echo '<form class="ft-form" method="post">';
195 wp_nonce_field("ft_calculator_action", "ft_calculator_nonce_field");
196 echo '<div>
197 <label for="rootFontSize">Root HTML Font Size (px):</label>
198 <input type="number" id="rootFontSize" name="rootFontSize" required value="' .
199 htmlspecialchars($rootFontSize) .
200 '">
201 </div>
202 <div class="grid-container">
203 <div><strong>Tag</strong></div>
204 <div><strong>Min Width (px)</strong></div>
205 <div><strong>Min Font Size (px)</strong></div>
206 <div><strong>Max Width (px)</strong></div>
207 <div><strong>Max Font Size (px)</strong></div>';
208
209 // Display input fields for each tag
210 foreach (["h1", "h2", "h3", "h4", "h5", "h6", "body", "p"] as $tag) {
211 $minWidthValue = isset($_POST[$tag . "MinWidth"])
212 ? $_POST[$tag . "MinWidth"]
213 : $defaultValues[$tag]["MinWidth"];
214 $minFontSizeValue = isset($_POST[$tag . "MinFontSize"])
215 ? $_POST[$tag . "MinFontSize"]
216 : $defaultValues[$tag]["MinFontSize"];
217 $maxWidthValue = isset($_POST[$tag . "MaxWidth"])
218 ? $_POST[$tag . "MaxWidth"]
219 : $defaultValues[$tag]["MaxWidth"];
220 $maxFontSizeValue = isset($_POST[$tag . "MaxFontSize"])
221 ? $_POST[$tag . "MaxFontSize"]
222 : $defaultValues[$tag]["MaxFontSize"];
223
224 echo "<div><strong>{$tag}</strong></div>
225 <div><input type='number' id='{$tag}MinWidth' name='{$tag}MinWidth' required value='{$minWidthValue}'></div>
226 <div><input type='number' id='{$tag}MinFontSize' name='{$tag}MinFontSize' required value='{$minFontSizeValue}'></div>
227 <div><input type='number' id='{$tag}MaxWidth' name='{$tag}MaxWidth' required value='{$maxWidthValue}'></div>
228 <div><input type='number' id='{$tag}MaxFontSize' name='{$tag}MaxFontSize' required value='{$maxFontSizeValue}'></div>";
229 }
230
231 echo '</div><input type="submit" value="Generate CSS"></form>';
232
233 // Display the traditional CSS output
234 if (!empty($cssOutput)) {
235 echo "<h2>Generated CSS:</h2>";
236 echo '<textarea id="cssOutput" rows="10" cols="70">' .
237 htmlspecialchars($cssOutput) .
238 "</textarea><br>";
239 echo '<button onclick="copyToClipboard(\'cssOutput\')">Copy CSS</button>';
240 }
241
242 // Display the CSS variables output
243 if (!empty($cssVariablesOutput)) {
244 echo "<h2>Generated CSS Variables:</h2>";
245 echo '<textarea id="cssVariablesOutput" rows="10" cols="70">' .
246 htmlspecialchars($cssVariablesOutput) .
247 "</textarea><br>";
248 echo '<button onclick="copyToClipboard(\'cssVariablesOutput\')">Copy CSS Variables</button>';
249 }
250
251 // JavaScript for copy to clipboard functionality
252 echo '<script>
253 function copyToClipboard(elementId) {
254 var copyText = document.getElementById(elementId);
255 copyText.select();
256 document.execCommand("copy");
257 }
258 </script>';
259
260 echo "</div>";
261}
262
263
264// Define the function for the fluid typography calculator
265function fluid_typography_calculator() {
266 // Call the existing function to display the fluid typography calculator
267 ft_calculator_page();
268}
269
270// Add the shortcode
271add_shortcode('Fluid_calc', 'fluid_typography_calculator');