CSS and ASP.NET controls - asp.net

I've noticed when trying to apply the 'style' attribute to an asp:TextBox control, for example or when attempting to use a css class to apply a style, it doesn't take. I have to specifically set the attribute. For instance:
<asp:TextBox runat="server" ID="DescriptionTextBox" BackColor="#F7FCFF" /> // Works
<asp:TextBox runat="server" ID="DescriptionTextBox" CssClass="textbox" /> // Doesn't work
<style type="text/css">
.textbox
{
background-color: #F7FCFF;
}
</style>
I know this is a simple question, but can someone kindly shed some light on it for me?
Thank you

Don't get too confused over what an asp control actually is. In fact all it does is generate HTML, which is what the CSS is then applied to.
Your second example with CssClass should work, but instead of debugging by looking at your aspx you really need to check out the HTML (using your browsers version of the developer tools such as Firebug will show you what styles are being applied).

The text box control probably generates either style attribute with background colour or uses more specific CSS rule.
Check the html generated and use FireBug to see which CSS rules are applied / overridden.

Everything looks to be correct. Make sure that you are linking your style sheet between your head tags, or if you opt to go the route of inline tags, those also need to be in between the head.
<html>
<head>
<link href="StyleSheet.css" type="text/css" rel="stylesheet" />
</head>
<body>....
OR
<html>
<head>
<style type="text/css">
.textbox
{
background-color: #F7FCFF;
}
</style>
</head>....
Remember that there isn't an actual TextBox control in HTML so unless it gives you the property (like asp.net does) you must have that CssClass that you used. Also, if you are using the format in your example as is to compare that is where your problem is. See my second code block for where the style should be.
Hope that helps
Tony

You could also do something like DescriptionTextBox.style.add("background-color", "#fff") in your code behind.

Related

What is the best way to give users a printer-friendly page option?

My site is in asp.net 4 / vb. I'm trying to figure out the best way to make a printer-friendly page that only includes our logo at the top and pertinent information, but omits things like navigational bars and other things that aren't necessary. I have a click-to-print icon and it works fine in all browsers, but it doesn't always print out printer-friendly.
I've read things on this site about making a print.css stylesheet, but I'm unsure as to how I'd code the stylesheet, or if I have to assign div attributes to things I want omitted -- and the posts were older posts. Is it recommended that I omit the navigational links, etc., and if so, what is the best way to go about doing this? Thank you for your help!
You can use CSS #media types.
<p> this should be part of the printed page </p>
<div id="navigation_bar_that_should_not_be printed" class="noprint">.....</div>
A simplistic style sheet for the above would be:
#media screen
{
/* whatever styles you have for display */
}
#media print
{
.noprint { display: none; }
}
In the above, the <div> with the class="noprint" will be displayed on screen as usual, but it will not be printed.
Update:
The "C" in CSS stands for "cascading" - meaning the "last" or closest instruction wins. I can only assume that the <span class="bodycontent"... (being the last or closest) is overriding the div.
ASP.Net Controls have a CssClass property, that's how you'd define it:
<asp:HyperLink NavigateUrl="http://www.google.com" runat="server" CssClass="noprint" Text="foo" />
You can even directly type class="noprint" (instead of using CssClass) in any ASP.Net tag - VS may complain but it should be ok:
<asp:HyperLink NavigateUrl="http://www.google.com" runat="server" class="noprint" Text="foo" />
You don't need to actually add additional elements to wrap stuff that you don't want to show when printing. The best way to do a print stylesheet is to apply a class (maybe call it print_hide) on elements you want to hide when your page is printed. For example:
<div>Text</div>
<img class='print_hide' src='some_huge_image.png'/>
In your print.css stylesheet, you would do:
.print_hide {
display: none;
}
To apply the stylesheet, add this to your head:
<link rel="stylesheet" type="text/css" media="print" href="print.css">
The div would still print, but the image would not.
This is, of course, in addition to whatever other style changes you want, like removing background images, changing colors, fonts, etc.
Adding that class to stuff to hide at print is a relatively minimal change to existing code.
The other option is to create a separate printer friendly version of all of your pages, and if your pages are really complicated, this might be the way to do it. That being said, the benefit of print.css (in addition to being less work) is that users don't need to explicitly select Printer friendly version, of course.

