{"id":83429,"date":"2019-02-21T17:31:39","date_gmt":"2019-02-21T17:31:39","guid":{"rendered":"https:\/\/www.red-gate.com\/simple-talk\/?p=83429"},"modified":"2022-05-02T20:45:28","modified_gmt":"2022-05-02T20:45:28","slug":"custom-forms-in-bootstrap-4","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/development\/javascript\/custom-forms-in-bootstrap-4\/","title":{"rendered":"Custom Forms in Bootstrap 4"},"content":{"rendered":"<p>Since the very beginning, Bootstrap managed to revamp and redecorate the visuals of HTML web pages. Bootstrap authors achieved that by extending the standard taxonomy of web elements in the various HTML specs with UX-oriented actionable and rendering elements as they emerged from the industry practices. The extended Bootstrap taxonomy includes elements such as modals, dropdowns, custom tooltips, navbars, tab strips, input and button groups, progress bars, carousels and more. None of these has a direct HTML match, but a smart combination of HTML templates, CSS styles and, in some cases, a pinch of JavaScript does the job.<\/p>\n<p>In addition, Bootstrap resets the visual settings of pages changing the visual properties of a few native HTML elements. As a result, text input fields and buttons get rendered with color, padding and border settings different from browser\u2019s standards. Needless to say, different Bootstrap themes apply different visual settings to the same set of native HTML elements.<\/p>\n<p>Not all HTML constituent (visual) elements were originally affected by Bootstrap. Select lists, checkboxes, radio buttons, file uploads, special input fields (date\/time field, range bars) were entirely left to the browser\u2019s internal implementation. This created a visual gap between the elements touched by Bootstrap graphics and those left to the browser\u2019s rendering. For this reason, a number of (mostly jQuery-based) plugins appeared to provide nicer graphics for select lists, checkboxes and radio buttons.<\/p>\n<p>Finally, Bootstrap 4 brings the long-awaited restyling for core HTML elements. In this article, you\u2019ll find out more.<\/p>\n<h2>Input Text Boxes<\/h2>\n<p>Let\u2019s start with plain input text boxes. As mentioned, since the early days Bootstrap restyled input text boxes to give them a consistent look-and-feel. In version 4, an interesting new feature has been added in the form of a new CSS class.<\/p>\n<pre class=\"lang:c# theme:vs2012\">&lt;input\u00a0readonly\u00a0\r\n       type=\"text\"\u00a0\r\n       class=\"form-control-plaintext\"\u00a0\r\n       value=\"Some\u00a0unmodifiable\u00a0text\" \/&gt;<\/pre>\n<p>Typically, you give input text fields the class <code>form-control<\/code> to enable the Bootstrap restyling. However, if the input field is meant to be read-only, then by adding the new class <code>form-control-plaintext<\/code> you enable a different set of CSS styles that remove the surrounding frame typical of input fields. As a result, the content of the <code>value<\/code> property is rendered as plain text. The effective result is slightly different across browsers. In Microsoft Edge, the control is rendered as plain text. In Google Chrome, instead, the text is also sensitive to clicking, and a frame appears all around as a focus outline.<\/p>\n<h2>Checkboxes<\/h2>\n<p>Bootstrap 4 introduces the <code>form-check-input<\/code> class that, combined with <code>form-check-label<\/code>, improves the layout of plain checkboxes whether they are clickable or disabled. In particular, you use the canonical <code>disabled<\/code> attribute to disable the control, and Bootstrap will automatically apply a lighter color to indicate a different state. Depending on the specific needs of the user interface, multiple checkboxes may be rendered inline or vertically stacked. Both scenarios can be achieved through HTML layout elements (e.g., DIV elements) but using native Bootstrap 4 classes specifically targeted at checkboxes helps to gain consistency. Here\u2019s how to render multiple checkboxes inline.<\/p>\n<pre class=\"lang:c# theme:vs2012\">&lt;div\u00a0class=\"form-check\u00a0form-check-inline\"&gt;\r\n    &lt;input\u00a0class=\"form-check-input\"\u00a0\r\n           type=\"checkbox\"\u00a0\r\n           id=\"c1\"\u00a0\r\n           value=\"c1\"&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;label\u00a0class=\"form-check-label\"\u00a0for=\"c1\"&gt;First&lt;\/label&gt;\r\n&lt;\/div&gt;\r\n&lt;div\u00a0class=\"form-check\u00a0form-check-inline\"&gt;\r\n    &lt;input\u00a0class=\"form-check-input\"\u00a0\r\n           type=\"checkbox\"\u00a0\r\n           id=\"c2\"\u00a0\r\n           value=\"c2\"&gt;\r\n    &lt;label\u00a0class=\"form-check-label\"\u00a0for=\"c2\"&gt;Second&lt;\/label&gt;\r\n&lt;\/div&gt;<\/pre>\n<p>As you can see, it\u2019s all about wrapping checkboxes in a DIV container styled with the <code>form-check<\/code> class. In addition, you add the <code>form-check-inline<\/code> class to have controls laid out horizontally. Note that, by default, multiple checkboxes wrapped in <code>form-check<\/code> elements are stacked vertically. In other words, removing <code>form-check-inline<\/code> classes in the code snippet above will stack control vertically.<\/p>\n<p>In all these cases, though, the actual user interface remains the one natively provided by the browser. A parallel set of classes also exists to modify the look-and-feel of checkboxes to make them look more modern and colorful. Here\u2019s an example:<\/p>\n<pre class=\"lang:c# theme:vs2012\">&lt;div\u00a0class=\"custom-control\u00a0custom-checkbox\"&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0&lt;input\u00a0type=\"checkbox\"\u00a0\r\n             class=\"custom-control-input\"\u00a0\r\n             id=\"cc1\"\u00a0name=\"cc1\"&gt;\r\n\u00a0\u00a0   &lt;label\u00a0class=\"custom-control-label\"\u00a0\r\n            for=\"cc1\"&gt;\r\n            I'm\u00a0a\u00a0custom\u00a0checkbox\r\n     &lt;\/label&gt;\r\n&lt;\/div&gt;<\/pre>\n<p>You use the classes <code>custom-control<\/code> and <code>custom-checkbox<\/code> on the surrounding DIV and <code>custom-control-input<\/code> and <code>custom-control-label<\/code> on the checkbox and the label respectively. The figure below (from Google Chrome) shows the difference between a default and a custom checkbox.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"809\" height=\"150\" class=\"wp-image-83430\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2019\/02\/word-image-60.png\" \/><\/p>\n<p>Bootstrap 4 allows making the checkbox a little bigger or a little smaller than the default by using the classes <code>form-control-sm<\/code> and <code>form-control-lg<\/code> on the surrounding DIV. Note that if you need larger checkboxes, then you\u2019d better develop something yourself outside Bootstrap or get inspired by the tons of readymade snippets available <a href=\"http:\/\/bootsnipp.com\/\">online<\/a>.<\/p>\n<h2>Radio Buttons<\/h2>\n<p>All aspects of default and custom checkboxes apply to radio buttons too. To have a radio button, you only have to change the value of the <code>type<\/code> attribute to radio. The figure below shows the user interface of Bootstrap 4 custom radio buttons.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"173\" height=\"130\" class=\"wp-image-83431\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2019\/02\/word-image-61.png\" \/><\/p>\n<p>Here\u2019s the corresponding markup:<\/p>\n<pre class=\"lang:c# theme:vs2012\">&lt;div\u00a0class=\"custom-control\u00a0custom-radio\"&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0&lt;input\u00a0type=\"radio\"\u00a0\r\n            class=\"custom-control-input\"\u00a0\r\n            id=\"r1\"\u00a0\r\n            name=\"r1\"&gt;\r\n\u00a0\u00a0\u00a0\u00a0 &lt;label\u00a0class=\"custom-control-label\"\u00a0\r\n            for=\"r1\"&gt;Option\u00a01&lt;\/label&gt;\r\n&lt;\/div&gt;\r\n&lt;div\u00a0class=\"custom-control\u00a0custom-radio\"&gt;\r\n\u00a0\u00a0\u00a0\u00a0 \u00a0&lt;input\u00a0type=\"radio\"\u00a0\r\n            class=\"custom-control-input\"\u00a0\r\n            id=\"r2\"\u00a0\r\n            name=\"r2\"&gt;\r\n\u00a0\u00a0\u00a0\u00a0 &lt;label\u00a0class=\"custom-control-label\"\u00a0\r\n            for=\"r2\"&gt;Option\u00a02&lt;\/label&gt;\r\n&lt;\/div&gt;<\/pre>\n<p>You may have noticed that the color of the checked radio button in the figure is different (orange) from the color of the checked checkbox seen earlier (blue). Blue is the default color of the Bootstrap classes, but it can be changed via CSS. Here\u2019s how to make it orange.<\/p>\n<pre class=\"lang:c# theme:vs2012\">.custom-radio\u00a0\r\n.custom-control-input:checked~.custom-control-label::after\u00a0{\r\n    background-color:\u00a0orange;\u00a0\u00a0\u00a0\r\n\u00a0\u00a0\u00a0 background-image:\u00a0url(...);\u00a0\r\n\u00a0\u00a0\u00a0 border-radius:\u00a050%;\r\n}<\/pre>\n<p>The circle that characterizes the radio button is actually an SVG image identified by the provided URL. Here\u2019s the SVG source of the default one.<\/p>\n<pre class=\"lang:c# theme:vs2012\">&lt;svg viewbox='-4 -4 8 8'&gt;\r\n    &lt;circle r='3' fill='#fff'\/&gt;\r\n&lt;\/svg&gt;<\/pre>\n<p>In the case of radio buttons, however, it holds the general recommendation to look elsewhere (e.g., <a href=\"http:\/\/bootsnipp.com\">http:\/\/bootsnipp.com<\/a>) for fancier visual solutions.<\/p>\n<h2>Toggle Switches<\/h2>\n<p>Since the early days of iPhone devices, people loved the toggle switch UI element to choose between two mutually exclusive states\u2014on\/off, yes\/no, true\/false and the like. Conceptually, a toggle switch is not different from a single checkbox or perhaps two paired radio buttons. To make toggle switches attractive is their intuitive user interface. Many plugins and extensions to various frameworks have been created to make it easy to turn a checkbox into a toggle switch.<\/p>\n<p>Since version 4.2, Bootstrap has its own class to render a custom checkbox as an iPhone-style toggle switch. Here\u2019s the necessary markup.<\/p>\n<pre class=\"lang:c# theme:vs2012\">&lt;div\u00a0class=\"custom-control\u00a0custom-switch\"&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0&lt;input\u00a0type=\"checkbox\"\u00a0\r\n            class=\"custom-control-input\"\u00a0\r\n            id=\"accept\"&gt;\r\n\u00a0    &lt;label\u00a0class=\"custom-control-label\"\u00a0\r\n            for=\"accept\"&gt;I Accept&lt;\/label&gt;\r\n&lt;\/div&gt;<\/pre>\n<p>The figure below demonstrates the toggle switch in its checked and unchecked state.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"369\" height=\"58\" class=\"wp-image-83432\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2019\/02\/word-image-62.png\" \/><\/p>\n<p>In addition to making it a custom checkbox, the only class to use is <code>custom-switch<\/code>. Again, note that you need at least Bootstrap 4.2. The latest version at the time of this writing is 4.3.<\/p>\n<h2>Drop-down Lists<\/h2>\n<p>In the newest Bootstrap version, the <code>SELECT<\/code> element got a minor restyling at last. It\u2019s nothing comparable to multi-select, highly customizable drop-down lists you can find around. One of the most commonly used is Bootstrap Select. You can download and play with it <a href=\"https:\/\/developer.snapappointments.com\/bootstrap-select\/\">here<\/a>.<\/p>\n<p>Natively from the core Bootstrap, you get the following user interface only a bit nicer than the default one rendered by browsers.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"436\" height=\"282\" class=\"wp-image-83433\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2019\/02\/word-image-63.png\" \/><\/p>\n<p>The corresponding markup is shown below. As you can see, the only change you\u2019re required to introduce is the <code>custom-select<\/code> class.<\/p>\n<pre class=\"theme:vs2012 lang:c# decode:true\">&lt;select name=\"food\" class=\"custom-select\"&gt;     \r\n    &lt;option selected&gt;No favorite food&lt;\/option&gt;     \r\n    &lt;option value=\"meat\"&gt;Meat&lt;\/option&gt;     \r\n    &lt;option value=\"fish\"&gt;Fish&lt;\/option&gt;     \r\n    &lt;option value=\"vegan\"&gt;Vegan&lt;\/option&gt; \r\n&lt;\/select&gt;<\/pre>\n<p>The drop-down fully supports the multiple selection in the usual HTML way, that is by adding the <code>multiple<\/code> attribute.<\/p>\n<h2>File Uploaders<\/h2>\n<p>The file uploader component has always been part of the HTML specification since the very early days. Lately, though, it is often hidden behind nicer user interfaces that support the drag-and-drop of files and preview of images. Some basic restyling of the classic input box with a push button that unifies the rendering across all browsers is possible.<\/p>\n<pre class=\"lang:c# theme:vs2012\">&lt;div class=\"custom-file\"&gt;\r\n     &lt;input type=\"file\" \r\n            class=\"custom-file-input\" id=\"file1\"&gt;\r\n     &lt;label class=\"custom-file-label\" for=\"file1\"&gt;\r\n          Choose file\r\n     &lt;\/label&gt;\r\n&lt;\/div&gt;<\/pre>\n<p>The classes <code>custom-file<\/code>, <code>custom-file-input<\/code><em>,<\/em> and <code>custom-file-label<\/code> do the job of restyling the file uploader. Bootstrap 4 also allows you to change the label that describes the purpose of the file. The <em>Choose file<\/em> description of the code snippet above can be replaced by simply editing the body of the <code>LABEL<\/code> element. Also, the text of the button can be changed or localized, but that requires recompiling the Bootstrap SASS sources.<\/p>\n<p>This said, the file uploader\u2014even restyled\u2014doesn\u2019t seem to be the preferred choice of developers today. Not because there\u2019s more to improve, but because drag-and-drop and preview (and even data binding) are must-have features.<\/p>\n<h2>Range Inputs<\/h2>\n<p>Introduced by HTML5, the range input controls provide a way for users to enter a number in a closed range. The default user interface of a range control in Google Chrome is below:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"271\" height=\"58\" class=\"wp-image-83434\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2019\/02\/word-image-64.png\" \/><\/p>\n<p>As mentioned, the user interface changes with the browser. Bootstrap 4 provides additional CSS classes to give range controls a uniform interface across browsers. Here\u2019s how to turn it on.<\/p>\n<pre class=\"lang:c# theme:vs2012\">&lt;div&gt; \r\n     &lt;label\u00a0for=\"customRange\"&gt;Your age?&lt;\/label&gt;\r\n\u00a0\u00a0   &lt;input\u00a0type=\"range\"\u00a0\r\n            class=\"custom-range\"\u00a0\r\n            id=\"customRange\"\u00a0\r\n            name=\"range1\" \/&gt;\r\n&lt;\/div&gt;<\/pre>\n<p>The trick is using the class <code>custom-range<\/code> on the <code>INPUT<\/code> element of type <em>range<\/em>. The output is shown below, and it is uniform across browsers.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1206\" height=\"52\" class=\"wp-image-83435\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2019\/02\/word-image-65.png\" \/><\/p>\n<p>In this case, the highlight color (blue by default) can be changed via CSS, as shown earlier for checkboxes.<\/p>\n<h2>More Specific Form Control Classes<\/h2>\n<p>In Bootstrap 4, you also find a number of additional <code>form-control-XXX<\/code> CSS classes that apply to the rendering of a variety of INPUT elements, as listed in the table below.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"598\" height=\"142\" class=\"wp-image-83436\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2019\/02\/word-image-66.png\" \/><\/p>\n<p>In addition, for all <code>INPUT<\/code> elements in a Bootstrap 4 form, you can set heights using classes like <code>form-control-lg<\/code> and <code>form-control-sm<\/code>.<\/p>\n<h2>Form Sizing<\/h2>\n<p>In Bootstrap 4, forms also support auto-layout for columnar content. On the foundation of flexbox grids, developers can set the width of one column using the <code>col-N<\/code> syntax and then have the sibling columns automatically adapt to the remaining width. In other words, the remaining columns (out of a total of 12 available in the grid system) are equally split on the remaining space. The flexbox grid works regardless if predefined grid classes (e.g., <em>col-6<\/em>) or inline widths are used: the remaining columns will resize accordingly. The class <code>col<\/code> indicates that the width of the column is flexibly adapted. Here\u2019s a sample form that lays out horizontally, with the first column taking up half the width and the remaining two a quarter each.<\/p>\n<pre class=\"lang:c# theme:vs2012\">&lt;form&gt;\r\n    &lt;div class=\"form-row\"&gt;\r\n       &lt;div class=\"col-6\"&gt;\r\n            &lt;input type=\"text\" class=\"form-control\"&gt;\r\n       &lt;\/div&gt;\r\n       &lt;div class=\"col\"&gt;\r\n           &lt;input type=\"text\" class=\"form-control\"&gt;\r\n       &lt;\/div&gt;\r\n       &lt;div class=\"col\"&gt;\r\n           &lt;input type=\"text\" class=\"form-control\"&gt;\r\n       &lt;\/div&gt;\r\n    &lt;\/div&gt;\r\n&lt;\/form&gt;<\/pre>\n<h2>Summary<\/h2>\n<p>An interesting trend is going on in the web industry and revolves around the use of custom components in web pages. In this context, a custom component is a reusable set of HTML tags encapsulated in a single container. As a result, the new component can be used within web pages as if it were a native part of the markup language. Whether part of an Angular, React, or a Blazor solution, web components extend the taxonomy of a web page.<\/p>\n<p>Bootstrap attempted to do the same since the first version. Unlike web components, though, Bootstrap didn\u2019t introduce any new top-level syntax element in the HTML markup but provided a number of HTML snippets that altogether worked as a new component.<\/p>\n<p><a id=\"post-83429-_30j0zll\"><\/a> Until version 4, Bootstrap disregarded a number of fundamental HTML elements (e.g., checkboxes, radio buttons, select menus) that only now are styled in a modern and consistent, non-browser-based way. This article just covered custom forms as they\u2019re supported in Bootstrap 4.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Bootstrap 4 functionality makes it easy for developers to make web forms better and more intuitive for the user. In this article, Dino Esposito covers how to change the look and feel of core form controls like checkboxes and radio buttons that previous versions of Bootstrap left untouched.&hellip;<\/p>\n","protected":false},"author":221911,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[146044],"tags":[],"coauthors":[6780],"class_list":["post-83429","post","type-post","status-publish","format-standard","hentry","category-javascript"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/83429","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/221911"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=83429"}],"version-history":[{"count":3,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/83429\/revisions"}],"predecessor-version":[{"id":83438,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/83429\/revisions\/83438"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=83429"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=83429"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=83429"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=83429"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}