Strange input widths in Firefox vs. Chrome - html

I've got some number inputs in a flex layout which are not sizing as expected in Firefox, and I don't understand why.
The result in Chrome:
The result in Firefox:
As you can see, the XP row doesn't overflow its parent in Chrome (no horizontal scrolling), but it has significant overflow in Firefox (with horizontal scrolling), on top of the number inputs overlapping neighboring label texts.
The relevant HTML & CSS from the page is:
/**
* The ".charsheet" prefix on each rule is automatically added
*/
.charsheet .sheet-flexbox-h input[type=number] {
flex: 1 1 40%;
margin-left: 5px;
}
.charsheet .sheet-flexbox-inline > label > span {
white-space: nowrap;
font-size: 89%;
}
.charsheet .sheet-flexbox-h > label {
width: 100%;
display: flex;
flex-direction: row;
}
.charsheet .sheet-flexbox-inline {
display: inline-flex;
width: 100%;
}
.charsheet .sheet-3colrow .sheet-2col:last-child {
width: calc(66% - 5px);
}
.charsheet .sheet-body {
display: block;
overflow-x: visible;
overflow-y: scroll;
position: relative;
flex: 1 1 auto;
}
.charsheet .sheet-content {
height: 100%;
display: flex;
flex-direction: column;
}
.charsheet {
position: absolute;
left: 0;
height: calc(100% - 70px);
width: calc(100% - 12px);
}
/**
* CSS rules below are on the page, but not editable by me
*/
.ui-dialog .charsheet input[type=number] {
width: 3.5em;
}
.ui-dialog .charsheet input {
box-sizing: border-box;
}
<!-- I can only modify the descendants of .charsheet -->
<div class="charsheet tab-pane lang-en" style="display: block;">
<div class="sheet-content">
<div class="sheet-body">
<!-- ... -->
<div class="sheet-3colrow">
<div class="sheet-col"><!-- ... --></div>
<div class="sheet-2col">
<!-- ... -->
<div class="sheet-flexbox-h sheet-flexbox-inline">
<label>
<span data-i18n="current-experience-points">Current XP:</span>
<input type="number" name="attr_xp">
</label>
<label>
<span data-i18n="total-experience-points">Total XP:</span>
<input type="number" name="attr_xp_max">
</label>
<!-- etc... -->
</div><!-- /sheet-flexbox-h -->
<!-- ... -->
</div><!-- /sheet-2col -->
</div><!-- /sheet-3colrow -->
<!-- ... -->
</div><!-- /sheet-body -->
<div class="sheet-footer"><!-- ... --></div>
</div><!-- /sheet-content -->
</div><!-- /charsheet -->
My full CSS and HTML can be found at Roll20/roll20-character-sheets on GitHub. The full CSS that I can't edit can be found live (minified) at Roll20.net
Update: I've created a fiddle to demonstrate the problem: https://jsfiddle.net/Lithl/az1njzn8/
Fiddle in Chrome, fiddle in Firefox

Short answer
Add a simple min-width:0 rule to the input selector
Explanation
After doing a bit of research, I think the conclusion that I can make here is that flex has been known to have various issues and different behaviours across browsers, specially Firefox. I found a couple of useful threads that can lead to various fixes/hacks to have consistent results. A thread that helped me is : https://teamtreehouse.com/community/firefox-flexbox-not-working (scroll down to the comments)
Coming back to your question, I was able to fix it using two separate ways and I was able to produce consistent results in Chrome and Firefox. Both of them require a simple CSS change.
First approach
Change your CSS to the following:
.charsheet .sheet-flexbox-h input[type=text],
.charsheet .sheet-flexbox-h input[type=number],
.charsheet .sheet-flexbox-h select {
-webkit-flex: 1 1 auto;
flex: 1 1 auto;
margin-left: 5px;
}
I noticed that you had 40% as the flex-basis value but could not really figure out why you had this value, perhaps it may have other impacts elsewhere changing it to auto. But this does fix the issue.
Second approach
Add a simple min-width:0 rule to the input selector in your CSS. So your CSS would look like:
.charsheet input[type=text],
.charsheet input[type=number] {
display: inline-block;
min-width:0;
width: 165px;
font-size: 12px;
border: none;
border-bottom: 1px solid black;
border-radius: 0;
background-color: transparent;
}
I found this helpful tip from the link I posted above. Again, I do not have a very concrete explanation as to why this works, but it seems to get the job done.
I would recommend you go with the second approach, as it may have minimal impact since you are setting the width.
Working fiddle here with second approach: https://jsfiddle.net/az1njzn8/4/

