I want two buttons to be displayed right next to each other, with no border in between. The buttons are:
<button class="tButton">1</button>
<button class="tButton">2</button>
My naive approach for the css is:
.tButton {
width: 50px;
height: 50px;
margin:0px;
padding: 0px;
background-color: gray;
border: none;
}
But this leaves some space between the buttons (JSFiddle). In Firefox, the example renders as:
This problem goes away when I use float: left; on the buttons. But I am trying to understand the following about CSS:
Why is there any margin to begin with, even though I explicitly set margin: 0;?
Because by default buttons are inline-block elements, and as any inline/inline-block elements they respect white spaces including new lines.
For this reason putting buttons on the same line gets rid of gaps:
.tButton {
width: 50px;
height: 50px;
margin:0px;
padding: 0px;
background-color: gray;
border: none;
}
<button class="tButton">1</button><button class="tButton">2</button>
as well as making them float: left since in this case buttons become floated block-level elements.
This happens with inline and inline-block elements. space is added in newline. You should change your markup, from:
<button class="tButton">1</button>
<button class="tButton">2</button>
To
<button class="tButton">1</button><button class="tButton">2</button>
single line fiddle
as a variant, you can write:
<button class="tButton">1</button
><button class="tButton">2</button>
The body is still a “BIG DIV” which needs to be set with margin zero and give a display:flex; so the items on its container will stack one together to the other inline. I checked your code in https://jsfiddle.net/83a2Lou0/ and it needs to be saved first before you see the effect of the changes.
I forked your same code in code pen and there the changes are saved automatically. Just add this to your CSS:
body{
margin: 0;
display: flex;
}
.tButton {
/* The same properties and values you have here. */
And that‘s it. Check here the same coding:
https://codepen.io/limakid/pen/KKQRdXK
Related
At the bottom of my page there are 3 buttons. "Send, Save and Cancel" buttons. The Save and Cancel buttons are the same height but the "Send" button is different from the other two. Why is this happening?
I read on another post that said elements render buttons different from normal buttons so I tried to fix it with the solution given but it didn't work. I also tried removing element but it still didn't work. Thanks for your help!
Buttons Styles
background-color: #8f81e8;
color: #fff;
border-radius: 5px;
text-transform: uppercase;
font-weight: 300;
font-size: 16px;
cursor: pointer;
padding: 1rem;
CodePen
It's because your send is input while other elements are button.
Add border: none; to your css
you can give static height to all three buttons.
You have two different divs: .user-messages (the left one) and .settings the right one.
The left one contains an input, while the right one contains two buttons. So you can either add border:none to the left one to make the border disappear and then re-arrange your layout to use a button instead of an input.
Update
Wrap the buttons into a seperate div below the div of the two pages and do the following:
div {
display:flex;
justify-content:space-around;
}
button {
width: 100%;
margin: 5px; /* or whatever you want to have */
}
<div style="width: 100%; background-color: green;">
<button type="button">A</button>
<button type="button">B</button>
<button type="button">C</button>
</div>
Is the result of my snippet the desired outcome?
Seems to be the display: flex on the settings-btn-box that is causing it. One solution could look something like this:
.settings-btn-box {
/* display: flex; */
}
.settings-btn-box button {
width: 49%;
}
.btn-save {
/* margin-right: 10px; */
}
.btn-cancel {
/* margin-left: 10px; */
float: right;
}
Personally, I'm not a big fan of float, but since it's the last element in the div it should be fine.
I have an annoying issue with the html layout of a form. I cannot really change the general setup, since it is part of a huge framework. But I have to "move" a button to a more suitable location. I am close, but not happy with the solution so far. Maybe you can give me some idea in this. Here is a dramatically simplified version to demonstrate my approach:
I have two container divs, top and bottom.
The top container shows a button on the left side. That button is fixed, but can have a different width due to the translation of its label.
The bottom container holds lots of stuff. Amongst that a second button at its top which works fine, but looks wrong. I want to optically move it into the top container, since there is a logical connection to the button in there. Sure, really placing it in there would be the correct solution, but I currently cannot do that. Instead I use a fixed position which works fine, except for the horizontal placement. I have to decide how far pushed from the left to place the button, so that it certainly does not overlap the first button in the container. I obviously have to consider all translations, the result works, but depending on the first buttons label I have an annoying horizontal gap between the two buttons.
I tried to use a pseudo element (::before) on the second button to help with the layout. Since when rendering the view I obviously have the translated label of the first button I can copy that into some property of the second button and use that property in my css to fill a before pseudo element of the second button which has exactly the same length as the first button. That is what is shown in the code example posted below.
What I completely fail to do is to place that pseudo element such that is it left in the top container (so exactly below the first button). The idea is to indirectly place the second button that way. Looks like this is not possible, obviously. But since I am a bloody beginner in markup and styling I thought it might be worth asking here...
Below is some drastically stripped down code to demonstrate my approach.
I create a jsfiddle for you to play around with. Here is the code:
HTML:
<div id="top-container">
<button>multilingual button text</button>
</div>
<div id="bottom-container">
<h2>
Some title opening the bottom container
<span class="into-top-container">
<button id="place-me" reference-text="multilingual button text">button to be placed</button>
</span>
</h2>
<p>Some content</p>
<p>Some content</p>
<p>Some content</p>
</div>
CSS:
body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
div {
margin: 0;
padding: 5px;
}
button {
margin: 0;
padding: 5px;
white-space: nowrap;
}
div#top-container {
width: 100%;
border: 1px solid green;
}
div#bottom-container {
width: 100%;
border: 1px solid blue;
}
#place-me {
position: fixed;
top: 0;
left: 400px;
margin: 5px;
background: yellow;
}
#place-me::before {
z-index: 0;
/*visibility: hidden;*/
position: absolute;
content: attr(reference-text);
margin: 0 5px;
padding: 0;
background: gold;
right: 100%;
}
Notes:
that in the above code the second button is placed with left: 400px;. That is more or less what I want to change. But obviously left: 0 is not correct...
the visibility css rule for the pseudo element is currently commented out for demonstration purpose
keep in mind that the second button is *not* contained inside the top container, but actually logically below the title of the bottom container. The goal is to move it optically up into the top container which already is where close to what I want. Except for the horizontal alignment...
Upon request here is a screenshot:
It is taken from the fiddle I posted above. I added the red ellipse which shows what element pair I want to move and the left pointing arrow indicating where I want to move that too. I want to move it exactly that far, that the two tests "multilingual button text" are exactly placed on top of each other, but without specifying an explicit left placement obviously. That is why the pseudo element exists: as a dummy placeholder. I would then hide that pseudo element and have the second button placed exactly right of the first button, regardless of how long the translated text in there is.
So the final result should like like that:
OK, I invested some more time, since this issue popped up again after a regression in our code and I found, as often after allowing some time to pass, a logical and relatively clean solution:
I use the same stripped down code to for demonstration purposes.
The jsfiddle is based on the one provided in the question itself.
HTML: no real change, except for the reference-text having moved from button to container, for the why see below:
CSS:
* {
font-size: 12px;
font-weight: normal;
font-family: Arial;
}
body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
font-size: 12px;
font-weight: normal;
}
span,
div {
margin: 0;
padding: 5px;
}
button {
margin: 0;
padding: 5px;
white-space: nowrap;
}
div#top-container {
width: 100%;
border: 1px solid green;
}
div#bottom-container {
width: 100%;
border: 1px solid blue;
}
span.into-top-container {
position: fixed;
top: 0;
left: 0;
pointer-events: none;
border: 1px solid transparent;
}
span.into-top-container::before {
visibility: hidden;
content: attr(reference-text);
position: relative;
margin-right: 5px;
padding: 5px;
border: 2px solid;
background: gold;
}
#place-me {
background: yellow;
pointer-events: all;
}
The basic change in strategy: it is the container holding the button to be placed that has to be positioned in a fixed manner, not that button itself (so the <span class="into-top-container">)! That allows to use the pseudo before element, now also anchored to that container, not the button, to take the space as required without actually getting part of the button itself.
Since that container is now place over the original multilingual button that one is not clickable any more. That issue is fixed by a css pointer-events set to none for the container and set to all for the placed button again. That makes the container itself simply ignore all events (clicks) and have them passed to the original button beneath.
I had to make sure that the font used inside the pseudo element is style exactly like the original multilingual button. That actually makes sense, since the font styling defines the actual width used by that button, so the actual width used by the pseudo element should be defined in exactly the same manner. In the example above I forced that by simply setting all elements font style rules to some fixed values (the initial * {...} in the CSS code). That can obviously also be done right inside the css rules for the pseudo element itself. I chose the more simple and brute variant here to keep the code clean.
This question already has answers here:
Why does this inline-block element have content that is not vertically aligned
(4 answers)
Closed 8 years ago.
Here's a fiddle that shows my code in action
The result seems crazy to me: in Chrome second button is slightly above the first.
In Firefox it is slightly below.
<div id="accounts">
<button class="account">
<h1>VISA Card</h1>
<span class="balance">-433.18</span>
</button>
<button class="account">
<h1 class="plus"><i class="icon icon-plus-sign"></i></h1>
<span class="plus-text">Add Account</span>
</button>
</div>
What is even more confusing is that padding on the h1.plus affects the position of the whole div.
What is going on here? I want two buttons to show up on the same line and simply don't undestand why they aren't. Is this a bug in the rendering engine?
UPDATE:
Narendra suggested an easy fix - float:left the buttons. I want to figure out why this misalignment happening in the first place.
You are using display:inline-block, so the buttons are aligned by their vertical-align property, which defaults to baseline.
This is a diagram from the specs which illustrates exactly that:
You can see in the first two boxes how padding and the font size of the content influence the positioning.
As a fix, use vertical-align: top or bottom, or even middle.
Edit: The image is from the table section and the situation is slighty different for inline-blocks.
Add this to your button.account: vertical-align: middle; .
And you can lose the display: inline-block; property, as it is not needed.
Check below code
button.account {
display: block;
float: left;
height: 80px;
margin: 10px 10px;
padding: 10px 5px;
width: 170px;
}
.account h1 {
font-size: 16px;
height: 16px;
margin: 0 0 5px;
padding: 4px 0 2px;
}
.account .balance {
display: block;
font-size: 24px;
}
.account h1.plus {
font-size: 24px;
padding-top: 0px;
}
Here is the fiddle http://jsfiddle.net/Gq3U8/13/
If you are using inline-block, the main concern is about the whitespace (you will see the default margin around the element). To fix this just add vertical-align:top, instead of using float:left. It will align the element to the top.
.account {
display: inline-block;
vertical-align: top; /*add this one*/
margin: 10px 10px; /*remove this one then can see whitespace*/
}
I have 4 buttons in a header div. I have placed them all using margins top and left in css so they are all next to each other in one line. Nothing fancy.
Now I'm trying to do an action when the button is pressed the button text moves down a little bit.
I'm using this code in CSS :
#btnhome:active{
line-height : 25px;
}
HTML :
<div id="header">
<button id="btnhome">Home</button>
<button id="btnabout">About</button>
<button id="btncontact">Contact</button>
<button id="btnsup">Help Us</button>
</div>
Button CSS example :
#btnhome {
margin-left: 121px;
margin-top: 1px;
width: 84px;
height: 45px;
background: transparent;
border: none;
color: white;
font-size:14px;
font-weight:700;
}
Also those buttons work on a header background, I'm sure it has something to do with these settings :
#header {
background-image: url(images/navbar588.png);
height: 48px;
width: 588px;
margin: 2em auto;
}
It works well but the only problem is that the all other buttons also move their text down? Why Is that? Aren't I clearly clarifying that I want to use #btnhome only? All the buttons have completely different ID's. All buttons have the same CSS settings except the margins. What do I need to edit?
Thank you very much.
as I expected, yeah, it's because the whole DOM element is being pushed down. You have multiple options. You can put the buttons in separate divs, and float them so that they don't affect each other. the simpler solution is to just set the :active button to position:relative; and use top instead of margin or line-height. example fiddle: http://jsfiddle.net/5CZRP/
try changing that line-height change to a margin-top or padding-top change instead
#btnhome:active{
margin-top : 25px;
}
Edit:
You could also try adding a span inside the button
<div id="header">
<button id="btnhome"><span>Home</span></button>
<button id="btnabout">About</button>
<button id="btncontact">Contact</button>
<button id="btnsup">Help Us</button>
</div>
Then style that
#btnhome span:active { padding-top:25px;}
Use margins instead of line-height and then apply float to the buttons. By default they are displaying as inline-block, so when one is pushed down the hole line is pushed down with him. Float fixes this:
#header button {
float:left;
}
Here's a working jsfidle.
[type=submit]{
margin-left: 121px;
margin-top: 19px;
width: 84px;
height: 40px;
font-size:14px;
font-weight:700;
}
Ok, I had a simple layout problem a week or two ago. Namely sections of a page needed a header:
+---------------------------------------------------------+
| Title Button |
+---------------------------------------------------------+
Pretty simple stuff. Thing is table hatred seems to have taken over in the Web world, which I was reminded of when I asked Why use definition lists (DL,DD,DT) tags for HTML forms instead of tables? Now the general topic of tables vs divs/CSS has previously been discussed, for example:
DIV vs Table; and
Tables instead of DIVs.
So this isn't intended to be a general discussion about CSS vs tables for layout. This is simply the solution to one problem. I tried various solutions to the above using CSS including:
Float right for the button or a div containing the button;
Position relative for the button; and
Position relative+absolute.
None of these solutions were satisfactory for different reasons. For example the relative positioning resulted in a z-index issue where my dropdown menu appeared under the content.
So I ended up going back to:
<style type="text/css">
.group-header { background-color: yellow; width: 100%; }
.group-header td { padding: 8px; }
.group-title { text-align: left; font-weight: bold; }
.group-buttons { text-align: right; }
</style>
<table class="group-header">
<tr>
<td class="group-title">Title</td>
<td class="group-buttons"><input type="button" name="Button"></td>
</tr>
</table>
And it works perfectly. It's simple, as backward compatibile as it gets (that'll work probably even on IE5) and it just works. No messing about with positioning or floats.
So can anyone do the equivalent without tables?
The requirements are:
Backwards compatible: to FF2 and IE6;
Reasonably consistent: across different browsers;
Vertically centered: the button and title are of different heights; and
Flexible: allow reasonably precise control over positioning (padding and/or margin) and styling.
On a side note, I came across a couple of interesting articles today:
Why CSS should not be used for layout; and
Tables vs CSS: CSS Trolls begone
EDIT: Let me elaborate on the float issue. This sort of works:
<html>
<head>
<title>Layout</title>
<style type="text/css">
.group-header, .group-content { width: 500px; margin: 0 auto; }
.group-header { border: 1px solid red; background: yellow; overflow: hidden; }
.group-content { border: 1px solid black; background: #DDD; }
.group-title { float: left; padding: 8px; }
.group-buttons { float: right; padding: 8px; }
</style>
</head>
<body>
<div class="group-header">
<div class="group-title">This is my title</div>
<div class="group-buttons"><input type="button" value="Collapse"></div>
</div>
<div class="group-content">
<p>And it works perfectly. It's simple, as backward compatibile as it gets (that'll work probably even on IE5) and it just works. No messing about with positioning or floats.</p>
<p>So can anyone do the equivalent without tables that is backwards compatible to at least FF2 and IE6?</p>
<p>On a side note, I came across a couple of interesting articles today:</p>
</div>
</body>
</html>
Thanks to Ant P for the overflow: hidden part (still don't get why though). Here's where the problem comes in. Say I want the title and button to be vertically centered. This is problematic because the elements are of different height. Compare this to:
<html>
<head>
<title>Layout</title>
<style type="text/css">
.group-header, .group-content { width: 500px; margin: 0 auto; }
.group-header { border: 1px solid red; background: yellow; overflow: hidden; }
.group-content { border: 1px solid black; background: #DDD; }
.group-header td { vertical-align: middle; }
.group-title { padding: 8px; }
.group-buttons { text-align: right; }
</style>
</head>
<body>
<table class="group-header">
<tr>
<td class="group-title">This is my title</td>
<td class="group-buttons"><input type="button" value="Collapse"></td>
</tr>
</table>
<div class="group-content">
<p>And it works perfectly. It's simple, as backward compatibile as it gets (that'll work probably even on IE5) and it just works. No messing about with positioning or floats.</p>
<p>So can anyone do the equivalent without tables that is backwards compatible to at least FF2 and IE6?</p>
<p>On a side note, I came across a couple of interesting articles today:</p>
</div>
</body>
</html>
which works perfectly.
There is nothing wrong with using the tools that are available to you to do the job quickly and correctly.
In this case a table worked perfectly.
I personally would have used a table for this.
I think nested tables should be avoided, things can get messy.
Just float left and right and set to clear both and you're done. No need for tables.
Edit: I know that I got a lot of upvotes for this, and I believed I was right. But there are cases where you simply need to have tables. You can try doing everything with CSS and it will work in modern browsers, but if you wish to support older ones... Not to repeat myself, here the related stack overflow thread and rant on my blog.
Edit2: Since older browsers are not that interesting anymore, I'm using Twitter bootstrap for new projects. It's great for most layout needs and does using CSS.
Float title left, float button right, and (here's the part I never knew until recently) - make the container of them both {overflow:hidden}.
That should avoid the z-index problem, anyway. If it doesn't work, and you really need the IE5 support, go ahead and use the table.
This is kind of a trick question: it looks terribly simple until you get to
Say I want the title and button to be vertically centered.
I want to state for the record that yes, vertical centring is difficult in CSS. When people post, and it seems endless on SO, "can you do X in CSS" the answer is almost always "yes" and their whinging seems unjustified. In this case, yes, that one particular thing is hard.
Someone should just edit the entire question down to "is vertical centring problematic in CSS?".
In pure CSS, a working answer will one day be to just use "display:table-cell". Unfortunately that doesn't work across current A-grade browsers, so for all that you might as well use a table if you just want to achieve the same result anyway. At least you'll be sure it works far enough into the past.
Honestly, just use a table if it's easier. It won't hurt.
If the semantics and accessibility of the table element really matter to you, there is a working draft for making your table non-semantic:
http://www.w3.org/TR/wai-aria/#presentation
I think this requires a special DTD beyond XHTML 1.1, which would just stir up the whole text/html vs application/xml debate, so let's not go there.
So, on to your unresolved CSS problem...
To vertically align two elements on their center: it can be done a few different ways, with some obtuse CSS hackery.
If you can fit within the following constraints, then there is a relatively simple way:
The height of the two elements is fixed.
The height of the container is fixed.
The elements will be narrow enough not to overlap (or can be set to a fixed width).
Then you can use absolute positioning with negative margins:
.group-header { height: 50px; position: relative; }
.group-title, .group-buttons { position: absolute; top: 50%; }
# Assuming the height of .group-title is a known 34px
.group-title { left: 0; margin-top: -17px; }
# Assuming the height of .group-buttons is a known 38px
.group-buttons { right: 0; margin-top: -19px; }
But this is pointless in most situations... If you already know the height of the elements, then you can just use floats and add enough margin to position them as needed.
Here is another method which uses the text baseline to vertically align the two columns as inline blocks. The drawback here is that you need to set fixed widths for the columns to fill out the width from the left edge. Because we need to keep the elements locked to a text baseline, we can't just use float:right for the second column. (Instead, we have to make the first column wide enough to push it over.)
<html>
<head>
<title>Layout</title>
<style type="text/css">
.group-header, .group-content { width: 500px; margin: 0 auto; }
.group-header { border: 1px solid red; background: yellow; }
.valign { display: inline-block; vertical-align: middle; }
.group-content { border: 1px solid black; background: #DDD; }
.group-title { padding: 8px; width: 384px; }
.group-buttons { padding: 8px; width: 84px; text-align: right; }
</style>
<!--[if lt IE 8]>
<style type="text/css">
.valign { display: inline; margin-top: -2px; padding-top: 1px; }
</style>
<![endif]-->
</head>
<body>
<div class="group-header">
<div class="valign">
<div class="group-title">This is my title.</div>
</div><!-- avoid whitespace between these! --><div class="valign">
<div class="group-buttons"><input type="button" value="Collapse"></div>
</div>
</div>
<div class="group-content">
<p>And it works perfectly, but mind the hacks.</p>
</div>
</body>
</html>
The HTML: We add .valign wrappers around each column. (Give them a more "semantic" name if it makes you happier.) These need to be kept without whitespace in between or else text spaces will push them apart. (I know it sucks, but that's what you get for being "pure" with the markup and separating it from the presentation layer... Ha!)
The CSS: We use vertical-align:middle to line up the blocks to the text baseline of the group-header element. The different heights of each block will stay vertically centered and push out the height of their container. The widths of the elements need to be calculated to fit the width. Here, they are 400 and 100, minus their horizontal padding.
The IE fixes: Internet Explorer only displays inline-block for natively-inline elements (e.g. span, not div). But, if we give the div hasLayout and then display it inline, it will behave just like inline-block. The margin adjustment is to fix a 1px gap at the top (try adding background colors to the .group-title to see).
I would recommend not using a table in this instance, because that is not tabular data; it's purely presentational to have the button located at the far right. This is what I'd do to duplicate your table structure (change to a different H# to suit where you are in your site's hierarchy):
<style>
.group-header { background: yellow; zoom: 1; padding: 8px; }
.group-header:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
/* set width appropriately to allow room for button */
.group-header h3 { float: left; width: 300px; }
/* set line-height or margins to align with h3 baseline or middle */
.group-header input { float: right; }
</style>
<div class="group-header">
<h3>This is my title</h3>
<input type="button" value="Collapse"/>
</div>
If you want true vertical alignment in the middle (ie, if the text wraps the button is still middle-aligned with respect to both lines of text), then you either need to do a table or work something with position: absolute and margins. You can add position: relative to your drop-down menu (or more likely its parent) in order to pull it into the same ordering level as the buttons, allowing you to bump it above them with z-index, if it comes to that.
Note that you don't need width: 100% on the div because it's a block-level element, and zoom: 1 makes the div behave like it has a clearfix in IE (other browsers pick up the actual clearfix). You also don't need all those extraneous classes if you're targeting things a bit more specifically, although you might need a wrapper div or span on the button to make positioning easier.
Do a double float in a div and use the clearfix. http://www.webtoolkit.info/css-clearfix.html Do you have any padding/margin restrictions?
<div class="clearfix">
<div style="float:left">Title</div>
<input type="button" value="Button" style="float:right" />
</div>
<div class="group-header">
<input type="button" name="Button" value="Button" style="float:right" />
<span>Title</span>
</div>
I've chose to use Flexbox, because it made things so much easier.
You basically need to go to the parent of the children you want to align and add display:box (prefixed of course). To make them sit in the sides, use justify-content. Space between is the right thing when you have elements which need to be aligned to the end, like in this case (see link)...
Then the vertical align issue. Because I made the parent of the two elements, you want to align a Flexbox. It's easy now to use align-items: center.
Then I added the styles you wanted before, removed the float from the title and button in the header and added a padding:
.group-header, .group-content {
width: 500px;
margin: 0 auto;
}
.group-header{
border: 1px solid red;
background: yellow;
overflow: hidden;
display: -webkit-box;
display: -moz-box;
display: box;
display: -webkit-flex;
display: -moz-flex;
display: -ms-flexbox;
display: flex;
-webkit-justify-content: space-between;
-moz-justify-content: space-between;
-ms-justify-content: space-between;
-o-justify-content: space-between;
justify-content: space-between;
webkit-align-items: center;
-moz-align-items: center;
-ms-align-items: center;
-o-align-items: center;
align-items: center;
padding: 8px 0;
}
.group-content{
border: 1px solid black;
background: #DDD;
}
.group-title {
padding-left: 8px;
}
.group-buttons {
padding-right: 8px
}
See Demo
I agree that one should really only use tables for tabular data, for the simple reason that tables don't show until they're finished loading (no matter how fast that is; it's slower that the CSS method). I do, however, feel that this is the simplest and most elegant solution:
<html>
<head>
<title>stack header</title>
<style type="text/css">
#stackheader {
background-color: #666;
color: #FFF;
width: 410px;
height: 50px;
}
#title {
color: #FFF;
float: left;
padding: 15px 0 0 15px;
}
#button {
color: #FFF;
float: right;
padding: 15px 15px 0 0;
}
</style>
</head>
<body>
<div id="stackheader">
<div id="title">Title</div>
<div id="button">Button</div>
</div>
</body>
</html>
The button function and any extra detail can be styled from this basic form. Apologies for the bad tags.