How to center the content of month input field? - html

I'm having trouble centering the text inside a HTML month-input field. Here's a simplified version of my HTML/CSS to demonstrate the issue:
If you run it, you'll see that it is not centered - and if you try "text-align: right", it doesn't move all the way right either. It does move with both alternatives, which is strange.
Any idea why this happens?
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<style>
body {
font-family: Helvetica;
font-size: 14px;
position: relative;
text-align: center;
}
.monthSelector{
display: inline-block;
text-align: center;
width: 250px;
}
</style>
</head>
<body>
<input disabled type="month" class="monthSelector" min="2017-01" max="2099-12" value="2018-01">
</body>
</html>
This is how it looks to me: As you can see the text is not centered inside the input box.

This doesn't work as expected because of the way input type="month" is rendered.
If you remove the disabled attribute you will see that (depending on the browser) you have some arrows and carets on the right. Taking them into account your text is in dead center.
You need to add this CSS
input[type=month]::-webkit-calendar-picker-indicator,
input[type=month]::-webkit-inner-spin-button {
display: none;
-webkit-appearance: none;
}
et voila
EDIT:
You can use :disabled CSS selector so it doesn't affect your other inputs
input[type=date]:disabled::-webkit-calendar-picker-indicator,
input[type=date]:disabled::-webkit-inner-spin-button {
-webkit-appearance: none;
display: none;
}

It is caused by default input controls being present (but invisible due to the input being disabled) when you give it month type. The inputs text is centered relatively to the inputs width minus the width of the controls. One way around it is giving them a manually selected margin to visually center the text.
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<style>
body {
font-family: Helvetica;
font-size: 14px;
position: relative;
text-align: center;
}
.monthSelector{
display: inline-block;
text-align: center;
width: 250px;
box-sizing:border-box;
}
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
/* display: none; <- Crashes Chrome on hover */
-webkit-appearance: none;
margin: -15px; /* <-- Apparently some margin are still there even though it's hidden */
}
</style>
</head>
<body>
<input disabled type="month" class="monthSelector" min="2017-01" max="2099-12" value="2018-01">
</body>
</html>

#Daut has given a good explanation about the rendering of hidden elements in the month input.
You could go with the solution but it adds another challenge. Now, you are forced to make sure that the CSS has enough properties to render correctly in all browsers. Then you usually go for polyfills or you could just mark the input type as text.

Related

CSS Search Bar Not Responsive

I'm making a responsive GitHub Homepage Clone (https://github.com/) with HTML and CSS before moving on to JS. I'm currently working on a search bar. However, when I narrow the screen from the left side, the search bar width stays the same, causing the search bar to leave the entire left navigation bar. Any help would be greatly appreciated :)
P.S. Please view the code snippet at full page view
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
background-color: #f6f8fa;
font-family: Helvetica, sans-serif;
}
#left-menu {
background-color: white;
width: 25%;
display: flex;
flex-direction: column;
}
#left-menu-items {
margin: 40px 15px 300px 25px;
width: 85%;
}
#left-menu input {
background-color: transparent;
border: solid 1px #e1e4e8;
border-radius: 5px;
outline: none;
margin-bottom: 20px;
padding: 8px 113px 8px 10px;
}
#left-menu input::placeholder {
color: #d2d5d8;
font-size: 15px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://kit.fontawesome.com/735c9ee1fa.js" crossorigin="anonymous"></script>
<link rel="stylesheet" type="text/css" href="stylesheet.css">
<title>GitHub Homepage</title>
</head>
<body>
<section id="left-menu">
<div id="left-menu-items">
<input type="search" placeholder="Find a repository...">
</div>
</section>
</body>
</html>
The element I'm working on is the search bar that says "Find a
repository..." In order to allow the box to stretch to the right, I've
added a ton of padding.
Hi, Joshua.
In this case, asking a question with so many parts is hard to answer. If you can create a smaller example - it might help.
<aside class="sidebar">
<input type="search" placeholder="Find a repository">
</aside>
.
.sidebar {
border: 1px solid blue;
padding: 10px;
}
input[type='search'] {
padding: 5px 10px;
font-style: innherit;
}
https://jsfiddle.net/sheriffderek/smnovwqj/
From there - we can help you. You can always ask in the CSS Discord too.
HERE: with the sidebar in tact: https://jsfiddle.net/sheriffderek/e6k8gydu/
Presumably you want the search input to shrink and grow with the page.
To that end, you should use max-width: 300px along with flex-grow: 1 on the <input>.
flex-grow tells the flex-box how to allocate space along its main axis (in this case, the X axis). The value you give it represents a fraction of the parent flex-box. So in this case, if give it the value flex-grow: 1 it will take up as much space as it can, until it runs into another fixed with element, or another element that also has flex-grow set with a nonzero value.
Max-width simply tells the element how large it's allowed to get. You can obviously fine tune this by changing the value, but 300px seemed about right to me.
Put the two together and you no longer need your crazy padding. The input will shrink all the way down to nothing (if you want that to change you also add the min-width property)
and grow all the way up to 300px in this case.
You'll also also want to get rid of the <p> next to your text input. In this scenario, there's no reason at all to use a paragraph, as it has default styling that changes how it behaves. I would use a <div> instead.
After that I would get rid of the relative positioning on nav div p{} and just let flex-box do its magic. If you're trying to position an element in that way, a much better way is with margin. This is what margin is meant to be used for.
Sorry my answer isn't a more specific, but your question is a bit broad.

How do I put a p and an a tag inline in html?