I've had the same issue with number inputs behaving differently in Chrome vs. Firefox, and Gurtej's solution unfortunately didn't work for me.
What works for me though is to set a default width that would override the useragent's default width – even though the width is eventually being modified by more complex rules and circumstances with percentages, min-width, max-width and flexbox.
input[type="number"] {
width: 100px;
}
Compare https://jsfiddle.net/pyu0h1r2/1/ vs. https://jsfiddle.net/pyu0h1r2/2/.

Related

Weekday boxes have little lines or spaces between them if you look carefully. These lines or gaps are present in chrome but not in firefox

I am using vite react typescript.
My App component
function App() {
return (
<div>
<DatePicker />
</div>
);
}
My DatePicker component
function DatePicker() {
return (
<div className="datepicker-wrapper">
<input />
<input />
<Calendar />
</div>
);
}
My Calendar Component
function Calendar() {
return (
<div className="datepicker-popper">
<div className="datepicker-weekday">Sunday</div>
<div className="datepicker-weekday">Monday</div>
<div className="datepicker-weekday">Tuesday</div>
<div className="datepicker-weekday">Wednesday</div>
<div className="datepicker-weekday">Thursday</div>
<div className="datepicker-weekday">Friday</div>
<div className="datepicker-weekday">Saturday</div>
</div>
);
}
and finally my css file
body {
margin: 0;
}
.datepicker-wrapper {
position: relative;
font-family: monospace;
display: flex;
gap: 2rem;
}
.datepicker-popper {
position: absolute;
bottom: -0.8rem;
left: 50%;
translate: -50% 100%;
box-sizing: border-box;
padding: 0.3rem;
width: 100%;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
border-radius: 0.6rem;
}
.datepicker-weekday {
display: block;
background-color: palevioletred;
}
check this image
The boxes containing weekdays have weird space or line b/w them in chrome but not in firefox.
I tried making the container flexbox, grid. I also tried changing the div to span but none of them worked.
Here is the codesandbox link : https://codesandbox.io/p/sandbox/wonderful-stitch-deoc00?file=%2Fsrc%2Findex.css&selection=%5B%7B%22endColumn%22%3A1%2C%22endLineNumber%22%3A31%2C%22startColumn%22%3A1%2C%22startLineNumber%22%3A1%7D%5D
Try running this sandbox in chrome and firefox. You will see the difference.
I think you need just use 'normalize.css' file to avoid different results in different browsers. Normalizing file you can take from each site you have googled
EDIT: The problem from my perspective is the translate property.
There is a similar question with a probable explanation of why this happens.
If you add flex-wrap: wrap to .datepicker-wrapper, it will allow the .datepicker-popper to fall below the inputs and you can get rid of all the absolute positioning and translating that cause the white line to appear.
It will also make your code more readable.
here is the code with the above mentioned fixes applied: https://codepen.io/Aga-K-O/pen/RwBqZWq?editors=1100

Decrease padding size as parent element getting smaller