Why do I get the error message "Element 'style' cannot be nested within element 'style'"?

I need to override some <style> elements within my Razor page so I've inserted the styles immediately after the opening code block:
#{
ViewBag.Title = "New Account";
Layout = "~/Views/Shared/_Layout_Form.cshtml";
}
<style type="text/css">
#main
{
height: 400px;
}
</style>
The page renders correctly in the browser but Visual Studio green squiggles at <style> complaining that:
<Validation (XHTML 1.0 Transitional): Element 'style' cannot be nested within element 'style'>
I've doublechecked the master page - no problems highlighted there.
What's Visual Studio expecting at this point? What's the correct way to override styles on a page by page basis? Via jQuery?
The style element cannot be nested under the <body> or child elements of the <body>, instead it should go to the <head> element of the page.
If you try to override the styles like this, they get inserted into the default section of your layout page by #RenderBody(), which I assume is inside the <body> of the layout page, while the default styles still stay in the <head>.
The proper way to override some part of the layout page from the content page would be something along these lines, using Razor sections:
_layout.cshtml
<head>
#if (IsSectionDefined("Style"))
{
#RenderSection("Style");
}
else
{
<style type="text/css">
/* Default styles */
</style>
}
</head>
<body>
#RenderBody()
...
page.cshtml
#{
Layout = "layout.cshtml";
}
#section Style
{
<style type="text/css">
#main
{
height: 400px;
}
</style>
}
<!-- Body content here -->
...
Now if the Style section is defined on the content page, its contents will override the defaults from the layout page.
I suggest you read more on Razor layouts and sections. A nice article on this by ScottGu can be found here.
Regarding Visual Studio markup validation warnings
Visual Studio has a problem when markup that makes up a single page is being split up between different files like this. In most cases there is no way for Visual Studio (or any such IDE for that matter) to know how the different page fragments will be dynamically put together in the end. So usually you can't avoid some of these warnings on a project.
Personally I would ignore the warnings if I know what I'm doing and the resulting pages pass the markup validation (http://validator.w3.org/).
If you really want to hide the warnings, you need to disable the appropriate validation options in Visual Studio. E.g. for HTML in Visual Studio 2012 this can be done in Tools > Options > Text Editor > HTML > Validation.
This appears to be a quirk of using Razor. The validator can't "see" the overall HTML because it's scattered across multiple files using Razor logic to piece it all back together again.
The trick I just figured out is to "hide" the <style> and </style> from the validator. Instead of:
<style>
use:
#MvcHtmlString.Create("<style type\"text/css\">")
And instead of:
</style>
use:
#MvcHtmlString.Create("</style>")
The validator doesn't understand these lines are generating <style> and </style>, so it stops complaining about them.
Make sure you're using a #section XXX around the <style> element where "XXX" is referencing a #RenderSection(name: "XXX", required: false) in a master file that is within the HTML <head> element. This is necessary to make sure the <style> element gets inserted in the <head> element where it belongs.
I've seen this happen on my projects as well. Fortunately, when you run the program, it figures itself out and everything should render as expected.
Due to the separation of content at design time, I believe a few of the warnings from razor pages can be safely ignored.
If the CSS isn't actually being recognized, make sure to add that to the question, but if all you're doing is trying to get a perfect no warnings build, then you might just have to set VS to ignore parser errors such as these.
I think you should be set style in HeadContent
<asp:Content ID="Content1" ContentPlaceHolderID="HeadContent" runat="server">
<style type="text/css">
.hideGridColumn {
display: none;
}
</style>
</asp:Content>
That good for me.
The style tag should be in the head tag, not in the body tag.
You should make a region in the head tag in your layout, and put the style tag in that region.
If you ViewSource one the page as it appears in the browser have you got
<style type="text/css">
//some other style stuff, then
<style type="text/css">
#main
{
height: 400px;
}
</style>
</style>
As that's what the validator implies.
If the page passes a W3 validation test, just ignore VS. I think it struggles a bit with Razor.

