execCommand heading not working - javascript
As the title explains, for some reason document.execCommand('heading', false, 'h1') (or any other heading size) does not work. However, other commands such as 'bold', 'link', et cetera, do work.
I am looking at caniuse and it seems to be supported across the board while there are "0 known issues."
Below is the code I am using. Notably, I tried embedding a demo and even creating a codepen, but for some reason none the of the commands work in either.
const formatToolClass = document.getElementsByClassName('format-tool')
const preventDefault = (e) => e.preventDefault()
const applyStyle = function(){
document.designMode = 'on'
document.execCommand('heading', false, 'h1') // does not work
document.execCommand('bold', false, null) // will work
document.designMode = 'off'
}
for (let i = 0; i < formatToolClass.length; i++){
formatToolClass[i].addEventListener('mousedown', preventDefault)
formatToolClass[i].addEventListener('click', applyStyle)
}
Any idea what is going on??
P.S. Below is the HTML and CSS in case you want to mess around with it in a browser.
<!DOCTYPE html>
<head>
<title>Is required and cannot be empty.</title>
<meta charset="UTF-8">\
<link rel="stylesheet" href="css/write.css">
</head>
<body>
<div id="controls">
<div class="controls format-tool" id="controls-embolden" data-xcom="bold">Embolden</div>
<div class="controls format-tool" id="controls-italicize" data-xcom="italic">Italicize</div>
<div class="controls format-tool" id="controls-heading" data-xcom="heading">Heading</div> <!---->
<div class="controls format-tool" id="controls-link" data-xcom="createLink">Link</div> <!---->
<div class="controls format-tool" id="controls-list" data-xcom="insertUnorderedList">List</div>
<div class="controls format-tool" id="controls-image" data-xcom="insertImage">Image</div> <!---->
<div class="controls" id="controls-shortcuts">Shortcuts</div>
<div class="controls" id="controls-save">Save</div>
<div class="controls" id="controls-publish">Publish</div>
</div>
<div id="user-input" contenteditable="true">
By portraying me in a sexual way to attendees, this would have opened the door to additional harassment, and added yet another hurdle I’d have to overcome in order to be perceived as a competent professional. The fact that nowhere along the way did ReactiveConf organizers recognize how this gift could actually be harmful, to me, demonstrated a complete lack of empathy for women in tech. That’s not an organization I want to associate myself or my employer, Meteor Development Group (MDG), with.
Not only is the photo itself problematic, but also the fact that ReactiveConf never asked for my consent. I was never informed that ReactiveConf was planning on altering my photo for the event, nor did I see the superhero picture until after day one of the conference had ended. None of the organizers explicitly asked for my permission to display the picture on the big screen. Had I presented my talk on day 1, I would have been completely blindsided as I walked on stage, which is what happened to a colleague of mine who was also unhappy with his picture.
Speaking at a conference is already a monumental investment of mental, emotional, and physical effort, right up until the plane ride home. The will to continue investing any more energy into an event whose organizers had showed so little consideration for their speakers vanished as soon as I received the gift. After consulting with trusted members of my team, I decided to withdraw and leave the situation immediately.
By portraying me in a sexual way to attendees, this would have opened the door to additional harassment, and added yet another hurdle I’d have to overcome in order to be perceived as a competent professional. The fact that nowhere along the way did ReactiveConf organizers recognize how this gift could actually be harmful, to me, demonstrated a complete lack of empathy for women in tech. That’s not an organization I want to associate myself or my employer, Meteor Development Group (MDG), with.
</div>
<script src="js/write.js"></script>
</body>
</html>
body {
width: 100vw;
height: 100vh;
overflow: hidden;
margin: 0;
}
#controls {
width: 100%;
height: 10%;
display: flex;
justify-content: space-around;
box-sizing:border-box;
border:solid red 1px;
}
.controls {
font-size: 1.5vmin;
display: flex;
justify-content: center;
align-items: flex-end;
box-sizing:border-box;
border:solid orange 1px;
}
#user-input {
width: 80%;
height: 90%;
max-width: 1440px;
padding: 1.25%;
overflow-y: visible;
overflow-x: hidden;
font-family: arial;
font-size: 3vmin;
color: #000;
box-sizing:border-box;
border:solid black 1px;
}
You are making a wrong assumption. The caniuse site states that execCommand is supported without issues, which is correct, but that doesn't mean that all the commands are supported. In fact, the caniuse page has a comment in the Notes section:
To determine what commands are supported, see Document.queryCommandSupported()
And if you check "heading", you'll see it is not supported in Chrome:
console.log(document.queryCommandSupported("heading"))
It is not supported on IE either. Firefox states that it supports it, but it may or may not be in the way you expect: instead of applying the heading styles to only the selected text, it applies it to the whole block (works like a "formatBlock" which makes sense as a heading is a block level element and not an inline element as a bold/italics would be).
If that works for you, there's a workaround that is using "formatBlock" as it is supported by Chrome, Firefox and IE:
console.log(document.queryCommandSupported("formatBlock"))
In that case, what you would do is setting the formatBlock to the heading you want (looks like an h1) and it will work:
const formatToolClass = document.getElementsByClassName('format-tool')
const preventDefault = (e) => e.preventDefault()
const applyStyle = function() {
document.designMode = 'on'
document.execCommand('formatBlock', false, 'h1')
document.designMode = 'off'
}
for (let i = 0; i < formatToolClass.length; i++) {
formatToolClass[i].addEventListener('mousedown', preventDefault)
formatToolClass[i].addEventListener('click', applyStyle)
}
body {
width: 100vw;
height: 100vh;
overflow: hidden;
margin: 0;
}
#controls {
width: 100%;
height: 10%;
display: flex;
justify-content: space-around;
box-sizing: border-box;
border: solid red 1px;
}
.controls {
font-size: 1.5vmin;
display: flex;
justify-content: center;
align-items: flex-end;
box-sizing: border-box;
border: solid orange 1px;
}
#user-input {
width: 80%;
height: 90%;
max-width: 1440px;
padding: 1.25%;
overflow-y: visible;
overflow-x: hidden;
font-family: arial;
font-size: 3vmin;
color: #000;
box-sizing: border-box;
border: solid black 1px;
}
<div id="controls">
<div class="controls format-tool" id="controls-embolden" data-xcom="bold">Embolden</div>
<div class="controls format-tool" id="controls-italicize" data-xcom="italic">Italicize</div>
<div class="controls format-tool" id="controls-heading" data-xcom="heading">Heading</div>
<!---->
<div class="controls format-tool" id="controls-link" data-xcom="createLink">Link</div>
<!---->
<div class="controls format-tool" id="controls-list" data-xcom="insertUnorderedList">List</div>
<div class="controls format-tool" id="controls-image" data-xcom="insertImage">Image</div>
<!---->
<div class="controls" id="controls-shortcuts">Shortcuts</div>
<div class="controls" id="controls-save">Save</div>
<div class="controls" id="controls-publish">Publish</div>
</div>
<div id="user-input" contenteditable="true">
By portraying me in a sexual way to attendees, this would have opened the door to additional harassment, and added yet another hurdle I’d have to overcome in order to be perceived as a competent professional. The fact that nowhere along the way did ReactiveConf
organizers recognize how this gift could actually be harmful, to me, demonstrated a complete lack of empathy for women in tech. That’s not an organization I want to associate myself or my employer, Meteor Development Group (MDG), with. Not only is the
photo itself problematic, but also the fact that ReactiveConf never asked for my consent. I was never informed that ReactiveConf was planning on altering my photo for the event, nor did I see the superhero picture until after day one of the conference
had ended. None of the organizers explicitly asked for my permission to display the picture on the big screen. Had I presented my talk on day 1, I would have been completely blindsided as I walked on stage, which is what happened to a colleague of mine
who was also unhappy with his picture. Speaking at a conference is already a monumental investment of mental, emotional, and physical effort, right up until the plane ride home. The will to continue investing any more energy into an event whose organizers
had showed so little consideration for their speakers vanished as soon as I received the gift. After consulting with trusted members of my team, I decided to withdraw and leave the situation immediately. By portraying me in a sexual way to attendees,
this would have opened the door to additional harassment, and added yet another hurdle I’d have to overcome in order to be perceived as a competent professional. The fact that nowhere along the way did ReactiveConf organizers recognize how this gift
could actually be harmful, to me, demonstrated a complete lack of empathy for women in tech. That’s not an organization I want to associate myself or my employer, Meteor Development Group (MDG), with.
</div>
Now, if you want only the text that you selected to be an H1, then you could do a trick: use "insertHTML" to add the tags <h1> and </h1> surrounding the selected text (it will work on Edge, but not on Internet Explorer). Something like this:
const formatToolClass = document.getElementsByClassName('format-tool')
const preventDefault = (e) => e.preventDefault()
const applyStyle = function() {
document.designMode = 'on'
document.execCommand('insertHTML', false, '<h1>' + window.getSelection().toString() + '</h1>')
document.designMode = 'off'
}
for (let i = 0; i < formatToolClass.length; i++) {
formatToolClass[i].addEventListener('mousedown', preventDefault)
formatToolClass[i].addEventListener('click', applyStyle)
}
body {
width: 100vw;
height: 100vh;
overflow: hidden;
margin: 0;
}
#controls {
width: 100%;
height: 10%;
display: flex;
justify-content: space-around;
box-sizing: border-box;
border: solid red 1px;
}
.controls {
font-size: 1.5vmin;
display: flex;
justify-content: center;
align-items: flex-end;
box-sizing: border-box;
border: solid orange 1px;
}
#user-input {
width: 80%;
height: 90%;
max-width: 1440px;
padding: 1.25%;
overflow-y: visible;
overflow-x: hidden;
font-family: arial;
font-size: 3vmin;
color: #000;
box-sizing: border-box;
border: solid black 1px;
}
<div id="controls">
<div class="controls format-tool" id="controls-embolden" data-xcom="bold">Embolden</div>
<div class="controls format-tool" id="controls-italicize" data-xcom="italic">Italicize</div>
<div class="controls format-tool" id="controls-heading" data-xcom="heading">Heading</div>
<!---->
<div class="controls format-tool" id="controls-link" data-xcom="createLink">Link</div>
<!---->
<div class="controls format-tool" id="controls-list" data-xcom="insertUnorderedList">List</div>
<div class="controls format-tool" id="controls-image" data-xcom="insertImage">Image</div>
<!---->
<div class="controls" id="controls-shortcuts">Shortcuts</div>
<div class="controls" id="controls-save">Save</div>
<div class="controls" id="controls-publish">Publish</div>
</div>
<div id="user-input" contenteditable="true">
By portraying me in a sexual way to attendees, this would have opened the door to additional harassment, and added yet another hurdle I’d have to overcome in order to be perceived as a competent professional. The fact that nowhere along the way did ReactiveConf
organizers recognize how this gift could actually be harmful, to me, demonstrated a complete lack of empathy for women in tech. That’s not an organization I want to associate myself or my employer, Meteor Development Group (MDG), with. Not only is the
photo itself problematic, but also the fact that ReactiveConf never asked for my consent. I was never informed that ReactiveConf was planning on altering my photo for the event, nor did I see the superhero picture until after day one of the conference
had ended. None of the organizers explicitly asked for my permission to display the picture on the big screen. Had I presented my talk on day 1, I would have been completely blindsided as I walked on stage, which is what happened to a colleague of mine
who was also unhappy with his picture. Speaking at a conference is already a monumental investment of mental, emotional, and physical effort, right up until the plane ride home. The will to continue investing any more energy into an event whose organizers
had showed so little consideration for their speakers vanished as soon as I received the gift. After consulting with trusted members of my team, I decided to withdraw and leave the situation immediately. By portraying me in a sexual way to attendees,
this would have opened the door to additional harassment, and added yet another hurdle I’d have to overcome in order to be perceived as a competent professional. The fact that nowhere along the way did ReactiveConf organizers recognize how this gift
could actually be harmful, to me, demonstrated a complete lack of empathy for women in tech. That’s not an organization I want to associate myself or my employer, Meteor Development Group (MDG), with.
</div>
Related
How do i build a vertical carousel scroller in pure javascript?
This is what I want to accomplish The code is already here, but i do not know how to make it stop at each section. https://codepen.io/ellie_html/full/dyYjZyB the part of the css that makes the code above work is this .container { height:570px; width: 325px; overflow-y: scroll; scroll-snap-type: mandatory; scroll-snap-points-y: repeat(3rem); scroll-snap-type: y mandatory; position: relative; left: 510px; top: 50px; z-index: 1; border-radius: 15px; border: none; } .tiktok { height: 620px; width:300px; background-color: black; scroll-snap-align: start; } A vertical carousel scroller just like above, except, it must stop on each section instead of allowing the use to quicky scroll over each section. I notice google shorts https://www.youtube.com/shorts/3jqhfmUqgZk behave the same way if you scroll down. Snappy and crisp to the feel. However it also doesnt allow it to stop on each section. If a user scrolls very fast, it will skip over many. How can this be done in javascript? I have looked at many libraries so far but they all suffer from the same problem. I am trying to modify the code above to make it work. Or am i recreating the wheel and there is some tiny code out there that already does this?
I ended up using this library https://mobius1.github.io/Pageable/#page-1 Set it up in freescroll mode and dragmode. Its also free with no cost, and the snap feel of the scrolls is similar. It is also done in pure javascript with zero dependencies. Setting it in drag mode also prevents multiple sections from being skipped because a user wont be able to use the scroll wheel.
Have you tried fullpage.js? You can check its official docs here. fullPage is an Open Source application licensed under a GPLv3 license. This license allows you to use fullPage in Open Source projects but it requires your project to be public, provide attribution and be licensed under GPLv3. Here's a contrived example, also available on CodePen: new fullpage('#fullpage', { sectionsColor: ['yellow', 'orange', '#C0C0C0', '#ADD8E6'], // get your license at https://alvarotrigo.com/fullPage/pricing/ licenseKey: 'YOUR LICENSE KEY HERE ' }); .section { text-align:center; font-size: 3em; } .as-console-wrapper { display: none!important; } <link rel='stylesheet' href='https://unpkg.com/fullpage.js/dist/fullpage.min.css'> <script src="https://cdnjs.cloudflare.com/ajax/libs/fullPage.js/4.0.11/fullpage.min.js"></script> <div id="fullpage"> <div class="section">Section 1</div> <div class="section"> <div class="slide" data-anchor="slide1">Slide 2.1</div> <div class="slide" data-anchor="slide2">Slide 2.2</div> </div> <div class="section">Section 3</div> <div class="section">Section 4</div> </div>
Errors in CSS with text overflow: ellipsis in Vuetify columns [duplicate]
This question already has answers here: How can I get FF 33.x Flexbox behavior in FF 34.x? [duplicate] (3 answers) Closed 7 years ago. Since the latest (?) release of Firefox Nightly (35.0a1) I've been experiencing an issue with text-overflow: ellipsis inside a flexbox container with flex-direction: row, with each column being 50% wide. Demo: .container { width: 300px; background: red; } .row { display: flex; flex-direction: row; flex-wrap: wrap; } .column { flex-basis: 50%; } .column p { background: gold; /* Will not work in Firefox Nightly 35.0a1 */ text-overflow: ellipsis; overflow: hidden; white-space: nowrap; } <div class="container"> <div class="row"> <div class="column"> <p>Captain's Log, Stardate 9529.1: This is the final cruise of the starship Enterprise under my command. This ship and her history will shortly become the care of another crew. To them and their posterity will we commit our future. They will continue the voyages we have begun and journey to all the undiscovered countries boldly going where no man, where no one has gone before.</p> </div> <div class="column"> <p>Captain's Log, Stardate 9529.1: This is the final cruise of the starship Enterprise under my command. This ship and her history will shortly become the care of another crew. To them and their posterity will we commit our future. They will continue the voyages we have begun and journey to all the undiscovered countries boldly going where no man, where no one has gone before.</p> </div> </div> </div> In Nightly the text will leak outside its container, and not append the ... at the end. In Chrome and Firefox Stable it works as intended.
This was eventually tracked down to recent changes in Firefox Nightly. Long story short, setting min-width: 0 on the .column selector will make it work as expected. A more comprehensive answer can be found here. Of note: "Basically: flex items will refuse to shrink below their minimum intrinsic width, unless you explicitly specify "min-width" or "width" or "max-width" on them." The working solution: .container { width: 300px; background: red; } .row { display: flex; flex-direction: row; flex-wrap: wrap; } .column { /* This will make it work in Firefox >= 35.0a1 */ min-width: 0; flex-basis: 50%; } .column p { background: gold; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; } <div class="container"> <div class="row"> <div class="column"> <p>Captain's Log, Stardate 9529.1: This is the final cruise of the starship Enterprise under my command. This ship and her history will shortly become the care of another crew. To them and their posterity will we commit our future. They will continue the voyages we have begun and journey to all the undiscovered countries boldly going where no man, where no one has gone before.</p> </div> <div class="column"> <p>Captain's Log, Stardate 9529.1: This is the final cruise of the starship Enterprise under my command. This ship and her history will shortly become the care of another crew. To them and their posterity will we commit our future. They will continue the voyages we have begun and journey to all the undiscovered countries boldly going where no man, where no one has gone before.</p> </div> </div> </div>
How to create slider with titles instead of arrows
I have created a row of four headings across the page with descriptions for each below. I would like it beginning with the first title highlighted and the first description only. When each title is clicked, the description changes (slides) to match). Basically a slider but instead of arrows – titles. What is the best/easiest way to achieve this? Thanks. .facilities { display: flex; flex-wrap: wrap; justify-content: space-between; margin: 0 0 30px 0; max-height: 40px; } .facilities .heading { flex: 0 0 25%; } ul.facility-descriptions { font-family: 'Montserrat',"Helvetica-Neue",Helvetica,Arial,sans-serif; font-size: 18px; font-weight: 300; line-height: 30px; padding: 0; margin: 0; } ul.facility-descriptions li { list-style: none; } <div class="facilities"> <div class="heading"><p>FACILITIES MANAGEMENT</p></div> <div class="heading"><p>CATERING SERVICES</p></div> <div class="heading"><p>CLEANING SERVICES</p></div> <div class="heading"><p>CAMP RELOCATIONS</p></div> </div> <ul class="facility-descriptions"> <li>We are responsible for the effective management of on-site accommodation on behalf of our clients. Our specialist staff in camp management and catering have a wealth of experience and proven record of accomplishment in this industry. Our services are supported with safe documented systems of work and are environmentally sustainable.</li> <li>Our menus aim to provide a wide choice for clients and residents whilst providing the necessary nutritional balance to support an individual's daily requirements. When compiling our menus, we consult widely and create recipes that take into consideration dietary guidelines to promote healthy living.</li> <li>We address all cleaning requirements on-site including detailed cleaning of specialised areas. We ensure that all camp quarters, rooms, and ablutions are maintained to an optimum hygienic condition. Services include daily cleaning, bed making, washing of guest's apparels, bed linen changed weekly and on departure of guests or when specifically requested, and twice daily cleaning of ablutions.</li> <li>The synergies associated with our transport and logistics activities enable us to bring added value to our clients when it comes to mobilisation, relocation or demobilisation of remote camp facilities. We operate a fleet of prime movers, winch trucks, specialised trailers, forklifts and all terrain mobile cranes complemented by a professional team of multi-skilled, experienced operators. This allows us to relocate camps in geographically diverse fields across a variety of remote locations.</li> </ul>
An easy way would be JavaScript (Get started here: http://www.w3schools.com/js). I've added jQuery, as it make life with JS much easier. If your solution is index-based (first header shows first description), this could be a simple solution: var headerList = $(".heading"); var descList = $(".facility-descriptions li"); var index = 0; headerList.click(function(){ $(descList[index]).hide(); index = headerList.index($(this)); $(descList[index]).show(); }); .facilities { display: flex; flex-wrap: wrap; justify-content: space-between; margin: 0 0 30px 0; max-height: 40px; } .facilities .heading { flex: 0 0 25%; cursor: pointer; } ul.facility-descriptions { font-family: 'Montserrat',"Helvetica-Neue",Helvetica,Arial,sans-serif; font-size: 18px; font-weight: 300; line-height: 30px; padding: 0; margin: 0; } ul.facility-descriptions li { list-style: none; display: none; } ul.facility-descriptions li:first-child { display: inline; } <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <div class="facilities"> <div class="heading"><p>FACILITIES MANAGEMENT</p></div> <div class="heading"><p>CATERING SERVICES</p></div> <div class="heading"><p>CLEANING SERVICES</p></div> <div class="heading"><p>CAMP RELOCATIONS</p></div> </div> <ul class="facility-descriptions"> <li>We are responsible for the effective management of on-site accommodation on behalf of our clients. Our specialist staff in camp management and catering have a wealth of experience and proven record of accomplishment in this industry. Our services are supported with safe documented systems of work and are environmentally sustainable.</li> <li>Our menus aim to provide a wide choice for clients and residents whilst providing the necessary nutritional balance to support an individual's daily requirements. When compiling our menus, we consult widely and create recipes that take into consideration dietary guidelines to promote healthy living.</li> <li>We address all cleaning requirements on-site including detailed cleaning of specialised areas. We ensure that all camp quarters, rooms, and ablutions are maintained to an optimum hygienic condition. Services include daily cleaning, bed making, washing of guest's apparels, bed linen changed weekly and on departure of guests or when specifically requested, and twice daily cleaning of ablutions.</li> <li>The synergies associated with our transport and logistics activities enable us to bring added value to our clients when it comes to mobilisation, relocation or demobilisation of remote camp facilities. We operate a fleet of prime movers, winch trucks, specialised trailers, forklifts and all terrain mobile cranes complemented by a professional team of multi-skilled, experienced operators. This allows us to relocate camps in geographically diverse fields across a variety of remote locations.</li> </ul> Please note that there are millions of solutions on the internet, consider using one of them. I think what you are looking for are tabs: http://www.w3schools.com/howto/howto_js_tabs.asp http://callmenick.com/post/simple-responsive-tabs-javascript-css https://jqueryui.com/tabs/
Dynamic max height as a calculation based on the heights of various flexbox items?
I have a list of flex-items. They're divs with some text and a link or two-- they may end up holding some images inside them eventually. These are small descriptions of portfolio items, which I imagine I'll add to as time goes on. I'd like the total height of my flex container to be calculated as a bit more than half of the totals of all the flex-items. I'd like to manage this with CSS and javascript, but I'm really not sure that's possible. I know that the standard max-height properties aren't going to do what I want, but I'm not sure there isn't a way to get the CSS flex containers and times to behave with some other property or attribute that I don't understand just yet. I looked through a number of other posts on dynamic div height-- but didn't manage to understand what I was looking at. The page in question can be found here: http://westerneditor.com/index.php/sandbox-2/ relevant CSS so far: .flex-container { display: flex; flex-flow: column wrap; align-items: center; justify-content: center; align-content: top; max-height:1100px; } .flex-item { display: inline-block; background: #292920; align-self:baseline; border: 2px solid orange; border-radius: 5px; padding: 5px; width: 190px; min-height: 100px; max-height: 500px; margin-top: 5px; margin-right: 5px; margin-left: 5px; margin-bottom: 10px; line-height: 21px; color: white; font-size: 1em; text-align: left; } Relevant HTML: <div class="flex-container"> <div class="flex-item"> When working for the Writing Center at UVU, I reworked and edited our Chicago/Turabian guide for clarity. <br> Chicago/Turabian Guide </div> <div class="flex-item"> I wrote a guide on writing to your government officials as well. <br> Writing Your Government Official </div> <div class="flex-item">I also wrote a piece on the Housing First program, designed to reduce homelessness in Utah, particularly in Salt Lake County. Utah’s Housing First program successful with large decrease in Utah’s chronic homeless </div> <div class="flex-item">And a piece that I collaborated on with Drew Clark, about the possible danger glyphosates and their use in the GMO farming industry. <br> GMOs not harmful to human health, but further research into farming practices necessary </div> <div class="flex-item"> While at the Deseret News, I was a major player in soliciting opinion pieces, editing them and arranging them for a couple of larger multi-perspective works. One of these on the BRT route in Provo, UT. We must consider alternatives on Provo’s BRT routes <br> Route 4 is the best option to bring BRT to Provo before funding fades </div> <div class="flex-item"> Another multi-perspective work was on Recapture Canyon, in southern Utah, the BLM, and general frustrations over who should control federal lands and how federal offices should treat locally popular destinations. <br> Public interest in public lands <br> The BLM hasn’t kept its own rules <br> Preserving our shared public lands <br> The deficit of trust between America and out government </div>
Jquery get your classes/divs/id's height(), width() and do what you want. $(document).ready(function(){ var total-height = $(".flex-container").height(); var total-width = $(".flex-container").width(); ;}) Edit JavaScript Height of the entire element, including borders. document.getElementById('.flex-container').offsetHeight Height excluding border and scrollbar, but including padding. document.getElementById('.flex-container').clientHeight
How to align text and checkboxes consistently? [duplicate]
This is one of the minor CSS problems that plague me constantly. How do folks around Stack Overflow vertically align checkboxes and their labels consistently cross-browser? Whenever I align them correctly in Safari (usually using vertical-align: baseline on the input), they're completely off in Firefox and IE. Fix it in Firefox, and Safari and IE are inevitably messed up. I waste time on this every time I code a form. Here's the standard code that I work with: <form> <div> <label><input type="checkbox" /> Label text</label> </div> </form> I usually use Eric Meyer's reset, so form elements are relatively clean of overrides. Looking forward to any tips or tricks that you have to offer!
Warning! This answer is too old and doesn't work on modern browsers. I'm not the poster of this answer, but at the time of writing this, this is the most voted answer by far in both positive and negative votes (+1035 -17), and it's still marked as accepted answer (probably because the original poster of the question is the one who wrote this answer). As already noted many times in the comments, this answer does not work on most browsers anymore (and seems to be failing to do that since 2013). After over an hour of tweaking, testing, and trying different styles of markup, I think I may have a decent solution. The requirements for this particular project were: Inputs must be on their own line. Checkbox inputs need to align vertically with the label text similarly (if not identically) across all browsers. If the label text wraps, it needs to be indented (so no wrapping down underneath the checkbox). Before I get into any explanation, I'll just give you the code: label { display: block; padding-left: 15px; text-indent: -15px; } input { width: 13px; height: 13px; padding: 0; margin:0; vertical-align: bottom; position: relative; top: -1px; *overflow: hidden; } <form> <div> <label><input type="checkbox" /> Label text</label> </div> </form> Here is the working example in JSFiddle. This code assumes that you're using a reset like Eric Meyer's that doesn't override form input margins and padding (hence putting margin and padding resets in the input CSS). Obviously in a live environment you'll probably be nesting/overriding stuff to support other input elements, but I wanted to keep things simple. Things to note: The *overflow declaration is an inline IE hack (the star-property hack). Both IE 6 and 7 will notice it, but Safari and Firefox will properly ignore it. I think it might be valid CSS, but you're still better off with conditional comments; just used it for simplicity. As best I can tell, the only vertical-align statement that was consistent across browsers was vertical-align: bottom. Setting this and then relatively positioning upwards behaved almost identically in Safari, Firefox and IE with only a pixel or two of discrepancy. The major problem in working with alignment is that IE sticks a bunch of mysterious space around input elements. It isn't padding or margin, and it's damned persistent. Setting a width and height on the checkbox and then overflow: hidden for some reason cuts off the extra space and allows IE's positioning to act very similarly to Safari and Firefox. Depending on your text sizing, you'll no doubt need to adjust the relative positioning, width, height, and so forth to get things looking right. I haven't tried this specific technique on any projects other than the one I was working on this morning, so definitely pipe up if you find something that works more consistently. Warning! This answer is too old and doesn't work on modern browsers.
Sometimes vertical-align needs two inline (span, label, input, etc...) elements next to each other to work properly. The following checkboxes are properly vertically centered in IE, Safari, FF, and Chrome, even if the text size is very small or large. They all float next to each other on the same line, but the nowrap means that the whole label text always stays next to the checkbox. The downside is the extra meaningless SPAN tags. .checkboxes label { display: inline-block; padding-right: 10px; white-space: nowrap; } .checkboxes input { vertical-align: middle; } .checkboxes label span { vertical-align: middle; } <form> <div class="checkboxes"> <label><input type="checkbox"> <span>Label text x</span></label> <label><input type="checkbox"> <span>Label text y</span></label> <label><input type="checkbox"> <span>Label text z</span></label> </div> </form> Now, if you had a very long label text that needed to wrap without wrapping under the checkbox, you'd use padding and negative text indent on the label elements: .checkboxes label { display: block; padding-right: 10px; padding-left: 22px; text-indent: -22px; } .checkboxes input { vertical-align: middle; } .checkboxes label span { vertical-align: middle; } <form> <div class="checkboxes"> <label><input type="checkbox"> <span>Label text x so long that it will probably wrap so let's see how it goes with the proposed CSS (expected: two lines are aligned nicely)</span></label> <label><input type="checkbox"> <span>Label text y</span></label> <label><input type="checkbox"> <span>Label text z</span></label> </div> </form>
Working off of One Crayon's solution, I have something that works for me and is simpler: .font2 {font-family:Arial; font-size:32px} /* Sample font */ input[type=checkbox], input[type=radio] { vertical-align: middle; position: relative; bottom: 1px; } input[type=radio] { bottom: 2px; } <label><input type="checkbox" /> Label text</label> <p class="font2"> <label><input type="checkbox"/> Label text</label> </p> Renders pixel-for-pixel the same in Safari (whose baseline I trust) and both Firefox and IE7 check out as good. It also works for various label font sizes, big and small. Now, for fixing IE's baseline on selects and inputs... Update: (Third-Party Edit) The proper bottom position depends on font-family and font-size! I found using bottom: .08em; for checkbox & radio elements is a good general value. I tested it in Chrome/Firefox/IE11 in windows with Arial & Calibri fonts using several small/mid/large font-sizes. .font2, .font2 input {font-family:Arial; font-size:32px} /* Sample font */ input[type=checkbox], input[type=radio] { vertical-align: middle; position: relative; bottom: .08em; /* this is a better value for different fonts! */ } <label><input type="checkbox" /> Label text</label> <p class="font2"> <label><input type="checkbox"/> Label text</label> </p>
One easy thing that seems to work well is to apply a adjust the vertical position of the checkbox with vertical-align. It will still be vary across browsers, but the solution is uncomplicated. input { vertical-align: -2px; } Reference
try vertical-align: middle also your code seems like it should be: <form> <div> <input id="blah" type="checkbox"><label for="blah">Label text</label> </div> </form>
Try my solution, I tried it in IE 6, FF2 and Chrome and it renders pixel by pixel in all the three browsers. * { padding: 0px; margin: 0px; } #wb { width: 15px; height: 15px; float: left; } #somelabel { float: left; padding-left: 3px; } <div> <input id="wb" type="checkbox" /> <label for="wb" id="somelabel">Web Browser</label> </div>
The only perfectly working solution for me is: input[type=checkbox], input[type=radio] { vertical-align: -2px; margin: 0; padding: 0; } Tested today in Chrome, Firefox, Opera, IE 7 and 8. Example: Fiddle
I have not completely tested my solution, but it seems to work great. My HTML is simply: <label class="checkbox"><input type="checkbox" value="0000">0000 - 0100</label> I then set all checkboxes to 24px for both height and width. To make the text aligned I make the label's line-height also 24px and assign vertical-align: top; like so: EDIT: After IE testing I added vertical-align: bottom; to the input and changed the label's CSS. You may find you need a conditional IE css case to sort out padding - but the text and box are inline. input[type="checkbox"] { width: 24px; height: 24px; vertical-align: bottom; } label.checkbox { vertical-align: top; line-height: 24px; margin: 2px 0; display: block; height: 24px; } <label class="checkbox"><input type="checkbox" value="0000">0000 - 0100</label> <label class="checkbox"><input type="checkbox" value="0100">0100 - 0200</label> <label class="checkbox"><input type="checkbox" value="0200">0200 - 0300</label> <label class="checkbox"><input type="checkbox" value="0300">0300 - 0400</label> If anyone finds that this doesn't work, please kindly let me know. Here is it in action (in Chrome and IE - apologies as screenshots were taken on retina and using parallels for IE):
I usually use line height in order to adjust the vertical position of my static text: label { line-height: 18px; } input { width: 13px; height: 18px; font-size: 12px; line-height: 12px; } <form> <div> <label><input type="checkbox" /> Label text</label> </div> </form> Hope that helps.
Let's finally take a look at the source of the problem The checkboxes are rendered using images (one may set custom ones via CSS). Here is an (unchecked) checkbox in FireFox, highlighted with DOM inspector: And here's the same unstyled checkbox in Chrome: You can see the margin (orange); padding is not present (would be shown green). So what's this pseudo-margin on the right and on the bottom of the checkbox? These are parts of the image used for the checkbox. That's why using just vertical-align: middle doesn't really suffice and that's the source of the cross-browser problems. So what can we do about this? One obvious option is – replace the images! Fortunately, one can do this via CSS and replace those with external images, base64 (in-CSS) images, in-CSS svg or just pseudo-elements. It's a robust (cross-browser!) approach, and here's an example of such adjustment stolen from this question: .checkbox-custom { opacity: 0; position: absolute; } .checkbox-custom, .checkbox-custom-label { display: inline-block; vertical-align: middle; margin: 5px; cursor: pointer; } .checkbox-custom + .checkbox-custom-label:before { content: ''; display: inline-block; background: #fff; border-radius: 5px; border: 2px solid #ddd; vertical-align: middle; width: 10px; height: 10px; padding: 2px; margin-right: 10px; text-align: center; } .checkbox-custom:checked + .checkbox-custom-label:before { width: 1px; height: 5px; border: solid blue; border-width: 0 3px 3px 0; transform: rotate(45deg); -webkit-transform: rotate(45deg); -ms-transform: rotate(45deg); border-radius: 0px; margin: 0px 15px 5px 5px; } <div> <input id="checkbox-1" class="checkbox-custom" name="checkbox-1" type="checkbox"> <label for="checkbox-1" class="checkbox-custom-label">First Choice</label> </div> <div> <input id="checkbox-2" class="checkbox-custom" name="checkbox-2" type="checkbox"> <label for="checkbox-2" class="checkbox-custom-label">Second Choice</label> </div> You may want to read some more in-depth articles about such styling like some listed here; it's out of scope of this answer. Ok, still what about no-custom-images-or-pseudo-elements solution? TL;DR: looks like this won't work, use custom checkbox instead First, let's notice that if in other browsers those pseudo-margins inside checkbox icon were arbitrary, there were no consistent solution. To build one, we have to explore the anatomy of such images in existing browsers. So what browsers do have the pseudo-margins in checkboxes? I've checked out Chrome 75, Vivaldi 2.5 (Chromium-based), FireFox 54 (don't ask why such outdated), IE 11, Edge 42, Safari ?? (borrowed one for a minute, forgot to check out the version). Only Chrome and Vivaldi has such pseudo-margins (I suspect all Chromium-based browsers as well, like Opera). What's the size of those pseudo-margins? To figure this out one can use a zoomed checkbox: input { zoom: 10; box-shadow: 0 0 1px inset #999; } <input type=checkbox> my result is ~7% of width/height and hence 0.9-1.0px in absolute units. The accuracy may be questioned, though: try different values of zoom for the checkbox. In my tests in both Chrome and Vivaldi the relative size of the pseudo-margin is very different at zoom values 10, 20 and at values 11-19 (??): scale seems to be more consistent: input { transform: scale(10) translate(50%, 50%); box-shadow: 0 0 1px inset #999; } <input type=checkbox> so probably ~14% and 2px are the correct values. Now that we know (?) the size of the pseudo-margin, let's note this is not enough. Are the sizes of the checkbox icons the same for all browsers? Alas! Here's what DOM inspector shows for unstyled checkboxes: FireFox: 13.3px Chromium-based: 12.8px for the whole thing, hence 12.8 (100% - 14%) = 11px for what is visually perceived as checkbox IE 11, Edge: 13px Safari: n/a (these should be compared on the same screen, I believe) Now before we discuss any solutions or tricks, let's ask: what is a correct alignment? What are we trying to achieve? To certain point it's a matter of taste, but basically I can think of the following "nice" alignments' aspects: text and checkbox on the same baseline (I deliberately don't adjust checkbox size here): or have same middle line in terms of lowercase letters: or same middle line in terms of capital letters (it's easier to see the difference for different font size): and also we have to decide whether the size of the checkbox should be equal to the height of a lowercase letter, a capital letter or something else (bigger, smaller or between lowercase and capital). For this discussion let's call an alignment nice if the checkbox is on the same baseline as the text and has the size of a capital letter (a highly arguable choice): Now what tools do we have to: adjust checkbox size recognize Chromium with its pseudo-margined checkbox and set specific styles adjust checkbox/label vertical alignment ? Regarding the checkbox size adjustment: there are width, height, size, zoom, scale (have I missed something?). zoom and scale don't allow to set absolute size, so they may help only with adjusting to text size, not set cross-browser size (unless we can write browser-specific rules). size doesn't work with Chrome (did it work with old IE? anyway, it's not that interesting). width and height work in Chrome and other browsers, so we can set a common size, but again, in Chrome it sets the size of the whole image, not the checkbox itself. Note: it is minimum(width, height) which defines a checkbox's size (if width ≠ height, the area outside checkbox square is added to "pseudo-margin"). An unfortunate thing is, the pseudo-margins in Chrome checkbox are not set to zero for any width and heights, as far as I can see. I'm afraid there's no reliable CSS-only method these days. Let's consider vertical alignment. vertical-align can't give consistent results when set to middle or baseline because of the Chrome's pseudo-margin, the only real option to get the same "coordinate system" for all the browsers is to align label and input to the top: (on the picture: vertical-align: top, bottom and bottom without box-shadow) So what result do we get from this? input[type="checkbox"] { height: 0.95em; width: 0.95em; } label, input { vertical-align: top; } <label><input type="checkbox">label</label> The snippet above works with Chrome (Chromium-based browsers), but other browsers require a smaller size of the checkbox. It seems to be impossible to adjust both the size and vertical alignment in a way that works around Chromium's checkbox image quirk. My final suggestion is: use custom checkboxes instead – and you'll avoid frustration :)
Now that flexbox is supported in all modern browsers, something like this seems like an easier approach to me. <style> label { display: flex; align-items: center; } input[type=radio], input[type=checkbox]{ flex: none; } </style> <form> <div> <label><input type="checkbox" /> Label text</label> </div> </form> Here's the complete prefixed version demo: label { display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-align: center; -webkit-align-items: center; -ms-flex-align: center; align-items: center; } input[type=radio], input[type=checkbox] { -webkit-box-flex: 0; -webkit-flex: none; -ms-flex: none; flex: none; margin-right: 10px; } /* demo only (to show alignment) */ form { max-width: 200px } <form> <label> <input type="radio" checked> I am an aligned radio and label </label> <label> <input type="checkbox" checked> I am an aligned checkbox and label </label> </form>
<form> <div> <label style="display: inline-block"> <input style="vertical-align: middle" type="checkbox" /> <span style="vertical-align: middle">Label text</span> </label> </div> </form> The trick is to use vertical-align only in table cells or inline-block if using label tag.
I think this is the easiest way input { position: relative; top: 1px; } <form> <div> <label><input type="checkbox" /> Label text</label> </div> <form>
I don't like relative positioning because it makes element rendered above everything else on its level (it can get on top of something if you have complex layout). I've discovered that vertical-align: sub makes checkboxes look good enough aligned in Chrome, Firefox and Opera. Can't check Safari since I don't have MacOS and IE10 is slightly off, but I've found it to be good enough solution for me. Another solution might be to try and make specific CSS for every browser and fine-tune it with some vertical-align in %/pixels/EMs: http://css-tricks.com/snippets/css/browser-specific-hacks/
This works well for me: fieldset { text-align:left; border:none } fieldset ol, fieldset ul { padding:0; list-style:none } fieldset li { padding-bottom:1.5em; float:none; clear:left } label { float:left; width:7em; margin-right:1em } fieldset.checkboxes li { clear:both; padding:.75em } fieldset.checkboxes label { margin:0 0 0 1em; width:20em } fieldset.checkboxes input { float:left } <form> <fieldset class="checkboxes"> <ul> <li> <input type="checkbox" name="happy" value="yep" id="happy" /> <label for="happy">Happy?</label> </li> <li> <input type="checkbox" name="hungry" value="yep" id="hungry" /> <label for="hungry">Hungry?</label> </li> </ul> </fieldset> </form>
The chosen answer with 400+ upvotes did not work for me in Chrome 28 OSX, probably because it wasn't tested in OSX or that it did work in whatever was around in 2008 when this question was answered. The times have changed, and new CSS3 solutions are now feasible. My solution uses pseudoelements to create a custom checkbox. So the stipulations (pros or cons, however you look at it) are as follows: Only works in modern browsers (FF3.6+, IE9+, Chrome, Safari) Relies on a custom designed checkbox, that will be rendered exactly the same in every browser/OS. Here I've just chosen some simple colors, but you could always add linear gradients and such to give it more of a bang. Is geared to a certain font/font size, which if changed, you'd simply change the positioning and size of the checkbox to make it appear vertically aligned. If tweaked correctly, the end result should still be near to exactly the same in all browser / operating systems. No vertical-alignment properties, no floats Must use the provided markup in my example, it will not work if structured like the question, however, the layout will essentially look the same. If you want to move things around, you'll have to also move the associated CSS div.checkbox { position: relative; font-family: Arial; font-size: 13px; } label { position: relative; padding-left: 16px; } label::before { content :""; display: inline-block; width: 10px; height: 10px; background-color: white; border: solid 1px #9C9C9C; position: absolute; top: 1px; left: 0px; } label::after { content:""; width: 8px; height: 8px; background-color: #666666; position: absolute; left: 2px; top: 3px; display: none; } input[type=checkbox] { visibility: hidden; position: absolute; } input[type=checkbox]:checked + label::after { display: block; } input[type=checkbox]:active + label::before { background-color: #DDDDDD; } <form> <div class="checkbox"> <input id="check_me" type=checkbox /> <label for="check_me">Label for checkbox</label> </div> </form> This solution hides the checkbox, and adds and styles pseudoelements to the label to create the visible checkbox. Because the label is tied to the hidden checkbox, the input field will still get updated and the value will be submitted with the form. And if you're interested, here's my take on radio buttons: http://jsfiddle.net/DtKrV/2/ Hope someone finds this useful!
If you use ASP.NET Web Forms you don't need to worry about DIVs and other elements or fixed sizes. We can align the <asp:CheckBoxList> text by setting float:left to the CheckboxList input type in CSS. Please check the following example code: .CheckboxList { font-size: 14px; color: #333333; } .CheckboxList input { float: left; clear: both; } .ASPX code: <asp:CheckBoxList runat="server" ID="c1" RepeatColumns="2" CssClass="CheckboxList"> </asp:CheckBoxList>
I've never had a problem with doing it like this: <form> <div> <input type="checkbox" id="cb" /> <label for="cb">Label text</label> </div> </form>
With an input type checkbox wrapped inside the label and floated to the left like so: <label for="id" class="checkbox"> <input type="checkbox" id="id"> <span>The Label</span> </label> this worked for me: label.checkbox { display: block; } .checkbox input { float: left; height: 18px; vertical-align: middle; } .checkbox span { float: left; line-height: 18px; margin: 0 0 0 20px; } Make sure the height of the is identical to the line-height of the (blocklevel) .
input[type=checkbox] { vertical-align: middle; } <input id="testCheckbox" name="testCheckbox" type="checkbox"> <label for="testCheckbox">I should align</label>
I usually leave a checkbox unlabeled and then make its "label" a separate element. It's a pain, but there's so much cross-browser difference between how checkboxes and their labels are displayed (as you've noticed) that this is the only way I can come close to controlling how everything looks. I also end up doing this in winforms development, for the same reason. I think the fundamental problem with the checkbox control is that it is really two different controls: the box and the label. By using a checkbox, you're leaving it up to the implementers of the control to decide how those two elements are displayed next to each other (and they always get it wrong, where wrong = not what you want). I really hope someone has a better answer to your question.
If you're using Twitter Bootstrap, you can just use the checkbox class on the <label>: <label class="checkbox"> <input type="checkbox"> Remember me </label>
CSS: .threeCol .listItem { width:13.9em; padding:.2em; margin:.2em; float:left; border-bottom:solid #f3f3f3 1px; } .threeCol input { float:left; width:auto; margin:.2em .2em .2em 0; border:none; background:none; } .threeCol label { float:left; margin:.1em 0 .1em 0; } HTML: <div class="threeCol"> <div class="listItem"> <input type="checkbox" name="name" id="id" value="checkbox1" /> <label for="name">This is your checkBox</label> </div> </div> The above code will place your list items in threecols and just change widths to suit.
Hardcode the checkbox's height and width, remove its padding, and make its height plus vertical margins equal to the label's line-height. If the label text is inline, float the checkbox. Firefox, Chrome, and IE7+ all render the following example identically: http://www.kornea.com/css-checkbox-align
Use simply vertical-align: sub, as pokrishka already suggested. Fiddle HTML Code: <div class="checkboxes"> <label for="check1">Test</label> <input id="check1" type="checkbox"></input> </div> CSS Code: .checkboxes input { vertical-align: sub; }
The following gives pixel-perfect consistency across browsers, even IE9: The approach is quite sensible, to the point of being obvious: Create an input and a label. Display them as block, so you can float them as you like. Set the height and the line-height to the same value to ensure they center and align vertically. For em measurements, to calculate the height of the elements, the browser must know the height of the font for those elements, and it must not itself be set in em measurements. This results in a globally applicable general rule: input, label {display:block;float:left;height:1em;line-height:1em;} With font size adaptable per form, fieldset or element. #myform input, #myform label {font-size:20px;} Tested in latest Chrome, Safari, and Firefox on Mac, Windows, Iphone, and Android. And IE9. This method is likely applicable to all input types that are not higher than one line of text. Apply a type rule to suit.
So I know this has been answered many times, but I feel I have a way more elegant solution than those that have been provided already. And not only 1 elegant solution, but 2 separate solutions to tickle your fancy. With that said, everything you need to know and see are contained in 2 JS Fiddle's, with comments. Solution #1 relies on the native "Checkbox" of the given browser, though with a twist... Its contained in a div which is easier to position cross-browser, with an overflow: hidden to chop the excess of a 1px stretched checkbox (this is so you cant see the ugly borders of FF) Simple HTML: (follow the link to review the css with comments, code block is to satisfy stackoverflow) http://jsfiddle.net/KQghJ/ <label><div class="checkbox"><input type="checkbox" /></div> Label text</label> Solution #2 uses the "Checkbox Toggle Hack" to toggle the CSS state of a DIV, which has been properly positioned across browser, and setup with a simple sprite for the checkbox unchecked and checked states. All that is needed is to adjust the background-position with said Checkbox Toggle Hack. This, in my opinion, is the more elegant solution as you have more control over your checkboxes & radios, and can guarantee they look the same across browser. Simple HTML: (follow the link to review the CSS with comments, code block is to satisfy StackOverflow) http://jsfiddle.net/Sx5M2/ <label><input type="checkbox" /><div class="checkbox"></div>Label text</label> If anyone disagree's with these methods, please leave me a comment, I would love to hear some feedback on why others have not come across these solutions, or if they have, why I see no answers here regarding them? If anyone sees one of these methods fail, it would be nice to see that too, but these have been tested in the latest browsers and rely on HTML / CSS methods that are quite old, and universal as far as I have seen.
This is not the best way of going about solving the issue vertical-align: middle Adding style="position:relative;top:2px;" to the input box would move it down 2px. So depending on your font size, you can move it along.
position: relative; has some issues in IE with z-index and animations like jQuery's slideUp/slideDown. CSS: input[type=checkbox], input[type=radio] { vertical-align: baseline; position: relative; top: 3px; margin: 0 3px 0 0; padding: 0px; } input.ie7[type=checkbox], input.ie7[type=radio] { vertical-align: middle; position: static; margin-bottom: -2px; height: 13px; width: 13px; } jQuery: $(document).ready(function () { if ($.browser.msie && $.browser.version <= 7) { $('input[type=checkbox]').addClass('ie7'); $('input[type=radio]').addClass('ie7'); } }); The styling probably needs tweaks depending on the font-size used in <label> PS: I use ie7js to make the css work in IE6.
Simplest solution is input { vertical-align: text-top; }