I have a grid that draws squares in cells. It has number of rows and number of columns, then it draw the grid cells and check if in each cell there should be a square or not (according to an array) and draws a square if needed.
The HTML end result looks something like this: (lets say I have 1 row and 3 columns and only 2 cells should have squars)
.row {
display: flex;
flex-wrap: wrap;
flex: 10000 1 0%;
}
.column {
display: flex;
flex-wrap: wrap;
max-width: 100px;
min-width: 10px;
padding: 4px;
border: 1px solid grey;
}
.square {
background-color: red;
width: 100%;
aspect-ratio: 1/1;
border-radius: 5px;
}
<div class="row">
<div class="column">
<div class="square"></div>
</div>
<div class="column">
<div class="square"></div>
</div>
<div class="column"></div>
</div>
The rows take the full width of the screen and the size of the columns should be identical between all of the columns and changing by the number of columns on the screen (For example if I have 5 columns they should all be with a width of 100px, but if I have 1000 columns they should all be with a width of 10px).
My problem is that after a certain break point in the column size the padding and border radius seems weird and I want to change their values when I hit that break point.
I can't use #container queries as there are still not fully supported.
If it help I'm using vue 2. but I think a CSS solution will be better in this case.
Trying to address the issue described:
My problem is that after a certain break point in the column size the
padding and border radius seems weird and I want to change their
values when I hit that break point. I can't use #container queries as
there are still not fully supported.
I crafted a little demo that helped me better explore the conditions bringing to such a scenario.
Obtaining border: collapse equivalent on flexbox items
The .row element remains a flexbox container but its flex items instead of having their border set, they are styled with their outline set.
The outline doesn't occupy space and it's expected to "collapse" when colliding with the outline produced by another element.
So to make it sure the layout wasn't affected by styling oddities, in the attempt to show off the borders of the flex items, this demo just relies on 2 key aspects to render those borders:
Setting the gap between the flex items
Setting the outline size expected to cover the gap left between
elements
.row {
gap: var(--col-gap);
}
.column {
outline: var(--col-gap) solid gray;
}
Using ::after for adding content to an element
Plus the red dot is applied as an ::after pseudo element with position:absolute, again to make sure that nothing affected the grid layout:
.column.square::after {
position: absolute;
content: '';
background-color: red;
width: 50%;
aspect-ratio: 1/1;
border-radius: 100%;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
The dashboard - exploring the options
Starting from there I added a "dashboard" with position: fixed that remains on top of the page and lets you control:
column width (px): here you set the width changing the cols per row according to the available container space
columns per row: here you set the cols per row changing their width according to the available container space
width
gap between cells (px): the gap between cells on the grid
toggle red dots visibility: will show/hide the red dots proving again that display: none; doesn't change the grid layout that it's depending exclusively by the .column element size set through the custom variable --col-width
toggle counter visibility: will show/hide the counter on top of each flex item
Conclusions so far:
Despite the efforts to minimize any interfence and taking all the steps needed to correctly setup a grid layout depending only on the fixed size of its cells, there are still some rendering issue with sometimes the occurrence of regular mismatching patterns on the border size for some lines. I should say that I only experience the problem on my laptop display and not on my desktop monitor so that's another factor.
I tried with different parameters on my demo and playing with the numbers, considering also the gap. A good and safe layout can be found minimizing potential problems (also raising the border size for example).
I couldn't get further than this using the flex layout.
const container = document.getElementById('container');
//draws the board
emptyElementAndFillWithColumns(container, 100);
//sets some columns randomly as .square
addRandomSquares(container);
//initializes the dashboard with the value coming from the css custom props
let columnsGap = parseInt(getCssCustomProp('col-gap'));
let columnsWidth = parseInt(getCssCustomProp('col-width'));
document.getElementById('gap').value = columnsGap;
document.getElementById('width').value = columnsWidth;
document.getElementById('width').dispatchEvent(new Event('change'));
document.getElementById('cols').value = Math.trunc(container.offsetWidth / (columnsWidth+columnsGap));
//input#width change event handler
document.getElementById('width')
.addEventListener('change', event => {
const width = parseInt(event.target.value);
const newCols = Math.trunc(container.offsetWidth / (width+columnsGap));
setCssCustomProp(container, 'col-width', `${width}px`);
document.getElementById('cols').value = newCols;
});
//input#cols change event handler
document.getElementById('cols')
.addEventListener('change', event => {
const cols = parseInt(event.target.value);
const newWidth = Math.trunc(container.offsetWidth / cols) - columnsGap;
setCssCustomProp(container, 'col-width', `${newWidth}px`);
document.getElementById('width').value = newWidth;
});
//input#gap change event handler
document.getElementById('gap')
.addEventListener('change', event => {
const gap = parseInt(event.target.value);
setCssCustomProp(container, 'col-gap', `${gap}px`);
columnsGap = gap;
});
//input#toggle-dots change event handler
document.getElementById('toggle-dots')
.addEventListener('change', event => {
container.classList.toggle('hide-dots');
});
//input#toggle-counters change event handler
document.getElementById('toggle-counters')
.addEventListener('change', event => {
container.classList.toggle('hide-counters');
});
//sets the --propName custom property at the style of target
function setCssCustomProp(target, propName, value){
target.style.setProperty(`--${propName}`, `${value}`);
}
//gets the --propName custom property value from the rule set on :root
function getCssCustomProp(propName){
const propValue =
getComputedStyle(document.documentElement).getPropertyValue(`--${propName}`);
return propValue;
}
//resets the container and appends a count number of columns
function emptyElementAndFillWithColumns(target, count){
for (i = 0; i <= count; i++) {
const column = document.createElement('div');
column.classList.add('column');
target.append(column);
}
}
//adds the square class to random .column elements in target
function addRandomSquares(target){
target.querySelectorAll('.column').forEach(column => {
if (Math.random() >= 0.5)
column.classList.add('square');
})
}
:root {
--col-width: 100px;
--col-gap: 1px;
}
*,
*::after,
*::before {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: sans-serif;
}
.row {
display: flex;
flex-wrap: wrap;
gap: var(--col-gap);
counter-reset: itemnr;
}
.column {
position: relative;
display: flex;
flex-wrap: wrap;
width: var(--col-width);
height: var(--col-width);
padding: 4px;
outline: var(--col-gap) solid gray;
}
.column.square::after {
position: absolute;
content: '';
background-color: red;
width: 50%;
aspect-ratio: 1/1;
border-radius: 100%;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.dashboard {
position: fixed;
right: 1rem;
top: 2rem;
border: solid darkgray;
padding: 1em;
z-index: 100;
background: gray;
color: white;
font-weight: 600;
font-size: 1.2rem;
opacity: .9;
}
.dashboard > *{
display: grid;
grid-template-columns: 1fr auto;
width: 100%;
gap: 1em;
}
.dashboard label{
}
.dashboard input[type="number"] {
width: 5em;
cursor: pointer;
}
.dashboard input[type="checkbox"] {
width: 1rem;
line-height: 1rem;
cursor: pointer;
}
#container.hide-dots .square::after{
display: none;
}
#container.hide-counters .column::before{
display: none;
}
small{
grid-column: 1 / -1;
font-size:.8rem;
text-align: center;
width: 100%;
margin-bottom: 1rem;
}
.column::before{
position: absolute;
counter-increment: itemnr;
content: counter(itemnr);
font-size: .8rem;
z-index: 10;
font-weight: 600;
}
<div id="container" class="row">
<div class="column square">
</div>
<div class="column"></div>
</div>
<div class="dashboard">
<div>
<label for="width">column width (px):</label>
<input
id="width" type="number" max="100" min="10">
</div>
<div>
<label for="cols">columns per row:</label>
<input
id="cols" type="number" max="50" min="1">
</div>
<div>
<label for="gap">gap between cells (px):</label>
<input
id="gap" type="number" max="10" min="0">
</div>
<div style="margin-top: 1rem;">
<label for="toggle-dots">toggle red dots visibility:</label>
<input id="toggle-dots" type="checkbox" checked>
</div>
<div>
<label for="toggle-counters">toggle counter visibility:</label>
<input id="toggle-counters" type="checkbox" checked>
</div>
</div>
If you want to increase or decrease size of padding you can give padding size in percent (%) that depends on parent element.

