I'm trying to show a simple button, with an image on it, like this:
<button type="button" style="width: 23px; height: 23px; padding:0">
<img src="Icon_304.png" />
</button>
The button looks right in Chrome, but is off a bit in Firefox—it's not horizontally centered, but skewed to the right. A FF screenshot is below. How can I get the image to be centered (like it is in Chrome by default)? I tried adding a margin: 0 to the img, to no avail.
The best way to do this is not to set the dimensions of the button, but to simply rely on padding. Obviously you should put these styles into a style sheet, as shown below.
DEMO: http://jsfiddle.net/QgTkt/4/
.tallButton {
padding: 50px 10px;
}
.wideButton {
padding: 10px 50px;
}
.equalButton {
padding: 10px;
}
<button type="button" class="equalButton">
<img src="http://dummyimage.com/32x32/ff0/000">
</button>
<br /><br /><br />
<button type="button" class="wideButton">
<img src="http://dummyimage.com/32x32/ff0/000">
</button>
<br /><br /><br />
<button type="button" class="tallButton">
<img src="http://dummyimage.com/32x32/ff0/000">
</button>
You can also set absolute position for the image and negative translate, this way you are able to set any size of the button without changing the padding again.
.tallButton{
position:relative;
width:200px;
height:200px;
}
.tallButton img {
position:absolute;
top: 50%;
left:50%;
-webkit-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
http://jsfiddle.net/QgTkt/292/
Set the image as background image of the button.
<button class="enjoyable"></button>
.enjoyable {
background-image: url("./icon.png");
background-position: center;
background-repeat: no-repeat;
background-size: contain;
}
Demo: http://jsfiddle.net/x7j4o0uh/1/
I threw this together pretty quickly, so it still needs some tweaking, but you can give this a shot... http://jsfiddle.net/GGXaP/3/
This script (using jQuery) handles the user interaction by adding/removing CSS classes as needed:
(function($) {
$(document).ready(function() {
$('.imageButton').hover(function() {
$(this).addClass('hover');
}, function() {
$(this).removeClass('hover');
});
$('.imageButton').mousedown(function() {
$(this).addClass('mouseDown');
});
$('.imageButton').mouseup(function() {
$(this).removeClass('mouseDown');
});
});
}(jQuery));
Then it's just a matter of setting up CSS to make the button look the way you like. The one in my example is pretty rough (I'm a "make it work" guy - not a "make it pretty" guy), but it's a start.
To solve this issue on Chrome I just added align-items : center on my button.
By default Chrome sets align-items : flex-start on all buttons, which aligns all elements inside the button on the left side, by overloading this property the picture inside my button is now centered.
Instead of giving height or width to button or image give padding to button so it will align that image to center
<button type="button" style="padding:10px">
<img src="test/images/searchIcon.png">
</button>
button {
display: grid;
align-items: center;
}
Inspiration: [1]
Related
What i'm trying to achieve
example of the closed version /
example of the opened version
At the top of the page in a 'fixed' header, i have a 'search' button next to a 'toggle' for the main menu. The header-search div (magnifying glass) is positioned next to the menu toggler (green). A form is currently positioned 'absolute' within the header to take up the full width of the header minus the padding on each side and its controls (search and toggler) as follows:
styles from header
.header {
top: 0;
left: 0;
width: 100%;
position: fixed;
background-color: var(--color-primary-700);
}
styles from header__aux
.header__aux {
display: flex;
column-gap: 1rem;
flex-flow: nowrap row;
}
.header-search {
display: block;
position: static;
}
.header-search__form {
top: 1.5rem;
height: 4rem;
overflow: hidden;
position: absolute;
left: var(--g-gutter);
width: calc(100% - (7rem + (var(--g-gutter)*2)));
}
.header-search__form-label {
top: -99.9rem;
left: -99.9rem;
color: inherit;
position: absolute;
}
.header-search__form.is-active
.header-search__form-input {
transform: translateX(0%);
}
.header-search__form-input {
width: 100%;
height: 4rem;
padding: 0 1.2em;
transform: translateX(100%);
border: .2rem solid #8097b3;
border-top-left-radius: 2rem;
border-bottom-left-radius: 2rem;
transition: transform 1s ease-in-out
background-color: var(--color-primary-700);
}
A input field inside this form is given 100% width and then using transform: translateX(100%) pushed completely to the right outside the overflow of the form (which retains it's width as set above). When a user presses the 'search' button a class is-active sets this transform: translateX(100%) to 0 and the input field should slide (from the right) to it's original position 100% of the width as seen in this image.
What this looks like in HTML
<header class="header section">
<div class="header__container container">
<a class="header__brand" href="#" aria-label="x">
<!-- svg brand -->
</a>
<div class="header__navs" id="headerNavs">
<div class="header__mask">
<ul id="headerMenu" class="header-menu">
</ul> <div class="header__langs header-langs">
Language
</div>
</div>
</div>
<div class="header__aux">
<div class="header__search header-search">
<button aria-label="Open of sluit het invoerveld voor een zoekopdracht" class="header-search__toggle" id="headerSearchToggle" aria-pressed="false" role="button" tabindex="0">
<i id="headerSearchIcon" class="far fa-search"></i>
</button>
<form class="header-search__form" action="/" id="headerSearchForm" role="search" method="get">
<label class="header-search__form-label" for="headerSearchInput">Zoeken</label>
<div class="header-search__form-slide">
<input placeholder="Zoeken …" required="" class="header-search__form-input" id="headerSearchInput" minlength="2" type="search" value="" name="s">
</div>
</form>
</div>
<a aria-label="" class="header__toggle header-toggle" aria-controls="headerNavs" aria-expanded="false" id="headerToggle" href="#">
Toggle
</a>
</div>
</div>
</header>
The problem
When opening the 'search' the input immediately jumps to the end of the animation which is seen in the example of the opened version (top) and then continues moving left, constantly correcting it's position back to what is seen in the image causing a weird 'flickering' effect usually in this position. Sliding the input 'back' to the right works perfectly.. What's even weirder is that it sometimes does work correctly for a few attempts once i've been on the page for a while. Then suddenly it breaks again.
What i've tried
Different types of browsers, including checking it on my own mobile device (not in the dev tools)
Giving the input the same fixed width as the parent
Removing a translateY on the parent and reverting to 'top' top position it in the vertical center
Adding 1 or multiple parents to the input to force it to inherit that width
As mentioned in a comment, adding transform:translateZ(0.1px); to force rendering using the GPU
What works, but i can't explain
Removing the overflow on the parent form element works and allows the animation to play smoothly, but that shows the input behind the element as seen in this image
I can think of some ways to make this look better, but i just really want to know what i'm missing. I believe i've done these types of simple animations 1000s of times now. A parent with overflow, hiding a child that's translated over.. or perhaps i'm mistaken. Hopefully someone can make sense of this - many thanks if you've taken the time to do so :)
I have a few images on my page. I'm finding that the page starts to render before the images have been loading (which is good), but that the visual effect is not great. Initially the user sees this:
--------hr--------
text
Then a few milliseconds later the page jumps to show this:
--------hr--------
[ ]
[ image ]
[ ]
text
Is there a simple way that I can show a grey background image of exactly the width and height that the image will occupy, until the image itself loads?
The complicating factor is that I don't know the height and width of the images in advance: they are responsive, and just set to width: 100% of the containing div. This is the HTML/CSS:
<div class="thumbnail">
<img src="myimage.jpeg" />
<div class="caption">caption</div>
</div>
img { width: 100% }
Here's a JSFiddle to illustrate the basic problem: http://jsfiddle.net/X8rTB/3/
I've looked into things like LazyLoad, but I can't help feeling there must be a simpler, non-JS answer. Or is the fact that I don't know the height of the image in advance an insurmountable problem? I do know the aspect ratio of the images.
Instead of referencing the image directly, stick it within a DIV, like the following:
<div class="placeholder">
<div class="myimage" style="background-image: url({somedynamicimageurl})"><img /></div>
</div>
Then in your CSS:
.placeholder {
width: 300;
height: 300;
background-repeat: no-repeat;
background-size: contain;
background-image: url('my_placeholder.png');
}
Keep in mind - the previous answers that recommend using a div background approach will change the semantic of your image by turning it from an img into a div background. This will result in things like no indexing of these images by a search crawler, delay in loading of these images by the browser (unless you explicitly preload them), etc.
A solution to this issue (while not using the div background approach) is to have a wrapper div to your image and add padding-top to it based on the aspect ratio of the image that you need to know in advance. The below code will work for an image with an aspect ratio of 2:1 (height is 50% of width).
<div style="width:100%;height:0; padding-top:50%;position:relative;">
<img src="<imgUrl>" style="position:absolute; top:0; left:0; width:100%;">
</div>
Of course - the major disadvantage of this approach is that you need to know the aspect ratio of the image in advance.
There is a really simple thing to check before you start looking into lazy-loading and other JavaScript. Make sure the JPEG images you are loading are saved with the 'progressive' option enabled!
This will cause them to load the image iteratively, starting with a placeholder that is low-resolution and faster to download, rather than waiting for the highest resolution data before rendering.
It's very simple...
This scenario allows to load a profile photo that defaults to a placeholder image.
You could load multi CSS background-image into an element. When an avatar photo fails, the placeholder image appears default of div.
If you're using a div element that loads via a CSS background-image, you could use this style:
#avatarImage {
background-image: url("place-holder-image.png"), url("avatar-image.png");
}
<div id="avatarImage"></div>
Feel free to copy this:
<script>
window.addEventListener("load", function () {
document.getElementById('image').style.backgroundColor = 'transparent';
});
</script>
<body>
<image src="example.example.example" alt="example" id="image" style="background-color:blue;">
</body>
I got this from here: Preloader keeps on loading and doesnt disappear when the content is loaded.
Apart from all solutions already mentioned, the last solution would be to hide the document until everything is loaded.
window.addEventListener('load', (e) => {
document.body.classList.add('loaded');
});
body {
opacity: 0;
}
body.loaded {
opacity: 1;
}
<div id="sidebar">
<img src="http://farm9.staticflickr.com/8075/8449869813_1e62a60f01_b.jpg" />
<img src="https://www.nla.gov.au/sites/default/files/pic-1.jpg" />
<img src="https://www.nla.gov.au/sites/default/files/pic-2.jpg" />
<img src="https://www.nla.gov.au/sites/default/files/pic-3.jpg" />
<img src="https://www.nla.gov.au/sites/default/files/pic-4.jpg" />
<img src="https://www.nla.gov.au/sites/default/files/pic-5.jpg" />
<img src="https://www.nla.gov.au/sites/default/files/pic-6.jpg" />
</div>
Or show some animation while everything is loading:
window.addEventListener('load', (e) => {
document.body.classList.add('loaded');
});
.loader {
border: 16px solid #f3f3f3;
border-radius: 50%;
border-top: 16px solid #3498db;
width: 70px;
height: 70px;
-webkit-animation: spin 2s linear infinite;
/* Safari */
animation: spin 2s linear infinite;
position: absolute;
left: calc(50% - 35px);
top: calc(50% - 35px);
}
#keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
body :not(.loader) {
opacity: 0;
}
body .loader {
display: block;
}
body.loaded :not(.loader) {
opacity: 1;
}
body.loaded .loader {
display: none;
}
<div class="loader"></div>
<div id="sidebar">
<img src="http://farm9.staticflickr.com/8075/8449869813_1e62a60f01_b.jpg" />
<img src="https://www.nla.gov.au/sites/default/files/pic-1.jpg" />
<img src="https://www.nla.gov.au/sites/default/files/pic-2.jpg" />
<img src="https://www.nla.gov.au/sites/default/files/pic-3.jpg" />
<img src="https://www.nla.gov.au/sites/default/files/pic-4.jpg" />
<img src="https://www.nla.gov.au/sites/default/files/pic-5.jpg" />
<img src="https://www.nla.gov.au/sites/default/files/pic-6.jpg" />
</div>
The only thing I can think of, to minimize the jump effect on your text, is to set min-height to where the image will appear, I would say - set it to the "shorter" image you know of. This way the jump will be less evident and you won't need to use lazyLoad or so... However it doesn't completely fix your problem.
Here's one naive way of doing it,
img {
box-shadow: 0 0 10px 0 rgba(#000, 0.1);
}
You can manipulate the values, but it creates a very light border around the image that doesn't push the contents. Images can load at whatever time they want, and you get a good user experience.
Here is what I did with Tailwind CSS, but it's just CSS:
img {
#apply bg-no-repeat bg-center;
body.locale-en & {
background-image: url("data:image/svg+xml;utf8,<svg width='100' height='100' viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'><text x='50%' y='50%' style='font-family: sans-serif; font-size: 12px;' dominant-baseline='middle' text-anchor='middle'>Loading…</text></svg>");
}
body.locale-fr & {
background-image: url("data:image/svg+xml;utf8,<svg width='100' height='100' viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'><text x='50%' y='50%' style='font-family: sans-serif; font-size: 12px;' dominant-baseline='middle' text-anchor='middle'>Chargement…</text></svg>");
}
}
You can find the width and height of the images in the developer tools console, for example in Chrome you can click the cursor icon in the developer tools console and when you hover on the page it will highlight all the properties of the elements in the page.
This will help you find the width and height of the images, because if you hover on top of your images it will give you the dimensions of the image and other more properties. You can also make an individual div for each image and make the div relative to the images width and height. You can do it like this:
The main div will contain the images and also the background-div which is below the image.
HTML:
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<div class=".mainDiv">
<div class="below"></div>
<img src="https://imgix.bustle.com/uploads/image/2020/2/13/da1a1ca4-95ec-40ea-83c1-4f07fac8b9b7-eqb9xdwx0auhotc.jpg" width="500"/>
</div>
</body>
</html>
CSS:
.mainDiv {
position: relative;
}
.below {
position: absolute;
background: #96a0aa;
width: 500px;
height: 281px;
}
img {
position: absolute;
}
The result will be that .below will be below the image and so when the image has trouble loading the user will instead see the grey .below div. You cannot see the .below div because it is hidden below the image. The only time you will see this is when the loading of the image is delayed. And this will solve all your problems.
I have got a way. But you will need to use JavaScript for it.
The HTML:
img = document.getElementById("img")
text = document.getElementById("text")
document.addEventListener("DOMContentLoaded", () => {
img.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOEAAADhCAMAAAAJbSJIAAAAA1BMVEWIiIhYZW6zAAAASElEQVR4nO3BgQAAAADDoPlTX+AIVQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwDcaiAAFXD1ujAAAAAElFTkSuQmCC";
text.innerHTML = "Loaded but image is not";
});
window.onload = function() {
img.src = "https://media.geeksforgeeks.org/wp-content/uploads/20190913002133/body-onload-console.png";
text.innerHTML = "Image is now loaded";
};
#img {
width: 400px;
height: 300px;
}
<hr>
<img id="img" src="https://media.geeksforgeeks.org/wp-content/uploads/20190913002133/body-onload-console.png">
<p>Here is the Image</p>
<p id="text">Not Loaded</p>
I want to use an image as a button, and that I can do, however I wish to add text on top of the button and don't know how
This is how I want it to look. 1 The image will be the whole and the text would be in the red part
How can I do that?
This is what I have so far:
<form action=".html" method="LINK">
<input type="image" src="cola.png" class="c11"/>
</form>
Image inputs are server side image maps. They are designed to let you click on an image and have the server identify where on the image you clicked.
If you want a regular button, with text, and a background image. Then use that:
<button>Your Text</button>
button {
background-image: url(cola.png);
}
You may with to adjust the height, width, background colour and border of the image too.
Instead of using an input as a button, use a button as a button, with the background set to the image you want, and because you're using a button, you can put text inside it easily.
<button type="submit">Text Goes Here</button>
button {
background-image: url('cola.png');
}
Then you can change the styling on the button to achieve the effect you want.
You can try something like this
<!DOCTYPE html>
<html>
<head>
<style>
button {
background-image: url("/images/driveicon.png");
background-repeat: no-repeat;
color: red;
}
</style>
</head>
<body>
<button type="submit">Click Me!</button>
</body>
</html>
There is many ways to do this:
Approach 1: Background image on div
HTML
<div class="button" onclick="myFunction()">Click me</div>
CSS
.button {
background: url('img.png') no-repeat;
background-size: cover;
background-position: center;
}
JavaScript
function myFunction() {
alert('I was clicked');
}
Approach 2: img tag with onclick
HTML
<div class="imgDiv">
<img onclick="myFunction()" src="img.png" />
<div>Click me</div>
</div>
CSS
.imgDiv {
position: relative;
}
.imgDiv img, .imgDiv div {
position: absolute;
left: 0px; top: 0px;
}
JavaScript
function myFunction() {
alert('I was clicked');
}
I am trying to setup background images using CSS but I can't seem to get the images to populate correctly.
Here is the CSS for what I want to do
a.fb {
background-image: url('img/Facebook.png');
}
a.fb:hover {
background-image: url('img/FacebookHover.png');
}
Here is the html code that I am using, I have tried a couple of different ways to populate the images with no luck
<div class="footer">
<a class="fb" href="http://www.facebook.com" target="_blank"></a>
</div>
Any help would be greatly appreciated
Okay added the following and still not go any other thoughts
a.fb {
display:block;
width: 33px;
height: 33px
background-image: url('img/Facebook.png');
}
EDIT: Yup got it working now forgot the ; after height, but no I get a white border around it and tried setting border: none; no luck
a.fb {
border: none;
display:block;
width: 33px;
height: 33px;
background-image: url('img/Facebook.png');
}
An anchor tag by default shows as an inline elements, so it depends on its content in order to get a height and width. To do what you want, you should add some styles: display:block; width: 20px; height: 20px.
You could also change the aproach completely and use html + mouseover and mouseout events:
<div class="footer">
<a class="fb" href="http://www.facebook.com" target="_blank">
<img src="http://www.facebook.com/images/fb_icon_325x325.png" alt="fb" name="fb" width="33px" height="33px" name="image_name" onmouseover="fb.src='http://goo.gl/cxiR7'; fb.width='38'; fb.height='38';" onmouseout="fb.src='http://www.facebook.com/images/fb_icon_325x325.png'; fb.width='33'; fb.height='33';" />
</a>
</div>
Here is a jsBin: http://jsbin.com/onehuw/1/edit
background-image only draws in the space that the element occupies. Your a tag has no content, and therefore it's width is 0. You'll not see any content (and background) until you give it at least some width (and height if needed).
You need to add padding to the <a> tag otherwise it has a width and height of 0 for example:
a.fb {
padding: 20px;
background-image: url('img/Facebook.png');
}
a.fb:hover {
background-image: url('img/FacebookHover.png');
}
You could also just set the width and height of the anchor
I would like the top half of this image to display by default, and then use some CSS to make the image shift upward so that the bottom half shows when the mouse hovers over it. Here is the code and what I've tried, but it is not working. Can anyone help me make this code work?
HTML:
<div id="next">
<img src="images/next3.png" alt="next page">
</div>
CSS:
#next a:hover{background: url('images/next3.png') 0 -45px;}
EDIT:
HTML:
<div id="next">
</div>
CSS:
#next {
height:40px;
width:160px;
background-image:url('images/next3.png');
}
#next:hover{background-position: 100% 100%;}
I think you need to use background-position attribute to achieve this.
CSS
div
{
height:40px;
width:160px;
background-image:url('http://i.stack.imgur.com/OOGtn.png');
}
div:hover
{
background-position:100% 100%;
}
JS Fiddle Example
You can also look into CSS Sprites.
You need to use it as a background in the first place. The <img> is covering the background.
Get rid of the image HTML and just use some CSS like this
a {
display: inline-block;
height: 40px;
width: 160px;
background: transparent url(img.jpg) 0 0 no-repeat;
}
a:hover {
background-position: 0 40px;
}
In this case you will need to remove your <img> tag and consistently use the CSS background attribute for both cases. Also define your height and width width of your a tag with CSS too.