CSS ID Selector not working but Class Selector does

I am having a problem in that a style is not being applied when I used an "ID" selector (#btnOK). However, if I use a class selector (.btnOK, by changing the "#btnOK" to a ".btnOK" in the CSS file), the style is applied.
Any idea why? The style IS also applied in design mode, but not at run time. It's findingf the css file, else, the class wouldn't be applied. Case sensitivity match on the ID.
In the web page:
<link href="CSS/CvCost.css" rel="stylesheet" type="text/css" />
<asp:Button ID="btnOK" CssClass="btnOK" runat="server" Text="OK" ValidationGroup="Add"/>
In CSS/CvCost.css:
#btnOK{
margin-right:5px;
margin-top:5px;
float:right;
width:75px;
height: 25px;
}
ASP.Net will automatically generate unique IDs based on the element's container.
You need to use ASP.Net's actual ClientID.
Since you can't do that in an external CSS file, you should just use a class selector.
If you're using ASP.Net 4, you can also set the new ClientIDMode property to Static.
If I recall correctly the ID that will show up when the code is ran/debugged wouldn't be the same as #btnOK. VS will give it another ID to go by when the code is ran.

Can we declaratively set the Style property of a web control?

I’ve noticed that on aspx page IntelliSense doesn’t display the Style property of a web control, even thought the control does have a Style property. Does that mean we shouldn’t declaratively set the Style property:
<asp:TextBox ID="UserName" Style="color:Green; padding:0px; margin:0px;" runat="server"></asp:TextBox>
Style translates to the client-side style property; it's actually a CssStyleCollection collection of styles. It doesn't display the style property directly, but once you type style=" it should start showing you the CSS styles that are available to you.
If you have to set these styles in the same file as your html then it's much better to use an embedded style that targets the ID of your control. The best solution, however, is to reference an external stylesheet (css) that contains your styles.
For example:
<style type="text/css">
#UserName {color:Green; padding:0px; margin:0px;}
</style>

Dealing with expandable jQuery content if javascript disabled

I have a messaging tool within the website I am currently working on. The idea is to have a header div and a details div (display="none") for each message.
Ideally, if javascript enabled, I have just the header showing and when the user clicks on it, the details div slide open.
This is fine but how should I work it if javascript is disabled? I was thinking of expanding all messages if disabled, but I don't want a flicker briefly when the page loads of all images open and, if javascript enabled, they collapse.
I'm using ASP.NET and was thinking of checking javascript status of the browser server side but i found out that it can't be done cleanly.
Any suggestions on how to achieve this?
One option is to place this in your head (after the defined styles):
<noscript>
<style type="text/css">
#mydivid {display: block;}
</style>
</noscript>
EDIT: Ive actually posted a better answer, which works off a correct default state.
Actually, the most semantically correct way that you could do this is to append another stylesheet to the head via javascript containing styles that will be implemented if javascript is enabled.
In your example, you will retain the default display for the elements in question.
Then you will create an additional stylesheet (js-enabled-styles.css for example), and place your display:none within that.
Then, in a script tag in your head you will append an additional stylesheet. Using jquery this would be:
$('head').append('<link rel="stylesheet" href="js-enabled-styles.css" type="text/css" />');
You are right the server can only tell you if the browser has JavaScript, it has no clue if it is enabled or not.
Things you can try is do not use onready or onload, just put the lines at the bottom of your JavaScript to hide the content. You might even want to place it directly after the elements on the page.
<div id="foo">
asdf
</div>
<script type="text/javascript">
jQuery("#foo").css("display","none");
</script>
One side note, sounds like you should be using a definition list instead of two divs. Would make probably more sense to a person using a screen reader.
I believe you're looking for the <noscript> tag.
You could achieve the result you describe in one of several ways, but here's a fairly straightforward one. Define your default style for the divs to be the following:
<style type="text/css">
div.details
{
display: none;
}
</style>
And after this style tag, use a noscript block to override the default (JavaScript enabled) style, as such:
<noscript>
<style type="text/css">
div.details
{
display: block;
}
</style>
</noscript>

Resources