Allow Bootstrap inline code block to break?

I'm working on Blaze, an app that uses the SE API to grab recent content. It works great for finding NAAs, but there's one problem. When someone has put a whole bunch of code or even an entire sentence in an inline code block, this happens:
When it should look like this (non-SO site):
Essentially, the inline code blocks aren't breaking, and thus are pushing the td out to the right. This is the HTML that is generated:
<tr>
<td style="vertical-align:top" class="col-md-1">
<div class="score">
<h2 style="color:rgba(0,0,0,0.6); pull:right">0</h2>
</div>
</td>
<td class="">
<div class="post col-md-9">
<h3>How can I insert PHP into a webpage using Javascript</h3>
<hr>
<span class="post-body" style="color:rgba(70,70,70,1)">
<p><code>Is it possible to insert PHP code into a webpage using javascript after the page has loaded?</code> The simple answer is no. The page has already been rendered, the only way to change it is using javascript running within the user's browser.</p>
...
</span>
<p style="color:grey; float:right">posted by MjrKusanagi <span>a minute ago</span></p>
</div>
</td>
</tr>
This is all the non-Bootstrap CSS I'm using:
<style>
img
{
max-width:100%;
}
html, body
{
height: 100%;
}
#wrap
{
min-height: 100%;
height: auto;
margin: 0 auto -50px;
padding: 0 0 50px;
}
#footer
{
height: 50px;
background-color: clear;
border-top:1px dashed rgba(0,0,0,0.2);
}
.navbar .navbar-nav
{
display: inline-block;
float: none;
}
.navbar .navbar-collapse
{
text-align: center;
}
.flag-button:hover
{
background-color:red;
color: white
}
</style>
Does anyone have any idea how to either (a) Make the td stronger than the inline code blocks, or (b) allow the code blocks to wrap?
Bootstrap sets code whitespace to no-wrap by default. You can override this by simply overriding it with a value that allows for wrapping.
http://jsfiddle.net/nNry2/
CSS
code {
white-space: normal;
}
I used a variation of #thgaskell's answer, taken from here (changing pre to code).
/* Browser specific (not valid) styles to make preformatted text wrap */
code {
white-space: pre-wrap; /* css-3 */
white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
white-space: -pre-wrap; /* Opera 4-6 */
white-space: -o-pre-wrap; /* Opera 7 */
word-wrap: break-word; /* Internet Explorer 5.5+ */
}

All CSS Method for Show/Hide Divs