I am trying to put a <p> tag inline with an <a> tag, but I can't figure out how. I've tried several display types in css, but they either don't work or do something weird to it.
(Here is a bunch of unnecessary words because the thing is saying there is too much code and not enough words. I think its pretty dumb because what I said is enough unless someone specifically asks for details about something).
Here's some example code:
body {
margin: 0;
padding: 0;
background-color: #efefef;
}
header {
margin: 0;
margin-top: -10px;
background-color: #ffffff;
}
header p {
margin: 0;
font-family: "arial";
font-size: 50px;
color: #3c3c3c;
margin-top: 10px;
margin-left: 10px;
text-align: center;
}
header a {
}
#information {
width: 500px;
height: 250px;
background-color: #ffffff;
box-shadow: 7px 7px 4px grey;
margin-left: 100px;
margin-top: 150px;
}
#information p {
font-family: "arial";
font-size: 20px;
color: #1febff;
}
#delete {
margin-top: 2000px;
}
<!DOCTYPE html>
<html>
<head>
<title>SaHa | Color Scheme</title>
<link href="style.css" type="text/css" rel="stylesheet" />
</head>
<body>
<header>
<p>SaHa</p>
Menu
</header>
<div id="information">
<p>Pretend that there is a bunch of important information here even though there really isn't.
This is normally where a message that actually means something would go, but this is just a
placeholder because I have nothing important to put here right now.
</p>
</div>
<div id="delete"></div>
</body>
</html>
In your HTML, try directly typing or after whatever text you want it to appear.
For example:<div>When i came<a> ut yiur name</a>so what do i do</div>
In your CSS body, try inline-block or just inline parameters with DISPLAY property to get any image or text into the normal flow of a line.
For example:
a {display:inline-block;}
Could you specify which elements in your example code you want inline?
Generally using display: inline and display: inline-block will make elements flow as if they were text. They will sit next to each other and jump to new lines when their container width gets too narrow. Browsers commonly apply display: block to <p> elements by default.
Assuming we are talking about the contents of your <header>, I added the following rule to your existing CSS. Check it out in action.
header p {
display: inline-block;
}
EDIT: Based on further comments, here is a solution to what you are looking for.
First of all I've wrapped your menu items in a nav element and made your main title a h1 element. Search engines like this better. A h1 element is also displayed inline by default and respects text-align properties on its parent container (which in this case is header).
<h1>SaHa</h1>
<nav>
Menu
Thing
Stuff
</nav>
On the CSS side I've made two crucial changes.
First, I've center-aligned your header text. This centers the new h1 element. Additionally I've set position: relative because we will need it in the next step.
header {
text-align: center;
position: relative;
}
Second, to position your menu to the right side of the screen I've lifted it from the regular flow of content with position: absolute. Now, by specifying either a top or bottom and left or right, we can position the menu anywhere in the header. Why the header? Because it is the nearest parent to nav that has a relative position. This is why we set it earlier!
nav {
position: absolute;
right: 10px;
bottom: 10px;
}
Try changing the values for right and bottom in this Codepen example. Try changing right to left and see what happens. What happens if you remove position: relative from .header?

How do you prevent "break" between "a:before" and "a" elements

If you are inserting something at the start of links (an icon, or whatever), how do you prevent the browser inserting a line break between the icon and the text when the link wraps at the edge of the page. i.e. With this:
a:before {
font-family: FontAwesome;
content: "\f101\00a0";
font-size: 0.9em;
opacity: 0.7;
text-decoration: none;
display: inline-block;
}
Currently if you resize the browser window, html like this:
<p>
This is some example text where my link
link is having its icon on the
previous line.
</p>
may render something like this:
This is some example text where my link %
link is having its icon on the previous line.
Try adding white-space:nowrap to your a element (not the :before psuedoelement)
However keep in mind that this may cause problems if the text cannot actually fit on one line in the window.
i.e. http://jsfiddle.net/A4VcV/4/
Remove the display:inline-block;
http://jsfiddle.net/ApaYP/
Tested on Mac Firefox, Safari and Chrome.
Hope this helps!
I prefer position: absolute; for this sort of thing. Here's an example:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<style media="all">
a {position: relative; padding-left: 1em;}
a:before {
font-family: FontAwesome;
content: "\f101\00a0";
font-size: 0.9em;
opacity: 0.7;
text-decoration: none;
position: absolute;
left: 0;
vertical-align: middle;
}
</style>
</head>
<body>
<p>This is some example text where my link link is having its icon on the previous line.</p>
</body>
</html>

Position an element at top right of a <span> in IE

I am having trouble positioning a (div) element at the top right of a span. It works in FF3, but not in IE7:
<html>
<head>
<style>
body
{
font-size: 24px;
}
.tag
{
padding: 3px;
background-color: lightblue;
position: relative;
}
.x
{
position: absolute;
top: 0px;
right: 0px;
width: 10px;
height: 10px;
background-color: orange;
}
</style>
</head>
<body>
text <span class="tag">tag<div class="x"></div></span> text
</body>
</html>
In FF3, a 10x10 orange box is rendered at the top right corner of the light blue box. I am having trouble getting this to work in IE7. Thanks!
First, get a proper doctype for your page so that it's not rendered in quirks mode.
W3C: Recommended list of DTDs
Second, make sure that the code is valid. You can not put a block element (div) inside an inline element (span).
W3C markup validation
you can also see this post if you have trouble with positionning in IE7 in the future

Can you do this HTML layout without using tables?

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.