I am setting up a FAQ page. On the page I have a div, of class=”faq_container”, with 6 child divs arranged in a 3×3 grid that contain the faq questions. So basically I have 6 clickable boxes.
Each question, when clicked, will reveal its answer hiding the all the questions but maintained within the faq_container div. There would be a close link below the answer to hide the answer and take you back to the questions.
I know this is probably pretty simple. I’m hoping someone can help me out.
Thanks!
While you've accepted a JavaScript solution, there are (at least) two ways that this can be achieved with CSS alone, the first using CSS :target pseudo-classes, and the second using input, and label, elements.
The first, assuming HTML similar to the following:
<div id="faq_container">
<ol>
<li id="faq1">
<h2>Question 1</h2>
<div>
<p>Text, relating to question one.</p> <a class="close" href="#hide">close</a>
<!-- the above link doesn't link to anything, just changes the hash whcih stops the ':target' pseudo-class matching the the current 'div' element -->
</div>
</li>
<!-- subsequent elements follow the above structure, stripped for brevity -->
</ol>
</div>
With the following CSS (albeit there's more CSS in the demo, since I've stripped out some of the purely aesthetic stuff here, for brevity, as above):
li {
/* some stripped out aesthetics */
position: relative; /* used to position the '.close' links */
}
li div {
height: 0; /* to allow for animation of the height 'none' to 'block' can't animate */
overflow: hidden;
/* all vendor prefixes removed for brevity, here and later */
transition: all 0.5s linear; /* animates to the default properties, from other 'states' */
}
/* li:target matches when the 'id' of the 'li' is equal to the hash/fragment-identifier in the URL */
li:target div {
height: 4em; /* to allow for animation (this is the awkward part of using pure CSS) */
transition: all 0.5s linear; /* transitions to the 'selected' state (when the user clicks a link in the 'h2' element) */
}
li a:link, li a:visited {
/* aesthetics removed */
}
/* styling the 'interactive' states (:hover, :active, :focus), and the 'selected' state using 'li:target h2 a' */
li a:hover, li a:active, li a:focus, li:target h2 a {
font-weight: bold;
text-decoration: underline;
}
a.close {
/* styling the '.close' link, so it's invisible in the 'non-selected' state */
position: absolute;
opacity: 0;
width: 0;
overflow: hidden;
transition: all 0.65s linear;
}
/* styling the '.close' link, so it's only visible when the question is 'selected' */
li:target a.close {
opacity: 1;
width: 4em;
transition: all 0.65s linear;
}
JS Fiddle demo.
The second approach uses label and input elements (type="radio" if only one question can be visible at a time, type="checkbox" if multiple elements can be visible), based on the following HTML:
<input id="close" name="question" type="radio" />
<div id="faq_container">
<ol>
<li>
<input id="faq1" type="radio" name="question" />
<h2><label for="faq1">Question 1</label></h2>
<div>
<div>
<p>Text, relating to question one.</p>
<label for="close">Close</label>
<!-- the above 'label' closes the question, by referring to an
'input' of the same name (different 'id'), taking advantage
of the fact that only one radio-'input' of a given name can
be checked (this 'input' is just before the ancestor 'ol') -->
</div>
</div>
</li>
<!-- subsequent elements follow the above structure, stripped for brevity -->
</ol>
</div>
And the following CSS (as before, aesthetics removed for brevity):
/* you could, instead, use a class-name to identify the relevant radio-inputs */
input[type=radio] {
/* using 'display: none' (apparently) in some browsers prevents
interactivity, so we fake it, by hiding: */
position: absolute;
opacity: 0;
left: -1000px;
}
/* styling the 'div' that's the adjacent-sibling of an 'h2' which is an
adjacent-sibling of an 'input' all of which are descendants of a 'div' */
div input + h2 + div {
height: 0; /* to allow for animating with transitions */
overflow: hidden;
/* vendor prefixes, again, stripped out */
transition: all 0.5s linear;
}
/* using 'input:checked + h2 + div' causes problems in Chrome, check the references;
so we're styling (respectively) a 'div' which is an adjacent sibling to an 'h2'
which is an adjacent-sibling of a checked 'input', and/or
a 'div' which is a general-sibling of a checked 'input' (in both cases these are
all descendants of another 'div' element) */
div input:checked + h2 + div,
div input:checked ~ div {
height: 4em; /* to allow for animating with transitions */
overflow-y: auto; /* a personal preference, but allows for
scrolling if the height is insufficient
though it can be a little ugly, with a flicker */
transition: all 0.5s linear;
}
JS Fiddle demo.
The same approach can be used with checkboxes, which allows the label to toggle the display of the relevant question, and makes the close links/labels pointless, HTML:
<div id="faq_container">
<ol>
<li>
<input id="faq1" type="checkbox" name="question" />
<h2><label for="faq1">Question 1</label></h2>
<div>
<div>
<p>Text, relating to question one.</p>
</div>
</div>
</li>
<!-- subsequent elements follow the above structure, stripped for brevity -->
</ol>
</div>
And CSS (precisely as the preceding example, but changed input[type=radio] to input[type=checkbox]):
/* duplicated, and aesthetic, CSS removed for brevity */
input[type=checkbox] {
position: absolute;
opacity: 0;
left: -1000px;
}
JS Fiddle demo.
References:
:target pseudo-selector.
Adjacent-sibling (+) combinator.
General-sibling (~) combinator.
Problems using chained adjacent-sibling combinators, particularly in Chrome: "Why does the general-sibling combinator allow toggling pseudo-element's content, but not the adjacent-sibling?"
If a jQuery solution is allowed, here is a quick mock-up.
$(".wrapper").click(function(){
$(this).children(".answer").toggle();
$(".wrapper").not(this).toggle();
$(".faq_container").toggleClass("active");
});
The simplest means of achieving what you're asking for comes down to changing the "class" attribute value of these DIV elements when their respective OnClick events are fired. For that, you'll need to use a scripting engine of some kind, and that is likely going to be JavaScript unless you want a post back, in which case you can just handle it in the code behind of the page. JQuery, as others have mentioned, is a good choice, but comes with some overhead.
The way this site works is that you post what you've tried so far, and what results you're getting. I get the impression that you haven't tried anything, so I would suggest that you do some searching on this site or your web search engine of choice for a string like "javascript change css class onclick" and see where that leads you.
Without more specifics on your exact use case and environment, you are unlikely to get a "here, copy and paste this code into your page" type of answer.
[EDIT] Never mind. I always underestimate the compulsion of developers to begin writing code before knowing any constraints. Enjoy your copypasta.
You should use this kind of structure :
$('.question').on('click', function(ev) {
ev.preventDefault();
$(this).find('.answer').show();
});
$('.close').on('click', function(ev) {
ev.preventDefault();
ev.stopPropagation();
var dismiss = $(this).data('dismiss');
$(this).closest('.'+dismiss).hide();
});
.faq {
position: relative;
width: 600px;
}
.question {
height: 178px; width: 178px;
margin: 5px;
padding: 5px;
border: 1px solid black;
background: #efefef;
float: left;
cursor: pointer;
}
.answer {
position: absolute;
top: 0; left: 0;
height: 578px; width: 578px;
margin: 5px;
padding: 5px;
border: 1px solid black;
background: #bebebe;
cursor: default;
display: none;
}
a.close {
position: absolute;
top: 5px; right: 5px;
display: block;
height: 20px; width: 20px;
color: black;
border: 1px solid black;
line-height: 20px;
text-align: center;
text-decoration: none;
}
a.close:hover {
background: #9f9f9f;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<section class="faq">
<article class="question">Question 1 ?
<div class="answer">
Answer 1 !
×
</div>
</article>
<article class="question">Question 2 ?
<div class="answer">
Answer 2 !
×
</div>
</article>
<article class="question">Question 3 ?
<div class="answer">
Answer 3 !
×
</div>
</article>
<article class="question">Question 4 ?
<div class="answer">
Answer 4 !
×
</div>
</article>
<article class="question">Question 5 ?
<div class="answer">
Answer 5 !
×
</div>
</article>
<article class="question">Question 6 ?
<div class="answer">
Answer 6 !
×
</div>
</article>
<article class="question">Question 7 ?
<div class="answer">
Answer 7 !
×
</div>
</article>
<article class="question">Question 8 ?
<div class="answer">
Answer 8 !
×
</div>
</article>
<article class="question">Question 9 ?
<div class="answer">
Answer 9 !
×
</div>
</article>
</section>
For the CSS, you'll need to mix float: left for your 3*3 pattern, and position: absolute for each answer.

Input type=text to fill parent container

I'm trying to let an <input type="text"> (henceforth referred to as “textbox”) fill a parent container by settings its width to 100%. This works until I give the textbox a padding. This is then added to the content width and the input field overflows. Notice that in Firefox this only happens when rendering the content as standards compliant. In quirks mode, another box model seems to apply.
Here's a minimal code to reproduce the behaviour in all modern browsers.
#x {
background: salmon;
padding: 1em;
}
#y, input {
background: red;
padding: 0 20px;
width: 100%;
}
<div id="x">
<div id="y">x</div>
<input type="text"/>
</div>
My question: How do I get the textbox to fit the container?
Notice: for the <div id="y">, this is straightforward: simply set width: auto. However, if I try to do this for the textbox, the effect is different and the textbox takes its default row count as width (even if I set display: block for the textbox).
EDIT: David's solution would of course work. However, I do not want to modify the HTML – I do especially not want to add dummy elements with no semantic functionality. This is a typical case of divitis that I want to avoid at all cost. This can only be a last-resort hack.
With CSS3 you can use the box-sizing property on your inputs to standardise their box models.
Something like this would enable you to add padding and have 100% width:
input[type="text"] {
-webkit-box-sizing: border-box; // Safari/Chrome, other WebKit
-moz-box-sizing: border-box; // Firefox, other Gecko
box-sizing: border-box; // Opera/IE 8+
}
Unfortunately this won't work for IE6/7 but the rest are fine (Compatibility List), so if you need to support these browsers your best bet would be Davids solution.
If you'd like to read more check out this brilliant article by Chris Coyier.
Hope this helps!
You can surround the textbox with a <div> and give that <div> padding: 0 20px. Your problem is that the 100% width does not include any padding or margin values; these values are added on top of the 100% width, thus the overflow.
Because of the way the Box-Modell is defined and implemented I don't think there is a css-only solution to this problem. (Apart from what Matthew described: using percentage for the padding as well, e.g. width: 94%; padding: 0 3%;)
You could however build some Javascript-Code to calculate the width dynmically on page-load... hm, and that value would of course also have to be updated every time the browserwindow is resized.
Interesting by-product of some testing I've done: Firefox does set the width of an input field to 100% if additionally to width: 100%; you also set max-width to 100%. This doesn't work in Opera 9.5 or IE 7 though (haven't tested older versions).
How do I get the textbox to fit the container in 2019?
Just use display: flex;
#x {
background: salmon;
padding: 1em;
display: flex;
flex-wrap: wrap;
}
#y, input {
background: red;
padding: 0 20px;
width: 100%;
}
<div id="x">
<div id="y">x</div>
<input type="text"/>
</div>
This is unfortunately not possible with pure CSS; HTML or Javascript modifications are necessary for any non-trivial flexible-but-constrained UI behavior. CSS3 columns will help in this regard somewhat, but not in scenarios like yours.
David's solution is the cleanest. It's not really a case of divitis -- you're not adding a bunch of divs unnecessarily, or giving them classnames like "p" and "h1". It's serving a specific purpose, and the nice thing in this case is that it's also an extensible solution -- e.g. you can then add rounded corners at any time without adding anything further. Accessibility also isn't affected, as they're empty divs.
Fwiw, here's how I implement all of my textboxes:
<div class="textbox" id="username">
<div class="before"></div>
<div class="during">
<input type="text" value="" />
</div>
<div class="after"></div>
</div>
You're then free to use CSS to add rounded corners, add padding like in your case, etc., but you also don't have to -- you're free to hide those side divs altogether and have just a regular input textbox.
Other solutions are to use tables, e.g. Amazon uses tables in order to get flexible-but-constrained layout, or to use Javascript to tweak the sizes and update them on window resizes, e.g. Google Docs, Maps, etc. all do this.
Anyway, my two cents: don't let idealism get in the way of practicality in cases like this. :) David's solution works and hardly clutters up HTML at all (and in fact, using semantic classnames like "before" and "after" is still very clean imo).
This behavior is caused by the different interpretations of the box model. The correct box model states that the width applies only to the content and padding and margin add on to it. So therefore your are getting 100% plus a 20px right and left padding equaling 100%+40px as the total width. The original IE box model, also known as quirks mode, includes padding and margin in the width. So the width of your content would be 100% - 40px in this case. This is why you see two different behaviors. As far as I know there is no solution for this there is however a work around by setting the width to say 98% and the padding to 1% on each side.
#Domenic this does not work. width auto does nothing more then the default behavior of that element because the initial value of width is auto ( see page 164, Cascading Style Sheets Level 2 Revision 1 Specification). Assigning a display of type block does not work either, this simply tell the browser to use a block box when displaying the element and does not assign a default behavior of taking as much space as possible like a div does ( see page 121, Cascading Style Sheets Level 2 Revision 1 Specification). That behavior is handled by the visual user agent not CSS or HTML definition.
i believe you can counter the overflow with a negative margin. ie
margin: -1em;
The default padding and border will prevent your textbox from truly being 100%, so first you have to set them to 0:
input {
background: red;
padding: 0;
width: 100%;
border: 0; //use 0 instead of "none" for ie7
}
Then, put your border and any padding or margin you want in a div around the textbox:
.text-box {
padding: 0 20px;
border: solid 1px #000000;
}
<body>
<div id="x">
<div id="y">x</div>
<div class="text-box"><input type="text"/></div>
</div>
</body>
This should allow your textbox to be expandable and the exact size you want without javascript.
To make the input fill up width of parent, there're 3 attributes to set: width: 100%, margin-left: 0, margin-right: 0.
I just guess zero margin setting can help, and I had tried it, however I don't know why margin (left and right; of course top and bottom margins don't affect here) should to be zero to make it works. :-)
input {
width: 100%;
margin-left: 0;
margin-right: 0;
}
Note: You may need to set box-sizing to border-box to make sure the padding don't affect the result.
I use to solve this with CSS-only tables. A little bit long example but
important for all who wants to make entry screens for large amount of fields
for databases...
// GH
// NO JAVA !!! ;-)
html {
height: 100%;
}
body {
position: fixed;
margin: 0px;
padding: 0px;
border: 2px solid #FF0000;
width: calc(100% - 4px);
/* Demonstrate how form can fill body */
min-height: calc(100% - 120px);
margin-top: 60px;
margin-bottom: 60px;
}
/* Example how to make a data entry form */
.rx-form {
display: table;
table-layout: fixed;
border: 1px solid #0000FF;
width: 100%;
border-collapse: separate;
border-spacing: 5px;
}
.rx-caption {
display: table-caption;
border: 1px solid #000000;
text-align: center;
padding: 10px;
margin: 10px;
width: calc(100% - 40px);
font-size: 2.5em;
}
.rx-row {
display: table-row;
/* To make frame on rows. Rows have no border... ? */
box-shadow: 0px 0px 0px 1px rgb(0, 0, 0);
}
.rx-cell {
display: table-cell;
margin: 0px;
padding: 4px;
border: 1px solid #FF0000;
}
.rx-cell label {
float: left;
border: 1px solid #00FF00;
width: 110px;
padding: 4px;
font-size: 1em;
text-align: right;
font-family: Arial, Helvetica, sans-serif;
overflow: hidden;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.rx-cell label:after {
content: " :";
}
.rx-cell input[type='text'] {
float: right;
border: 1px solid #FF00FF;
padding: 4px;
background-color: #eee;
border-radius: 0px;
font-family: Arial, Helvetica, sans-serif;
font-size: 1em;
/* Fill the cell - but subtract the label width - and litte more... */
width: calc(100% - 130px);
overflow: hidden;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
input[type='submit'] {
font-size: 1.3em;
}
<html>
<meta charset="UTF-8">
<body>
<!--
G Hasse, gorhas at raditex dot nu
This example have a lot of frames so we
can experiment with padding and margins.
-->
<form>
<div class='rx-form'>
<div class='rx-caption'>
Caption
</div>
<!-- First row of entry -->
<div class='rx-row'>
<div class='rx-cell'>
<label for="input11">Label 1-1</label>
<input type="text" name="input11" id="input11" value="Some latin text here. And if it is very long it will get ellipsis" />
</div>
<div class='rx-cell'>
<label for="input12">Label 1-2</label>
<input type="text" name="input12" id="input12" value="The content of input 2" />
</div>
<div class='rx-cell'>
<label for="input13">Label 1-3</label>
<input type="text" name="input13" id="input13" value="Content 3" />
</div>
<div class='rx-cell'>
<label for="input14">Label 1-4</label>
<input type="text" name="input14" id="input14" value="Content 4" />
</div>
</div>
<!-- Next row of entry -->
<div class='rx-row'>
<div class='rx-cell'>
<label for="input21">Label 2-1</label>
<input type="text" name="input21" id="input21" value="Content 2-1">
</div>
<div class='rx-cell'>
<label for="input22">Label 2-2</label>
<input type="text" name="input22" id="input22" value="Content 2-2">
</div>
<div class='rx-cell'>
<label for="input23">Label 2-3</label>
<input type="text" name="input23" id="input23" value="Content 2-3">
</div>
</div>
<!-- Next row of entry -->
<div class='rx-row'>
<div class='rx-cell'>
<label for="input21">Label 2-1</label>
<input type="text" name="input21" id="input21" value="Content 2-1">
</div>
<div class='rx-cell'>
<label for="input22">Label 2-2</label>
<input type="text" name="input22" id="input22" value="Content 2-2">
</div>
<div class='rx-cell'>
<label for="input23">Label 2-3</label>
<input type="text" name="input23" id="input23" value="Content 2-3">
</div>
</div>
<!-- And some text in cells -->
<div class='rx-row'>
<div class='rx-cell'>
<div>Cell content</div>
</div>
<div class='rx-cell'>
<span>Cell content</span>
</div>
</div>
<!-- And we place the submit buttons in a cell -->
<div class='rx-row'>
<div class='rx-cell'>
<input type="submit" name="submit1" value="submit1" />
<input type="submit" name="submit2" value="submit2" />
</div>
</div>
<!-- End of form -->
</div>
</form>
</body>
</html>